2017-02-25 88 views
0

我从codepen发现了很好的水模拟,并在其他线程的帮助下在这里修改了它(虽然找不到它)。Three.js camera control not working&WebGL shader

我已经使用three.js几次之前,但现在我只是无法理解为什么相机定位/旋转/方面/等不工作。无论我给摄像头使用什么坐标或角度,并且使用updateProjectionMatrix都没有任何反应,摄像机只停留在一个地方。

我评论了调整大小事件等,因为他们也没有做任何事情。

整个代码:

<!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行写了'rotate'而不是'rotation'。 – neeh

回答

1

有这么多尝试这种代码,它甚至不是很清楚,我你想要做什么,但我可以给一些提示:

  1. camera.rotate更改为camera.rotation l。 30
  2. 您的鼠标事件已被评论。如果你想用鼠标旋转相机,你将不得不添加一个mousemove事件;
  3. 顺便说一下,l。 50你发送一个vec4,但加载它为vec2升。 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

)如果你看一下顶点着色器,你会发现只有顶点位置影响渲染的图像。你的水模拟只是在一个位于所以你不能移动相机_traditionally_。使用你的'鼠标'矢量,或者将相机的旋转传递给片段着色器。 – neeh