Bläddra i källkod

WaterShader: Clean up.

Mr.doob 8 år sedan
förälder
incheckning
da79f04826
1 ändrade filer med 118 tillägg och 126 borttagningar
  1. 118 126
      examples/js/WaterShader.js

+ 118 - 126
examples/js/WaterShader.js

@@ -7,124 +7,12 @@
  * @author Jonas Wagner / http://29a.ch/ && http://29a.ch/slides/2012/webglwater/ : Water shader explanations in WebGL
  */
 
-THREE.ShaderLib[ 'water' ] = {
-
-	uniforms: THREE.UniformsUtils.merge( [
-		THREE.UniformsLib[ "fog" ], {
-			"normalSampler":    { value: null },
-			"mirrorSampler":    { value: null },
-			"alpha":            { value: 1.0 },
-			"time":             { value: 0.0 },
-			"distortionScale":  { value: 20.0 },
-			"noiseScale":       { value: 1.0 },
-			"textureMatrix" :   { value: new THREE.Matrix4() },
-			"sunColor":         { value: new THREE.Color( 0x7F7F7F ) },
-			"sunDirection":     { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
-			"eye":              { value: new THREE.Vector3() },
-			"waterColor":       { value: new THREE.Color( 0x555555 ) }
-		}
-	] ),
-
-	vertexShader: [
-		'uniform mat4 textureMatrix;',
-		'uniform float time;',
-
-		'varying vec4 mirrorCoord;',
-		'varying vec3 worldPosition;',
-
-		THREE.ShaderChunk[ "fog_pars_vertex"],
-
-		'void main()',
-		'{',
-		'	mirrorCoord = modelMatrix * vec4( position, 1.0 );',
-		'	worldPosition = mirrorCoord.xyz;',
-		'	mirrorCoord = textureMatrix * mirrorCoord;',
-		'   vec4 mvPosition =  modelViewMatrix * vec4( position, 1.0 );',
-		'	gl_Position = projectionMatrix * mvPosition;',
-
-		THREE.ShaderChunk[ "fog_vertex"],
-
-		'}'
-	].join( '\n' ),
-
-	fragmentShader: [
-		'precision highp float;',
-
-		'uniform sampler2D mirrorSampler;',
-		'uniform float alpha;',
-		'uniform float time;',
-		'uniform float distortionScale;',
-		'uniform sampler2D normalSampler;',
-		'uniform vec3 sunColor;',
-		'uniform vec3 sunDirection;',
-		'uniform vec3 eye;',
-		'uniform vec3 waterColor;',
-
-		'varying vec4 mirrorCoord;',
-		'varying vec3 worldPosition;',
-
-		'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 ) +',
-		'		texture2D( normalSampler, uv2 ) +',
-		'		texture2D( normalSampler, 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;',
-		'}',
-
-		THREE.ShaderChunk[ "common" ],
-		THREE.ShaderChunk[ "fog_pars_fragment" ],
-
-		'void main()',
-		'{',
-		'	vec4 noise = getNoise( worldPosition.xz );',
-		'	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;',
-		'	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.z + distortion ) );',
-
-		'	float theta = max( dot( eyeDirection, surfaceNormal ), 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, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
-		'	vec3 outgoingLight = albedo;',
-		'	gl_FragColor = vec4( outgoingLight, alpha );',
-
-			THREE.ShaderChunk[ "fog_fragment" ],
-
-		'}'
-	].join( '\n' )
-
-};
-
 THREE.Water = function ( renderer, camera, scene, options ) {
 
 	THREE.Object3D.call( this );
 	this.name = 'water_' + this.id;
 
-	function optionalParameter ( value, defaultValue ) {
+	function optionalParameter( value, defaultValue ) {
 
 		return value !== undefined ? value : defaultValue;
 
@@ -176,7 +64,115 @@ THREE.Water = function ( renderer, camera, scene, options ) {
 	this.renderTarget = new THREE.WebGLRenderTarget( width, height );
 	this.renderTarget2 = new THREE.WebGLRenderTarget( width, height );
 
-	var mirrorShader = THREE.ShaderLib[ "water" ];
+	var mirrorShader = {
+
+		uniforms: THREE.UniformsUtils.merge( [
+			THREE.UniformsLib[ 'fog' ],
+			{
+				normalSampler: { value: null },
+				mirrorSampler: { value: null },
+				alpha: { value: 1.0 },
+				time: { value: 0.0 },
+				distortionScale: { value: 20.0 },
+				noiseScale: { value: 1.0 },
+				textureMatrix: { value: new THREE.Matrix4() },
+				sunColor: { value: new THREE.Color( 0x7F7F7F ) },
+				sunDirection: { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },
+				eye: { value: new THREE.Vector3() },
+				waterColor: { value: new THREE.Color( 0x555555 ) }
+			}
+		] ),
+
+		vertexShader: [
+			'uniform mat4 textureMatrix;',
+			'uniform float time;',
+
+			'varying vec4 mirrorCoord;',
+			'varying vec3 worldPosition;',
+
+			THREE.ShaderChunk[ 'fog_pars_vertex' ],
+
+			'void main() {',
+			'	mirrorCoord = modelMatrix * vec4( position, 1.0 );',
+			'	worldPosition = mirrorCoord.xyz;',
+			'	mirrorCoord = textureMatrix * mirrorCoord;',
+			'	vec4 mvPosition =  modelViewMatrix * vec4( position, 1.0 );',
+			'	gl_Position = projectionMatrix * mvPosition;',
+
+			THREE.ShaderChunk[ 'fog_vertex' ],
+
+			'}'
+		].join( '\n' ),
+
+		fragmentShader: [
+			'precision highp float;',
+
+			'uniform sampler2D mirrorSampler;',
+			'uniform float alpha;',
+			'uniform float time;',
+			'uniform float distortionScale;',
+			'uniform sampler2D normalSampler;',
+			'uniform vec3 sunColor;',
+			'uniform vec3 sunDirection;',
+			'uniform vec3 eye;',
+			'uniform vec3 waterColor;',
+
+			'varying vec4 mirrorCoord;',
+			'varying vec3 worldPosition;',
+
+			'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 ) +',
+			'		texture2D( normalSampler, uv2 ) +',
+			'		texture2D( normalSampler, 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;',
+			'}',
+
+			THREE.ShaderChunk[ 'common' ],
+			THREE.ShaderChunk[ 'fog_pars_fragment' ],
+
+			'void main() {',
+			'	vec4 noise = getNoise( worldPosition.xz );',
+			'	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;',
+			'	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.z + distortion ) );',
+
+			'	float theta = max( dot( eyeDirection, surfaceNormal ), 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, ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance );',
+			'	vec3 outgoingLight = albedo;',
+			'	gl_FragColor = vec4( outgoingLight, alpha );',
+
+			THREE.ShaderChunk[ 'fog_fragment' ],
+
+			'}'
+		].join( '\n' )
+
+	};
+
 	var mirrorUniforms = THREE.UniformsUtils.clone( mirrorShader.uniforms );
 
 	this.material = new THREE.ShaderMaterial( {
@@ -220,12 +216,6 @@ THREE.Water.prototype.constructor = THREE.Water;
 
 THREE.Water.prototype.updateTextureMatrix = function () {
 
-	function sign( x ) {
-
-		return x ? x < 0 ? - 1 : 1 : 0;
-
-	}
-
 	this.updateMatrixWorld();
 	this.camera.updateMatrixWorld();
 
@@ -265,10 +255,12 @@ THREE.Water.prototype.updateTextureMatrix = function () {
 	this.mirrorCamera.matrixWorldInverse.getInverse( this.mirrorCamera.matrixWorld );
 
 	// Update the texture matrix
-	this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5,
-							0.0, 0.5, 0.0, 0.5,
-							0.0, 0.0, 0.5, 0.5,
-							0.0, 0.0, 0.0, 1.0 );
+	this.textureMatrix.set(
+		0.5, 0.0, 0.0, 0.5,
+		0.0, 0.5, 0.0, 0.5,
+		0.0, 0.0, 0.5, 0.5,
+		0.0, 0.0, 0.0, 1.0
+	);
 	this.textureMatrix.multiply( this.mirrorCamera.projectionMatrix );
 	this.textureMatrix.multiply( this.mirrorCamera.matrixWorldInverse );
 
@@ -282,8 +274,8 @@ THREE.Water.prototype.updateTextureMatrix = function () {
 	var q = new THREE.Vector4();
 	var projectionMatrix = this.mirrorCamera.projectionMatrix;
 
-	q.x = ( sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
-	q.y = ( sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
+	q.x = ( Math.sign( this.clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];
+	q.y = ( Math.sign( this.clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];
 	q.z = - 1.0;
 	q.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];