Browse Source

Only compute direction once in sky shader and disable depthWrite

depthTest is kept enabled since it may be desirable to render the sky after other geometry is already rendered.
Olli Etuaho 5 years ago
parent
commit
8461c0a721
2 changed files with 14 additions and 8 deletions
  1. 7 4
      examples/js/objects/Sky.js
  2. 7 4
      examples/jsm/objects/Sky.js

+ 7 - 4
examples/js/objects/Sky.js

@@ -22,7 +22,8 @@ THREE.Sky = function () {
 		fragmentShader: shader.fragmentShader,
 		fragmentShader: shader.fragmentShader,
 		vertexShader: shader.vertexShader,
 		vertexShader: shader.vertexShader,
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
 		uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
-		side: THREE.BackSide
+		side: THREE.BackSide,
+		depthWrite: false
 	} );
 	} );
 
 
 	THREE.Mesh.call( this, new THREE.BoxBufferGeometry( 1, 1, 1 ), material );
 	THREE.Mesh.call( this, new THREE.BoxBufferGeometry( 1, 1, 1 ), material );
@@ -173,9 +174,12 @@ THREE.Sky.SkyShader = {
 
 
 
 
 		'void main() {',
 		'void main() {',
+
+		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
+
 		// optical length
 		// optical length
 		// cutoff angle at 90 to avoid singularity in next formula.
 		// cutoff angle at 90 to avoid singularity in next formula.
-		'	float zenithAngle = acos( max( 0.0, dot( up, normalize( vWorldPosition - cameraPos ) ) ) );',
+		'	float zenithAngle = acos( max( 0.0, dot( up, direction ) ) );',
 		'	float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );',
 		'	float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );',
 		'	float sR = rayleighZenithLength * inverse;',
 		'	float sR = rayleighZenithLength * inverse;',
 		'	float sM = mieZenithLength * inverse;',
 		'	float sM = mieZenithLength * inverse;',
@@ -184,7 +188,7 @@ THREE.Sky.SkyShader = {
 		'	vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );',
 		'	vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );',
 
 
 		// in scattering
 		// in scattering
-		'	float cosTheta = dot( normalize( vWorldPosition - cameraPos ), vSunDirection );',
+		'	float cosTheta = dot( direction, vSunDirection );',
 
 
 		'	float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );',
 		'	float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );',
 		'	vec3 betaRTheta = vBetaR * rPhase;',
 		'	vec3 betaRTheta = vBetaR * rPhase;',
@@ -196,7 +200,6 @@ THREE.Sky.SkyShader = {
 		'	Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );',
 		'	Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );',
 
 
 		// nightsky
 		// nightsky
-		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
 		'	float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]',
 		'	float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]',
 		'	float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]',
 		'	float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]',
 		'	vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );',
 		'	vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );',

+ 7 - 4
examples/jsm/objects/Sky.js

@@ -31,7 +31,8 @@ var Sky = function () {
 		fragmentShader: shader.fragmentShader,
 		fragmentShader: shader.fragmentShader,
 		vertexShader: shader.vertexShader,
 		vertexShader: shader.vertexShader,
 		uniforms: UniformsUtils.clone( shader.uniforms ),
 		uniforms: UniformsUtils.clone( shader.uniforms ),
-		side: BackSide
+		side: BackSide,
+		depthWrite: false
 	} );
 	} );
 
 
 	Mesh.call( this, new BoxBufferGeometry( 1, 1, 1 ), material );
 	Mesh.call( this, new BoxBufferGeometry( 1, 1, 1 ), material );
@@ -182,9 +183,12 @@ Sky.SkyShader = {
 
 
 
 
 		'void main() {',
 		'void main() {',
+
+		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
+
 		// optical length
 		// optical length
 		// cutoff angle at 90 to avoid singularity in next formula.
 		// cutoff angle at 90 to avoid singularity in next formula.
-		'	float zenithAngle = acos( max( 0.0, dot( up, normalize( vWorldPosition - cameraPos ) ) ) );',
+		'	float zenithAngle = acos( max( 0.0, dot( up, direction ) ) );',
 		'	float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );',
 		'	float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );',
 		'	float sR = rayleighZenithLength * inverse;',
 		'	float sR = rayleighZenithLength * inverse;',
 		'	float sM = mieZenithLength * inverse;',
 		'	float sM = mieZenithLength * inverse;',
@@ -193,7 +197,7 @@ Sky.SkyShader = {
 		'	vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );',
 		'	vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );',
 
 
 		// in scattering
 		// in scattering
-		'	float cosTheta = dot( normalize( vWorldPosition - cameraPos ), vSunDirection );',
+		'	float cosTheta = dot( direction, vSunDirection );',
 
 
 		'	float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );',
 		'	float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );',
 		'	vec3 betaRTheta = vBetaR * rPhase;',
 		'	vec3 betaRTheta = vBetaR * rPhase;',
@@ -205,7 +209,6 @@ Sky.SkyShader = {
 		'	Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );',
 		'	Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );',
 
 
 		// nightsky
 		// nightsky
-		'	vec3 direction = normalize( vWorldPosition - cameraPos );',
 		'	float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]',
 		'	float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]',
 		'	float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]',
 		'	float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]',
 		'	vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );',
 		'	vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );',