Browse Source

Started to experiment with properties packing in geometry passes in deferred shading.

Using vec3 <=> float conversions from @benaadams

For the moment just testing how it works (had to fix blending in WebGLRenderer for this). Seems with two RGBA float passes we could eventually get quite decent material range.
alteredq 12 years ago
parent
commit
c0fb64deff

+ 26 - 1
examples/js/ShaderDeferred.js

@@ -1,6 +1,7 @@
 /**
  * @author alteredq / http://alteredqualia.com/
  * @author MPanknin / http://www.redplant.de/
+ * @author benaadams / http://blog.illyriad.co.uk/
  *
  */
 
@@ -30,6 +31,15 @@ THREE.ShaderDeferred = {
 			THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
 			THREE.ShaderChunk[ "specularmap_pars_fragment" ],
 
+			"const float unit = 255.0/256.0;",
+
+			"float vec3_to_float( vec3 data ) {",
+
+				"highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
+				"return compressed;",
+
+			"}",
+
 			"void main() {",
 
 				"gl_FragColor = vec4( diffuse, opacity );",
@@ -46,6 +56,9 @@ THREE.ShaderDeferred = {
 
 				THREE.ShaderChunk[ "fog_fragment" ],
 
+				"gl_FragColor.x = vec3_to_float( 0.999 * gl_FragColor.xyz );",
+				"gl_FragColor.yzw = vec3( 0.0 );",
+
 			"}"
 
 		].join("\n"),
@@ -364,6 +377,17 @@ THREE.ShaderDeferred = {
 
 			"uniform mat4 matProjInverse;",
 
+			"vec3 float_to_vec3( float data ) {",
+
+				"vec3 uncompressed;",
+				"uncompressed.x = fract( data );",
+				"float zInt = floor( data / 255.0 );",
+				"uncompressed.z = fract( zInt / 255.0 );",
+				"uncompressed.y = fract( floor( data - ( zInt * 255.0 ) ) / 255.0 );",
+				"return uncompressed;",
+
+			"}",
+
 			"void main() {",
 
 				"vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );",
@@ -443,7 +467,8 @@ THREE.ShaderDeferred = {
 
 				// color
 
-				"vec4 albedo = texture2D( samplerColor, texCoord );",
+				"vec4 colorMap = texture2D( samplerColor, texCoord );",
+				"vec3 albedo = float_to_vec3( abs( colorMap.x ) );",
 
 				// combine
 

+ 24 - 19
examples/webgl_lights_deferred_morphs.html

@@ -75,6 +75,9 @@
 			var WIDTH = window.innerWidth;
 			var HEIGHT = window.innerHeight - 2 * MARGIN;
 
+			var SCALED_WIDTH = Math.floor( SCALE * WIDTH );
+			var SCALED_HEIGHT = Math.floor( SCALE * HEIGHT );
+
 			var NEAR = 1.0, FAR = 350.0;
 			var VIEW_ANGLE = 45;
 			var ASPECT = WIDTH / HEIGHT;
@@ -100,7 +103,7 @@
 
 			// rendertargets
 
-			var rtColor, rtNormals, rtDepth, rtLightBuffer, rtEmitter, rtFinal;
+			var rtColor, rtNormals, rtDepth, rtLight, rtEmitter, rtFinal;
 
 			// composer
 
@@ -187,8 +190,11 @@
 
 			function createRenderTargets() {
 
-				var rtParamsFloat = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							          format: THREE.RGBAFormat, type: THREE.FloatType };
+				var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
+										    format: THREE.RGBAFormat, type: THREE.FloatType };
+
+				var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
+											 format: THREE.RGBAFormat, type: THREE.FloatType };
 
 				var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
 							          format: THREE.RGBFormat, type: THREE.UnsignedByteType };
@@ -197,14 +203,18 @@
 				// g-buffer
 				// ----------------------------------------------------------
 
