如何解决改变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 举报,一经查实,本站将立刻删除。