Bladeren bron

Update WebGLDeferredRenderer

Takahiro 8 jaren geleden
bovenliggende
commit
a3b2a184ef
2 gewijzigde bestanden met toevoegingen van 102 en 11 verwijderingen
  1. 37 9
      examples/js/renderers/WebGLDeferredRenderer.js
  2. 65 2
      examples/webgldeferred_animation.html

+ 37 - 9
examples/js/renderers/WebGLDeferredRenderer.js

@@ -1270,7 +1270,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
 	 *
 	 * 1') g-buffer normal + depth pass + shininess
 	 *
-	 *   R: normal
+	 *  RG: normal
 	 *   B: shininess
 	 *   A: depth
 	 */
@@ -1571,6 +1571,33 @@ THREE.DeferredShaderChunk = {
 
 	].join( "\n" ),
 
+	// Refer to http://aras-p.info/texts/CompactNormalStorage.html
+	packNormal: [
+
+		"vec2 normal_to_vec2( vec3 normal ) {",
+
+		"	return normal.xy / sqrt( normal.z * 8.0 + 8.0 ) + 0.5;",
+
+		"}"
+
+	].join( "\n" ),
+
+	unpackVector2: [
+
+		"vec3 vec2_to_normal( vec2 data ) {",
+
+		"	vec2 fenc = data * 4.0 - 2.0;",
+		"	float f = dot( fenc, fenc );",
+		"	float g = sqrt( 1.0 - f / 4.0 );",
+		"	vec3 normal;",
+		"	normal.xy = fenc * g;",
+		"	normal.z = 1.0 - f / 2.0;",
+		"	return normal;",
+
+		"}"
+
+	].join( "\n" ),
+
 	computeTextureCoord: [
 
 		"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"
@@ -1596,11 +1623,10 @@ THREE.DeferredShaderChunk = {
 
 	].join( "\n" ),
 
-	// TODO: optimize normal packing. reference http://aras-p.info/texts/CompactNormalStorage.html
 	packNormalDepthShininess: [
 
 		"vec4 packedNormalDepthShininess;",
-		"packedNormalDepthShininess.x = vec3_to_float( normal * 0.5 + 0.5 );",
+		"packedNormalDepthShininess.xy = normal_to_vec2( normal );",
 		"packedNormalDepthShininess.z = shininess;",
 		"packedNormalDepthShininess.w = position.z / position.w;"
 
@@ -1613,10 +1639,9 @@ THREE.DeferredShaderChunk = {
 
 		"if ( depth == 0.0 ) discard;",
 
-		"vec3 normal = float_to_vec3( normalDepthMap.x ) * 2.0 - 1.0;",
+		"vec3 normal = vec2_to_normal( normalDepthMap.xy );",
 		"float shininess = normalDepthMap.z;"
 
-
 	].join( "\n" ),
 
 	packColor: [
@@ -1991,7 +2016,7 @@ THREE.ShaderDeferred = {
 			"	vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
 
 			"	float rho = dot( lightDirectionVS, lightVector );",
-			"	float rhoMax = cos( lightAngle * 0.5 );",
+			"	float rhoMax = cos( lightAngle );",
 
 			"	if ( rho <= rhoMax ) discard;",
 
@@ -2135,7 +2160,7 @@ THREE.ShaderDeferred = {
 
 			"uniform float shininess;",
 
-			THREE.DeferredShaderChunk[ "packVector3" ],
+			THREE.DeferredShaderChunk[ "packNormal" ],
 
 			"void main() {",
 
@@ -2196,6 +2221,7 @@ THREE.ShaderDeferred = {
 			"uniform mat4 matProjInverse;",
 
 			THREE.DeferredShaderChunk[ "unpackFloat" ],
+			THREE.DeferredShaderChunk[ "unpackVector2" ],
 
 			"void main() {",
 
@@ -2270,6 +2296,7 @@ THREE.ShaderDeferred = {
 			"uniform mat4 matProjInverse;",
 
 			THREE.DeferredShaderChunk[ "unpackFloat" ],
+			THREE.DeferredShaderChunk[ "unpackVector2" ],
 
 			"void main() {",
 
@@ -2280,7 +2307,7 @@ THREE.ShaderDeferred = {
 			"	vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
 
 			"	float rho = dot( lightDirectionVS, lightVector );",
-			"	float rhoMax = cos( lightAngle * 0.5 );",
+			"	float rhoMax = cos( lightAngle );",
 
 			"	if ( rho <= rhoMax ) discard;",
 
@@ -2360,6 +2387,7 @@ THREE.ShaderDeferred = {
 			"uniform mat4 matProjInverse;",
 
 			THREE.DeferredShaderChunk[ "unpackFloat" ],
+			THREE.DeferredShaderChunk[ "unpackVector2" ],
 
 			"void main() {",
 
@@ -2458,7 +2486,7 @@ THREE.ShaderDeferred = {
 
 			"	vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
 			"	vec3 emissiveFinal = emissiveColor;",
-			"	vec3 specularFinal = specularColor * light.rgb * ( light.a / ( 0.2126 * light.r + 0.7152 * light.g + 0.0722 * light.b + 0.00001 ) );",
+			"	vec3 specularFinal = specularColor * light.rgb * light.a;",
 
 			"	gl_FragColor = vec4( diffuseFinal + emissiveFinal + specularFinal, 1.0 );",
 

+ 65 - 2
examples/webgldeferred_animation.html

@@ -36,6 +36,7 @@
 	<body>
 		<div id="container"></div>
 
+		<script src="js/libs/dat.gui.min.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 		<script src="../build/three.js"></script>
 		<script src="js/Detector.js"></script>
@@ -65,6 +66,7 @@
 
 			var numLights = 40;
 			var lights = [];
+			var transparentObjects = [];
 
 			var ready = false;
 
@@ -93,6 +95,7 @@
 				initKnight();
 				initRoom();
 				initLights();
+				initGui();
 
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				window.addEventListener( 'resize', onWindowResize, false );
@@ -210,18 +213,78 @@
 				mesh = new THREE.Mesh( geometry, transparentMaterial );
 				mesh.position.z = size / 2;
 				mesh.scale.multiplyScalar( 0.33 );
-				//room.add( mesh );
+				mesh.visible = false;
+				transparentObjects.push( mesh );
+				room.add( mesh );
 
 				// back2, to check if transparency works
 				mesh = new THREE.Mesh( geometry, transparentMaterial );
 				mesh.position.z = -size / 4;
 				mesh.scale.multiplyScalar( 0.75 );
-				//room.add( mesh );
+				mesh.visible = false;
+				transparentObjects.push( mesh );
+				room.add( mesh );
 
 				scene.add( room );
 
 			}
 
+			function initGui() {
+
+				var gui = new dat.GUI( { width: 280 } );
+
+				var api = {
+					'mode': 0,
+					'transparent_objects': false
+				};
+
+				var folder = gui.addFolder( 'menu' );
+
+				folder.add( api, 'mode', {
+
+					'classic': 0,
+					'light pre-pass': 1,
+					'forward': 2
+
+				} ).onChange( function() {
+
+					switch( parseInt( api.mode ) ) {
+
+						case 0:
+							renderer.forwardRendering = false;
+							renderer.enableLightPrePass( false );
+							break;
+
+						case 1:
+							renderer.forwardRendering = false;
+							renderer.enableLightPrePass( true );
+							break;
+
+						case 2:
+							renderer.forwardRendering = true;
+							break;
+
+						default:
+							break;
+
+					}
+
+				} );
+
+				folder.add( api, 'transparent_objects' ).onChange( function () {
+
+					for ( var i = 0, il = transparentObjects.length; i < il; i ++ ) {
+
+						transparentObjects[ i ].visible = api[ 'transparent_objects' ];
+
+					}
+
+				} );
+
+				folder.open();
+
+			}
+
 			function onDocumentMouseMove( event ) {
 
 				mouseX = ( event.clientX - windowHalfX ) / 10.0;