2017-02-25 18 views
0

codepenから素敵な水のシミュレーションが見つかりました。他のスレッドの助けを借りて修正しました(もはや見つけることができません)。Three.jsカメラコントロールが動作しない&WebGLシェーダ

私はこれまでに数回three.jsを使用しましたが、今はカメラの位置付け/回転/アスペクト/その他が機能していない理由を理解できません。私がカメラに与えた座標や角度が何であってもupdateProjectionMatrixを使用しても何も起こりません。カメラはちょうど1か所にとどまります。

リサイズイベントなどは何もしていないのでコメントアウトしました。

全体コード:

<!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> 


<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script> 


<style type="text/css"> 
    body { 
    overflow: hidden; 
    margin: 0; 
    height: 100%; 
    } 
</style> 

<title></title> 


<script type='text/javascript'>//<![CDATA[ 
    window.onload=function(){ 
     // init camera, scene, renderer 
     var scene, camera, renderer; 
     scene = new THREE.Scene(); 
     var fov = 75, 
     aspect = window.innerWidth/window.innerHeight; 
     camera = new THREE.PerspectiveCamera(fov, aspect, 0.1, 1000); 
     camera.position.z = 200; 
     camera.rotate.z = 1.5707963268; 

     camera.updateProjectionMatrix(); 

     renderer = new THREE.WebGLRenderer(); 
     renderer.setClearColor(0xc4c4c4); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     document.body.appendChild(renderer.domElement); 
     var clock = new THREE.Clock(); 

     var tuniform = { 
      time: { 
      type: 'f', 
      value: 0.1 
      }, 
      resolution: { 
      type: 'v2', 
      value: new THREE.Vector2() 
      }, 
      mouse: { 
      type: 'v4', 
      value: new THREE.Vector2() 
      } 
     }; 

     // Mouse position in - 1 to 1 
     renderer.domElement.addEventListener('mousedown', function(e) { 
     //var canvas = renderer.domElement; 
     //var rect = canvas.getBoundingClientRect(); 
     //tuniform.mouse.value.x = (e.clientX - rect.left)/window.innerWidth * 2 - 1; 
     //tuniform.mouse.value.y = (e.clientY - rect.top)/window.innerHeight * -2 + 1; 


     }); 

     renderer.domElement.addEventListener('mouseup', function(e) { 
      //var canvas = renderer.domElement; 
      //var rect = canvas.getBoundingClientRect(); 
      //tuniform.mouse.value.z = (e.clientX - rect.left)/window.innerWidth * 2 - 1; 
      //tuniform.mouse.value.w = (e.clientY - rect.top)/window.innerHeight * -2 + 1; 
     }); 

     // resize canvas function 
     window.addEventListener('resize',function() { 
      //camera.aspect = window.innerWidth/window.innerHeight; 
      //camera.updateProjectionMatrix(); 
      //renderer.setSize(window.innerWidth, window.innerHeight); 
     }); 

     tuniform.resolution.value.x = window.innerWidth; 
     tuniform.resolution.value.y = window.innerHeight; 

     // Create Plane 
     var material = new THREE.ShaderMaterial({ 
      uniforms: tuniform, 
      vertexShader: document.getElementById('vertex-shader').textContent, 
      fragmentShader: document.getElementById('fragment-shader').textContent 
     }); 

     var mesh = new THREE.Mesh(
     new THREE.PlaneBufferGeometry(window.innerWidth, window.innerHeight, 40), material 
    ); 

scene.add(mesh); 


// draw animation 
function render(time) { 
    tuniform.time.value += clock.getDelta(); 
    requestAnimationFrame(render); 
    renderer.render(scene, camera); 
} 
render(); 


}//]]> 

</script> 


</head> 

<body> 
    <!-- THIS is OPENGL Shading language scripts --> 
    <script id="vertex-shader" type="no-js"> 
     void main() { 
     gl_Position = vec4(position, 1.0); 
     } 
    </script> 

<script id="fragment-shader" type="no-js"> 
    #ifdef GL_ES 
    precision mediump float; 
    #endif 

    uniform float time; 
    uniform vec2 mouse; 
    uniform vec2 resolution; 
    varying vec2 surfacePosition; 

    const int NUM_STEPS = 8; 
    const float PI  = 3.1415; 
    const float EPSILON = 1e-3; 
    float EPSILON_NRM = 0.1/resolution.x; 

    // sea 
    const int ITER_GEOMETRY = 3; 
    const int ITER_FRAGMENT = 5; 
    const float SEA_HEIGHT = 0.6; 
    const float SEA_CHOPPY = 2.0; 
    const float SEA_SPEED = 0.5; 
    const float SEA_FREQ = 0.16; 
    const vec3 SEA_BASE = vec3(0.1,0.19,0.22); //meren pohjaväri 
    const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6); 
    const float SKY_INTENSITY = 1.0; 

    #define SEA_TIME time * SEA_SPEED 

    // math 
    mat4 fromEuler(vec3 ang) { 
     vec2 a1 = vec2(sin(ang.x),cos(ang.x)); 
     vec2 a2 = vec2(sin(ang.y),cos(ang.y)); 
     vec2 a3 = vec2(sin(ang.z),cos(ang.z)); 
     mat4 m; 
     m[0] = vec4(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x,0.0); 
     m[1] = vec4(-a2.y*a1.x,a1.y*a2.y,a2.x,0.0); 
     m[2] = vec4(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y,0.0); 
     m[3] = vec4(0.0,0.0,0.0,1.0); 
     return m; 
    } 
    vec3 rotate(vec3 v, mat4 m) { 
     return vec3(dot(v,m[0].xyz),dot(v,m[1].xyz),dot(v,m[2].xyz)); 
    } 

    float hash(vec2 p) { 
     float h = dot(p,vec2(127.1,311.7)); 
     return fract(sin(h)*43758.5453123); 
    } 

    float noise(in vec2 p) { 
     vec2 i = floor(p); 
     vec2 f = fract(p);  
     vec2 u = f*f*(3.0-2.0*f); 
    return -1.0+2.0*mix(mix(hash(i + vec2(0.0,0.0)), 
    hash(i + vec2(1.0,0.0)), u.x), 
    mix(hash(i + vec2(0.0,1.0)), 
    hash(i + vec2(1.0,1.0)), u.x), u.y); 
    } 


    // lighting 
    float diffuse(vec3 n,vec3 l,float p) { return pow(dot(n,l) * 0.4 + 0.6,p); } 
    float specular(vec3 n,vec3 l,vec3 e,float s) {  
     float nrm = (s + 8.0)/(3.1415 * 8.0); 
     return pow(max(dot(reflect(e,n),l),0.0),s) * nrm; 
    } 

    // sky 
    vec3 sky_color(vec3 e) { 
     e.y = max(e.y,0.0); 
     vec3 ret; 
     ret.x = pow(1.0-e.y,2.0); 
     ret.y = 1.0-e.y; 
     ret.z = 0.6+(1.0-e.y)*0.4; 
     return ret * SKY_INTENSITY; 
    } 

    // sea 
    float sea_octave(vec2 uv, float choppy) { 
     uv += noise(uv);   
     vec2 wv = 1.0-abs(sin(uv)); 
     vec2 swv = abs(cos(uv));  
     wv = mix(wv,swv,wv); 
     return pow(1.0-pow(wv.x * wv.y,0.65),choppy); 
    } 

    float map(vec3 p) { 
     float freq = SEA_FREQ; 
     float amp = SEA_HEIGHT; 
     float choppy = SEA_CHOPPY; 
     vec2 uv = p.xz; uv.x *= 0.75; 
     mat2 m = mat2(1.6,1.2,-1.2,1.6); 

     float d, h = 0.0;  
     for(int i = 0; i < ITER_GEOMETRY; i++) {   
     d = sea_octave((uv+SEA_TIME)*freq,choppy); 
     d += sea_octave((uv-SEA_TIME)*freq,choppy); 
     h += d * amp;   
     uv *= m; freq *= 1.9; amp *= 0.22; 
     choppy = mix(choppy,1.0,0.2); 
     } 
     return p.y - h; 
    } 
    float map_detailed(vec3 p) { 
     float freq = SEA_FREQ; 
     float amp = SEA_HEIGHT; 
     float choppy = SEA_CHOPPY; 
     vec2 uv = p.xz; uv.x *= 0.75; 
     mat2 m = mat2(1.6,1.2,-1.2,1.6); 

     float d, h = 0.0;  
     for(int i = 0; i < ITER_FRAGMENT; i++) {   
     d = sea_octave((uv+SEA_TIME)*freq,choppy); 
     d += sea_octave((uv-SEA_TIME)*freq,choppy); 
     h += d * amp;   
     uv *= m; freq *= 1.9; amp *= 0.22; 
     choppy = mix(choppy,1.0,0.2); 
     } 
     return p.y - h; 
    } 

    vec3 sea_color(in vec3 p, in vec3 n, in vec3 eye, in vec3 dist) { 
     float fresnel_o = 1.0 - max(dot(n,-eye),0.0); 
     float fresnel = pow(fresnel_o,3.0) * 0.65; 

     // reflection 
     vec3 refl = sky_color(reflect(eye,n)); 

     // color 
     vec3 ret = SEA_BASE;  
     ret = mix(ret,refl,fresnel); 

     // wave peaks  
     float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0); 
     ret += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten; 

     return ret; 
    } 

    // tracing 
    vec3 getNormal(vec3 p, float eps) { 
     vec3 n; 
     n.y = map_detailed(p);  
     n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y; 
     n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y; 
     n.y = eps; 
     return normalize(n); 
    } 
    float hftracing(vec3 ori, vec3 dir, out vec3 p) { 
     float tm = 0.0; 
     float tx = 1000.0;  
     float hx = map(ori + dir * tx); 
     if(hx > 0.0) return tx; 
     float hm = map(ori + dir * tm);  
     float tmid = 0.0; 
     for(int i = 0; i < NUM_STEPS; i++) { 
     tmid = mix(tm,tx, hm/(hm-hx));     
     p = ori + dir * tmid;     
     float hmid = map(p); 
     if(hmid < 0.0) { 
     tx = tmid; 
     hx = hmid; 
     } else { 
     tm = tmid; 
     hm = hmid; 
     } 
     } 
     return tmid; 
    } 

    // main 
    void main(void) { 
     vec2 uv = gl_FragCoord.xy/resolution.xy; 
     uv = 1.0 - uv * 2.0; 
     uv.x *= resolution.x/resolution.y; 
     //uv = (surfacePosition+vec2(0., .5))*17. + 5E-3*(pow(length(surfacePosition+vec2(0. ,0.5)), -2.)); 
     uv.y *= -1.; 
     //uv.y += -2.; 

     // ray 
     vec3 ang = vec3(0.0,0.003, pow(time, 0.6)); 
     ang = vec3(0.0,clamp(2.0-mouse.y*0.01,-0.3,PI),mouse.x*0.01); 

     vec3 ori = vec3(0.0,3.5,time*.05); 
     vec3 dir = normalize(vec3(uv.xy,-2.0)); 
     dir.z -= length(uv) * 0.15; 
     //dir = rotate(normalize(dir),ang); 

     // tracing 
     vec3 p; 
     float dens = hftracing(ori,dir,p); 
     vec3 dist = p - ori; 
     vec3 n = getNormal(p, dot(dist,dist)*EPSILON_NRM); 

     // color 
     vec3 color = sea_color(p,n,dir,dist); 
     vec3 light = normalize(vec3(0.0,1.0,0.8)); 
     color += vec3(diffuse(n,light,80.0) * SEA_WATER_COLOR) * 0.12; 
     color += vec3(specular(n,light,dir,60.0)); 

     // post 
     color = mix(sky_color(dir),color,pow(smoothstep(0.0,-0.05,dir.y),0.3)); 
     color = pow(color,vec3(0.75)); 
     gl_FragColor = vec4(color,1.0); 
    } 
</script> 

<script> 
    // tell the embed parent frame the height of the content 
    if (window.parent && window.parent.parent){ 
     window.parent.parent.postMessage(["resultsFrame", { 
     height: document.body.getBoundingClientRect().height, 
     slug: "uz6yo2w3" 
     }], "*") 
    } 
</script> 

</body> 

</html> 
+0

最初に、30行目に 'rotation'ではなく' rotate'を書いています。 – neeh

答えて

1

それはあなたが何をしようとして私にさえ明確ではないのですが、私はいくつかのヒントを与えることができ、このコードではそんなに試みがあります

  1. camera.rotatecamera.rotationに変更します。 30
  2. マウスイベントがコメントされています。マウスでカメラを回転させたい場合は、mousemoveイベントを追加する必要があります。
  3. ところで、l。 50あなたはvec4を送信しますが、vec2 lとして読み込みます。 126;
  4. ウィンドウのサイズが変更されたら、新しい解像度をシェーダに更新することもできます。
  5. l。 304、カメラの原点のZ成分をvec3 ori = vec3(0.0, 3.5, time * 5.0);からvec3 ori = vec3(0.0, 3.5, time * 5.0);に変更して、カメラが海に沿って移動するのを見ることができます。
  6. l。 306、代わりにdir = rotate(normalize(dir), ang);dir = normalize(dir) * fromEuler(ang);angはカメラの角度です)。
  7. l。 149、mat4 fromEuler(vec3 ang){...}を最初のmat3 fromEuler(vec3 ang){...}関数に変更してください。
  8. l。 301、ちょうどvec3 ang = vec3(0.0, 0.0, 0.0);を入れて遊んでください。ユーザーがカメラとやり取りする方法に応じて、この機能でマウス座標を使用できます。
+0

あなたの答えをありがとう。カメラの動きを「伝統的に」制御することさえ可能でした:camera.rotation.x、camera.position.zなど? 私は海に向かってカメラを傾斜させようとしていますが、まだ失敗しています:( – rosmo

+0

頂点シェーダを見ると、頂点位置だけがレンダリングされる画像に影響することがわかります。カメラの前にあるので、カメラを移動することはできません_代わりに 'mouse'ベクターを使うか、カメラの回転をフラグメントシェーダーに渡します。 – neeh

関連する問題