微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

改变three.js海洋场景中水的方向

如何解决改变three.js海洋场景中水的方向

我正在使用 Three.js Ocean Sceen 并且一切正常——除了我想改变水流方向,但不知道如何去做。着色器目前似乎总是向左上方移动,即使我旋转它的底层平面,而且我不熟悉着色器,似乎无法在指导它的代码中找到位置。

着色器代码here,或在下面。如果你能指出我需要改变方向的代码中的位置,我可以自己解决其余的问题!非常感谢。

var Water = function(geometry,options) {

    Mesh.call(this,geometry);

    var scope = this;

    options = options || {};

    var textureWidth = options.textureWidth !== undefined ? options.textureWidth : 512;
    var textureHeight = options.textureHeight !== undefined ? options.textureHeight : 512;

    var clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
    var alpha = options.alpha !== undefined ? options.alpha : 1.0;
    var time = options.time !== undefined ? options.time : 0.0;
    var normalSampler = options.waternormals !== undefined ? options.waternormals : null;
    var sunDirection = options.sunDirection !== undefined ? options.sunDirection : new Vector3(0.70707,0.70707,0.0);
    var sunColor = new Color(options.sunColor !== undefined ? options.sunColor : 0xffffff);
    var waterColor = new Color(options.waterColor !== undefined ? options.waterColor : 0x7F7F7F);
    var eye = options.eye !== undefined ? options.eye : new Vector3(0,0);
    var distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;
    var side = options.side !== undefined ? options.side : FrontSide;
    var fog = options.fog !== undefined ? options.fog : false;

    //

    var mirrorPlane = new Plane();
    var normal = new Vector3();
    var mirrorWorldPosition = new Vector3();
    var cameraWorldPosition = new Vector3();
    var rotationMatrix = new Matrix4();
    var lookAtPosition = new Vector3(0,-1);
    var clipPlane = new Vector4();

    var view = new Vector3();
    var target = new Vector3();
    var q = new Vector4();

    var textureMatrix = new Matrix4();

    var mirrorCamera = new PerspectiveCamera();

    var parameters = {
        minFilter: LinearFilter,magFilter: LinearFilter,format: RGBFormat
    };

    var rendertarget = new WebGLrendertarget(textureWidth,textureHeight,parameters);

    if (!MathUtils.isPowerOfTwo(textureWidth) || !MathUtils.isPowerOfTwo(textureHeight)) {

        rendertarget.texture.generateMipmaps = false;

    }

    var mirrorShader = {

        uniforms: UniformsUtils.merge([
            UniformsLib['fog'],UniformsLib['lights'],{
                'normalSampler': {
                    value: null
                },'mirrorSampler': {
                    value: null
                },'alpha': {
                    value: 1.0
                },'time': {
                    value: 0.0
                },'size': {
                    value: 1.0
                },'distortionScale': {
                    value: 20.0
                },'textureMatrix': {
                    value: new Matrix4()
                },'sunColor': {
                    value: new Color(0x7F7F7F)
                },'sunDirection': {
                    value: new Vector3(0.70707,0)
                },'eye': {
                    value: new Vector3()
                },'waterColor': {
                    value: new Color(0x555555)
                }
            }
        ]),vertexShader: [
            'uniform mat4 textureMatrix;','uniform float time;','varying vec4 mirrorCoord;','varying vec4 worldPosition;','#include <common>','#include <fog_pars_vertex>','#include <shadowmap_pars_vertex>','#include <logdepthbuf_pars_vertex>','void main() {','   mirrorCoord = modelMatrix * vec4( position,1.0 );','   worldPosition = mirrorCoord.xyzw;','   mirrorCoord = textureMatrix * mirrorCoord;','   vec4 mvPosition =  modelViewMatrix * vec4( position,'   gl_Position = projectionMatrix * mvPosition;','#include <beginnormal_vertex>','#include <defaultnormal_vertex>','#include <logdepthbuf_vertex>','#include <fog_vertex>','#include <shadowmap_vertex>','}'
        ].join('\n'),fragmentShader: [
            'uniform sampler2D mirrorSampler;','uniform float alpha;','uniform float size;','uniform float distortionScale;','uniform sampler2D normalSampler;','uniform vec3 sunColor;','uniform vec3 sunDirection;','uniform vec3 eye;','uniform vec3 waterColor;','vec4 getNoise( vec2 uv ) {','   vec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0,time / 29.0);','   vec2 uv1 = uv / 107.0-vec2( time / -19.0,time / 31.0 );','   vec2 uv2 = uv / vec2( 8907.0,9803.0 ) + vec2( time / 101.0,time / 97.0 );','   vec2 uv3 = uv / vec2( 1091.0,1027.0 ) - vec2( time / 109.0,time / -113.0 );','   vec4 noise = texture2D( normalSampler,uv0 ) +','       texture2D( normalSampler,uv1 ) +',uv2 ) +',uv3 );','   return noise * 0.5 - 1.0;','}','void sunLight( const vec3 surfacenormal,const vec3 eyeDirection,float shiny,float spec,float diffuse,inout vec3 diffuseColor,inout vec3 specularColor ) {','   vec3 reflection = normalize( reflect( -sunDirection,surfacenormal ) );','   float direction = max( 0.0,dot( eyeDirection,reflection ) );','   specularColor += pow( direction,shiny ) * sunColor * spec;','   diffuseColor += max( dot( sunDirection,surfacenormal ),0.0 ) * sunColor * diffuse;','#include <packing>','#include <bsdfs>','#include <fog_pars_fragment>','#include <logdepthbuf_pars_fragment>','#include <lights_pars_begin>','#include <shadowmap_pars_fragment>','#include <shadowmask_pars_fragment>','#include <logdepthbuf_fragment>','   vec4 noise = getNoise( worldPosition.xz * size );','   vec3 surfacenormal = normalize( noise.xzy * vec3( 1.5,1.0,1.5 ) );','   vec3 diffuseLight = vec3(0.0);','   vec3 specularLight = vec3(0.0);','   vec3 worldToEye = eye-worldPosition.xyz;','   vec3 eyeDirection = normalize( worldToEye );','   sunLight( surfacenormal,eyeDirection,100.0,2.0,0.5,diffuseLight,specularLight );','   float distance = length(worldToEye);','   vec2 distortion = surfacenormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;','   vec3 reflectionSample = vec3( texture2D( mirrorSampler,mirrorCoord.xy / mirrorCoord.w + distortion ) );','   float theta = max( dot( eyeDirection,0.0 );','   float rf0 = 0.3;','   float reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ),5.0 );','   vec3 scatter = max( 0.0,dot( surfacenormal,eyeDirection ) ) * waterColor;','   vec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(),( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ),reflectance);','   vec3 outgoingLight = albedo;','   gl_FragColor = vec4( outgoingLight,alpha );','#include <tonemapping_fragment>','#include <fog_fragment>','}'
        ].join('\n')

    };

    var material = new ShaderMaterial({
        fragmentShader: mirrorShader.fragmentShader,vertexShader: mirrorShader.vertexShader,uniforms: UniformsUtils.clone(mirrorShader.uniforms),lights: true,side: side,fog: fog
    });

    material.uniforms['mirrorSampler'].value = rendertarget.texture;
    material.uniforms['textureMatrix'].value = textureMatrix;
    material.uniforms['alpha'].value = alpha;
    material.uniforms['time'].value = time;
    material.uniforms['normalSampler'].value = normalSampler;
    material.uniforms['sunColor'].value = sunColor;
    material.uniforms['waterColor'].value = waterColor;
    material.uniforms['sunDirection'].value = sunDirection;
    material.uniforms['distortionScale'].value = distortionScale;

    material.uniforms['eye'].value = eye;

    scope.material = material;

    scope.onBeforeRender = function(renderer,scene,camera) {

        mirrorWorldPosition.setFromMatrixPosition(scope.matrixWorld);
        cameraWorldPosition.setFromMatrixPosition(camera.matrixWorld);

        rotationMatrix.extractRotation(scope.matrixWorld);

        normal.set(0,1);
        normal.applyMatrix4(rotationMatrix);

        view.subVectors(mirrorWorldPosition,cameraWorldPosition);

        // Avoid rendering when mirror is facing away

        if (view.dot(normal) > 0) return;

        view.reflect(normal).negate();
        view.add(mirrorWorldPosition);

        rotationMatrix.extractRotation(camera.matrixWorld);

        lookAtPosition.set(0,-1);
        lookAtPosition.applyMatrix4(rotationMatrix);
        lookAtPosition.add(cameraWorldPosition);

        target.subVectors(mirrorWorldPosition,lookAtPosition);
        target.reflect(normal).negate();
        target.add(mirrorWorldPosition);

        mirrorCamera.position.copy(view);
        mirrorCamera.up.set(0,1,0);
        mirrorCamera.up.applyMatrix4(rotationMatrix);
        mirrorCamera.up.reflect(normal);
        mirrorCamera.lookAt(target);

        mirrorCamera.far = camera.far; // Used in WebGLBackground

        mirrorCamera.updateMatrixWorld();
        mirrorCamera.projectionMatrix.copy(camera.projectionMatrix);

        // Update the texture matrix
        textureMatrix.set(
            0.5,0.0,1.0
        );
        textureMatrix.multiply(mirrorCamera.projectionMatrix);
        textureMatrix.multiply(mirrorCamera.matrixWorldInverse);

        // Now update projection matrix with new clip plane,implementing code from: http://www.terathon.com/code/oblique.html
        // Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
        mirrorPlane.setFromnormalAndcoplanarPoint(normal,mirrorWorldPosition);
        mirrorPlane.applyMatrix4(mirrorCamera.matrixWorldInverse);

        clipPlane.set(mirrorPlane.normal.x,mirrorPlane.normal.y,mirrorPlane.normal.z,mirrorPlane.constant);

        var projectionMatrix = mirrorCamera.projectionMatrix;

        q.x = (Math.sign(clipPlane.x) + projectionMatrix.elements[8]) / projectionMatrix.elements[0];
        q.y = (Math.sign(clipPlane.y) + projectionMatrix.elements[9]) / projectionMatrix.elements[5];
        q.z = -1.0;
        q.w = (1.0 + projectionMatrix.elements[10]) / projectionMatrix.elements[14];

        // Calculate the scaled plane vector
        clipPlane.multiplyScalar(2.0 / clipPlane.dot(q));

        // Replacing the third row of the projection matrix
        projectionMatrix.elements[2] = clipPlane.x;
        projectionMatrix.elements[6] = clipPlane.y;
        projectionMatrix.elements[10] = clipPlane.z + 1.0 - clipBias;
        projectionMatrix.elements[14] = clipPlane.w;

        eye.setFromMatrixPosition(camera.matrixWorld);

        // Render

        var currentrendertarget = renderer.getrendertarget();

        var currentXrEnabled = renderer.xr.enabled;
        var currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;

        scope.visible = false;

        renderer.xr.enabled = false; // Avoid camera modification and recursion
        renderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows

        renderer.setrendertarget(rendertarget);

        renderer.state.buffers.depth.setMask(true); // make sure the depth buffer is writable so it can be properly cleared,see #18897

        if (renderer.autoClear === false) renderer.clear();
        renderer.render(scene,mirrorCamera);

        scope.visible = true;

        renderer.xr.enabled = currentXrEnabled;
        renderer.shadowMap.autoUpdate = currentShadowAutoUpdate;

        renderer.setrendertarget(currentrendertarget);

        // Restore viewport

        var viewport = camera.viewport;

        if (viewport !== undefined) {

            renderer.state.viewport(viewport);

        }

    };

};

Water.prototype = Object.create(Mesh.prototype);
Water.prototype.constructor = Water;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。