-				rtNormals = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtDepth = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtColor = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
-				rtFinal = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
+				rtNormals = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtDepth   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtColor   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatNearest );
+				rtLight   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtEmitter = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
+				rtFinal   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
 
 				rtNormals.generateMipmaps = false;
 				rtDepth.generateMipmaps = false;
 				rtColor.generateMipmaps = false;
+				rtLight.generateMipmaps = false;
+				rtEmitter.generateMipmaps = false;
 				rtFinal.generateMipmaps = false;
 
 				var passNormals = new THREE.RenderPass( scene, camera );
@@ -224,8 +234,6 @@
 				// ----------------------------------------------------------
 
 				var emitterPass = new THREE.RenderPass( emitterScene, camera );
-				rtEmitter = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
-				rtEmitter.generateMipmaps = false;
 
 				compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
 				compEmitter.addPass( emitterPass );
@@ -234,17 +242,14 @@
 				// lighting pass
 				// ----------------------------------------------------------
 
-				rtLightBuffer = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtLightBuffer.generateMipmaps = false;
-
 				var passLight = new THREE.RenderPass( lightScene, camera );
-				compLightBuffer = new THREE.EffectComposer( renderer, rtLightBuffer );
+				compLightBuffer = new THREE.EffectComposer( renderer, rtLight );
 				compLightBuffer.addPass( passLight );
 
 				lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
 				lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
 				lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
-				lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLightBuffer;
+				lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLight;
 
 				var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
 
@@ -309,7 +314,7 @@
 				compositePass.needsSwap = true;
 
 				effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
-				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / ( SCALE * WIDTH ), 1 / ( SCALE * HEIGHT ) );
+				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCALED_WIDTH, 1 / SCALED_HEIGHT );
 
 				var effectColor = new THREE.ShaderPass( THREE.ColorCorrectionShader );
 				effectColor.renderToScreen = true;
@@ -470,11 +475,11 @@
 				lightShader = THREE.ShaderDeferred[ "light" ];
 				compositeShader = THREE.ShaderDeferred[ "composite" ];
 
-				unlitShader.uniforms[ "viewWidth" ].value = SCALE * WIDTH;
-				unlitShader.uniforms[ "viewHeight" ].value = SCALE * HEIGHT;
+				unlitShader.uniforms[ "viewWidth" ].value = SCALED_WIDTH;
+				unlitShader.uniforms[ "viewHeight" ].value = SCALED_HEIGHT;
 
-				lightShader.uniforms[ "viewWidth" ].value = SCALE * WIDTH;
-				lightShader.uniforms[ "viewHeight" ].value = SCALE * HEIGHT;
+				lightShader.uniforms[ "viewWidth" ].value = SCALED_WIDTH;
+				lightShader.uniforms[ "viewHeight" ].value = SCALED_HEIGHT;
 
 				// -----------------------
 				// default materials

+ 25 - 20
examples/webgl_lights_deferred_pointlights.html

@@ -78,6 +78,9 @@
 			var WIDTH = window.innerWidth;
 			var HEIGHT = window.innerHeight - 2 * MARGIN;
 
+			var SCALED_WIDTH = Math.floor( SCALE * WIDTH );
+			var SCALED_HEIGHT = Math.floor( SCALE * HEIGHT );
+
 			var NEAR = 1.0, FAR = 350.0;
 			var VIEW_ANGLE = 45;
 			var ASPECT = WIDTH / HEIGHT;
@@ -103,7 +106,7 @@
 
 			// rendertargets
 
-			var rtColor, rtNormals, rtDepth, rtLightBuffer, rtEmitter, rtFinal;
+			var rtColor, rtNormals, rtDepth, rtLight, rtEmitter, rtFinal;
 
 			// composer
 
