From c0fb64deffef2529b24e0959e0599abfd1376e03 Mon Sep 17 00:00:00 2001 From: alteredq Date: Tue, 27 Nov 2012 15:14:17 +0100 Subject: [PATCH] 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. --- examples/js/ShaderDeferred.js | 27 ++++++++++- examples/webgl_lights_deferred_morphs.html | 43 ++++++++++-------- .../webgl_lights_deferred_pointlights.html | 45 ++++++++++--------- 3 files changed, 75 insertions(+), 40 deletions(-) diff --git a/examples/js/ShaderDeferred.js b/examples/js/ShaderDeferred.js index fa582eb4e7..8011e50157 100644 --- a/examples/js/ShaderDeferred.js +++ b/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 diff --git a/examples/webgl_lights_deferred_morphs.html b/examples/webgl_lights_deferred_morphs.html index 9ce44fcc43..78abdfce03 100644 --- a/examples/webgl_lights_deferred_morphs.html +++ b/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 diff --git a/examples/webgl_lights_deferred_pointlights.html b/examples/webgl_lights_deferred_pointlights.html index 71624d7572..391dff48cd 100644 --- a/examples/webgl_lights_deferred_pointlights.html +++ b/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 -- GitLab