@@ -186,8 +189,11 @@
 
 			function createRenderTargets() {
 
-				var rtParamsFloat = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
-							          format: THREE.RGBAFormat, type: THREE.FloatType };
+				var rtParamsFloatLinear = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
+										    format: THREE.RGBAFormat, type: THREE.FloatType };
+
+				var rtParamsFloatNearest = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
+											 format: THREE.RGBAFormat, type: THREE.FloatType };
 
 				var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.LinearFilter, stencilBuffer: false,
 							          format: THREE.RGBFormat, type: THREE.UnsignedByteType };
@@ -196,14 +202,18 @@
 				// g-buffer
 				// ----------------------------------------------------------
 
-				rtNormals = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtDepth = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtColor = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
-				rtFinal = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
+				rtNormals = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtDepth   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtColor   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatNearest );
+				rtLight   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsFloatLinear );
+				rtEmitter = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
+				rtFinal   = new THREE.WebGLRenderTarget( SCALED_WIDTH, SCALED_HEIGHT, rtParamsUByte );
 
 				rtNormals.generateMipmaps = false;
 				rtDepth.generateMipmaps = false;
 				rtColor.generateMipmaps = false;
+				rtLight.generateMipmaps = false;
+				rtEmitter.generateMipmaps = false;
 				rtFinal.generateMipmaps = false;
 
 				var passNormals = new THREE.RenderPass( scene, camera );
@@ -223,8 +233,6 @@
 				// ----------------------------------------------------------
 
 				var emitterPass = new THREE.RenderPass( emitterScene, camera );
-				rtEmitter = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsUByte );
-				rtEmitter.generateMipmaps = false;
 
 				compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
 				compEmitter.addPass( emitterPass );
@@ -233,17 +241,14 @@
 				// lighting pass
 				// ----------------------------------------------------------
 
-				rtLightBuffer = new THREE.WebGLRenderTarget( SCALE * WIDTH, SCALE * HEIGHT, rtParamsFloat );
-				rtLightBuffer.generateMipmaps = false;
-
 				var passLight = new THREE.RenderPass( lightScene, camera );
-				compLightBuffer = new THREE.EffectComposer( renderer, rtLightBuffer );
+				compLightBuffer = new THREE.EffectComposer( renderer, rtLight );
 				compLightBuffer.addPass( passLight );
 
 				lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
 				lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
 				lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
-				lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLightBuffer;
+				lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLight;
 
 				var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
 
@@ -310,8 +315,8 @@
 
 				effectFXAA = new THREE.ShaderPass( THREE.FXAAShader );
 
-				//effectFXAA.uniforms[ 'resolution' ].value.set( 1 / ( WIDTH ), 1 / ( HEIGHT ) );
-				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / ( SCALE * WIDTH ), 1 / ( SCALE * HEIGHT ) );
+				//effectFXAA.uniforms[ 'resolution' ].value.set( 1 / WIDTH, 1 / HEIGHT );
+				effectFXAA.uniforms[ 'resolution' ].value.set( 1 / SCALED_WIDTH, 1 / SCALED_HEIGHT );
 				//effectFXAA.renderToScreen = true;
 
 				var effectColor = new THREE.ShaderPass( THREE.ColorCorrectionShader );
@@ -434,11 +439,11 @@
 				lightShader = THREE.ShaderDeferred[ "light" ];
 				compositeShader = THREE.ShaderDeferred[ "composite" ];
 
-				unlitShader.uniforms[ "viewWidth" ].value = SCALE * WIDTH;
-				unlitShader.uniforms[ "viewHeight" ].value = SCALE * HEIGHT;
+				unlitShader.uniforms[ "viewWidth" ].value = SCALED_WIDTH;
+				unlitShader.uniforms[ "viewHeight" ].value = SCALED_HEIGHT;
 
-				lightShader.uniforms[ "viewWidth" ].value = SCALE * WIDTH;
-				lightShader.uniforms[ "viewHeight" ].value = SCALE * HEIGHT;
+				lightShader.uniforms[ "viewWidth" ].value = SCALED_WIDTH;
+				lightShader.uniforms[ "viewHeight" ].value = SCALED_HEIGHT;
 
 				// -----------------------
 				// default materials