Browse Source

DepthFormat + DepthPacking on MeshDepthMaterial (#8573)

* add ability to specify on MeshDepthMaterial the type of depth packing one wants.

* depthRGBA -> clipZRGBA - more correct name.

* forgotten replace of depthRGBA -> clipZRGBA.

* add MeshDepthMaterial depthFormat + depthPacking.  Use equations compatible with z buffers.

* adopting MeshDepthMaterial instead of clipZRGBA.

* remove clipZRGBA shader (aka depthRGBA shader) as we can now use MeshDepthMaterial for it.

* remove some comments.

* enable skinning in MeshDepthMaterial, as it was enabled in depthRGBA material.

* remove unused shader.

* fix bug.

* fix bug in shadows with MEshDepthMaterial.

* remove unnecessary debug code.

* ensure that skinning and morphTargets propagate with MeshDepthMaterial.

* fix ssao example to use new MeshDepthMaterial.

* remove unused code.
Ben Houston (Clara.io) 9 years ago
parent
commit
148c47bcb9

+ 0 - 35
examples/js/shaders/DepthRGBAUnpackedShader.js

@@ -1,35 +0,0 @@
-/**
- * @author Ben Houston / bhouston / http://clara.io
- *
- * Test depth pack, unpack and range
- *
- */
-
-THREE.DepthRGBAUnpackedShader = {
-
-	vertexShader: THREE.ShaderChunk[ 'depth_vert' ],
-
-	fragmentShader: [
-    "#include <common>",
-    "#include <packing>",
-    "#include <logdepthbuf_pars_fragment>",
-
-    "void main() {",
-
-      "#include <logdepthbuf_fragment>",
-
-      "#ifdef USE_LOGDEPTHBUF_EXT",
-
-    		"float depth = gl_FragDepthEXT;",
-
-    	"#else",
-
-    		"float depth = gl_FragCoord.z;",
-
-      "#endif",
-
-    	 "gl_FragColor = vec4( vec3( unpackRGBAToLinearUnit( packLinearUnitToRGBA( depth ) ) ), 1.0 );",
-
-      "}" ].join( "\n" )
-
-};

+ 32 - 9
examples/webgl_materials_channels.html

@@ -51,7 +51,6 @@
 
 
 		<script src="js/loaders/BinaryLoader.js"></script>
-		<script src="js/shaders/DepthRGBAUnpackedShader.js"></script>
 
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
@@ -73,7 +72,7 @@
 			var cameraOrtho, cameraPerspective;
 			var controlsOrtho, controlsPerspective;
 
-			var mesh, materialStandard, materialDepth, materialDepthRGBA, materialDepthRGBAUnpacked, materialNormal;
+			var mesh, materialStandard, materialDepthAuto, materialDepthAutoRGBA, materialDepthLinearClipZ, materialDepthLinearClipZRGBA, materialDepthInvClipZ, materialDepthInvClipZRGBA, materialNormal;
 
 			var pointLight, ambientLight;
 
@@ -87,7 +86,7 @@
 			function initGui() {
 
 				var gui = new dat.GUI();
-				gui.add( params, 'material', [ 'standard', 'normal', 'depth', 'depthRGBA', 'depthRGBAUnpacked' ] );
+				gui.add( params, 'material', [ 'standard', 'normal', 'depthAuto', 'depthAutoRGBA', 'depthLinearClipZ', 'depthLinearClipZRGBA', 'depthInvClipZ', 'depthInvClipZRGBA' ] );
 				gui.add( params, 'camera', [ 'perspective', 'ortho' ] );
 
 			}
@@ -167,9 +166,30 @@
 				materialStandard.normalMap = normalMap;
 				materialStandard.normalScale.set( 1, - 1 );
 
-				materialDepth = new THREE.MeshDepthMaterial();
-				materialDepthRGBA = new THREE.ShaderMaterial( THREE.ShaderLib.depthRGBA );
-				materialDepthRGBAUnpacked = new THREE.ShaderMaterial( THREE.DepthRGBAUnpackedShader );
+				materialDepthAuto = new THREE.MeshDepthMaterial();
+				materialDepthAuto.depthFormat = THREE.AutoDepthFormat;
+				materialDepthAuto.depthPacking = THREE.LinearDepthPacking;
+
+				materialDepthAutoRGBA = new THREE.MeshDepthMaterial();
+				materialDepthAutoRGBA.depthFormat = THREE.AutoDepthFormat;
+				materialDepthAutoRGBA.depthPacking = THREE.RGBADepthPacking;
+
+				materialDepthLinearClipZ = new THREE.MeshDepthMaterial();
+				materialDepthLinearClipZ.depthFormat = THREE.LinearClipZDepthFormat;
+				materialDepthLinearClipZ.depthPacking = THREE.LinearDepthPacking;
+
+				materialDepthLinearClipZRGBA = new THREE.MeshDepthMaterial();
+				materialDepthLinearClipZRGBA.depthFormat = THREE.LinearClipZDepthFormat;
+				materialDepthLinearClipZRGBA.depthPacking = THREE.RGBADepthPacking;
+
+				materialDepthInvClipZ = new THREE.MeshDepthMaterial();
+				materialDepthInvClipZ.depthFormat = THREE.InvClipZDepthFormat;
+				materialDepthInvClipZ.depthPacking = THREE.LinearDepthPacking;
+
+				materialDepthInvClipZRGBA = new THREE.MeshDepthMaterial();
+				materialDepthInvClipZRGBA.depthFormat = THREE.InvClipZDepthFormat;
+				materialDepthInvClipZRGBA.depthPacking = THREE.RGBADepthPacking;
+
 				materialNormal = new THREE.MeshNormalMaterial();
 
 				//
@@ -236,9 +256,12 @@
 
 					switch ( params.material ) {
 						case 'standard': material = materialStandard; break;
-						case 'depth': material = materialDepth; break;
-						case 'depthRGBA': material = materialDepthRGBA; break;
-						case 'depthRGBAUnpacked': material = materialDepthRGBAUnpacked; break;
+						case 'depthAuto': material = materialDepthAuto; break;
+						case 'depthAutoRGBA': material = materialDepthAutoRGBA; break;
+						case 'depthLinearClipZ': material = materialDepthLinearClipZ; break;
+						case 'depthLinearClipZRGBA': material = materialDepthLinearClipZRGBA; break;
+						case 'depthInvClipZ': material = materialDepthInvClipZ; break;
+						case 'depthInvClipZRGBA': material = materialDepthInvClipZRGBA; break;
 						case 'normal': material = materialNormal; break;
 					}
 

+ 5 - 6
examples/webgl_postprocessing_ssao.html

@@ -48,7 +48,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 		<script src="js/postprocessing/RenderPass.js"></script>
 		<script src="js/postprocessing/ShaderPass.js"></script>
 		<script src="js/postprocessing/MaskPass.js"></script>
-		
+
 		<script src="js/Detector.js"></script>
 		<script src="js/libs/stats.min.js"></script>
 		<script src='js/libs/dat.gui.min.js'></script>
@@ -164,11 +164,10 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
 				var renderPass = new THREE.RenderPass( scene, camera );
 
 				// Setup depth pass
-				var depthShader = THREE.ShaderLib[ "depthRGBA" ];
-				var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
-
-				depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader,
-					uniforms: depthUniforms, blending: THREE.NoBlending } );
+				depthMaterial = new THREE.MeshDepthMaterial();
+				depthMaterial.depthFormat = THREE.AutoDepthFormat;
+				depthMaterial.depthPacking = THREE.RGBADepthPacking;
+				depthMaterial.blending = THREE.NoBlending;
 
 				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter };
 				depthRenderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, pars );

+ 11 - 0
src/Three.js

@@ -329,3 +329,14 @@ THREE.LogLuvEncoding = 3003;
 THREE.RGBM7Encoding = 3004;
 THREE.RGBM16Encoding = 3005;
 THREE.RGBDEncoding = 3006; // MaxRange is 256.
+
+// Depth format
+
+THREE.AutoDepthFormat = 3100;  // switches based on camera type, uses gl_FragCoord.z
+THREE.LinearClipZDepthFormat = 3101;	// used by orthographic cameras
+THREE.InvClipZDepthFormat = 3102;  // used by perspective cameras
+
+// Depth packing strategies
+
+THREE.LinearDepthPacking = 3200;  // for writing to float textures for high precision or for visualizing results in RGB buffers
+THREE.RGBADepthPacking = 3201; // for packing into RGBA buffers.

+ 12 - 0
src/materials/MeshDepthMaterial.js

@@ -1,6 +1,7 @@
 /**
  * @author mrdoob / http://mrdoob.com/
  * @author alteredq / http://alteredqualia.com/
+ * @author bhouston / https://clara.io
  *
  * parameters = {
  *  opacity: <float>,
@@ -16,7 +17,12 @@ THREE.MeshDepthMaterial = function ( parameters ) {
 
 	this.type = 'MeshDepthMaterial';
 
+	this.depthFormat = THREE.AutoDepthFormat;
+	this.depthPacking = THREE.LinearDepthPacking;
+
+	this.skinning = false;
 	this.morphTargets = false;
+
 	this.wireframe = false;
 	this.wireframeLinewidth = 1;
 
@@ -31,6 +37,12 @@ THREE.MeshDepthMaterial.prototype.copy = function ( source ) {
 
 	THREE.Material.prototype.copy.call( this, source );
 
+	this.depthFormat = source.depthFormat;
+	this.depthPacking = source.depthPacking;
+
+	this.skinning = source.skinning;
+	this.morphTargets = source.morphTargets;
+
 	this.wireframe = source.wireframe;
 	this.wireframeLinewidth = source.wireframeLinewidth;
 

+ 16 - 1
src/renderers/shaders/ShaderChunk/packing.glsl

@@ -14,8 +14,23 @@ vec4 packLinearUnitToRGBA( const in float value ) {
 	res -= res.xxyz * bit_mask;
 	return res;
 }
-
 float unpackRGBAToLinearUnit( const in vec4 rgba ) {
 	const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
 	return dot( rgba, bitSh );
 }
+
+// NOTE: viewZ/eyeZ is < 0 when in front of the camera per OpenGL conventions
+
+float viewZToLinearClipZ( const in float viewZ, const in float near, const in float far ) {
+  return ( viewZ + near ) / ( near - far );
+}
+float linearClipZToViewZ( const in float linearClipZ, const in float near, const in float far ) {
+  return linearClipZ * ( near - far ) - near;
+}
+
+float viewZToInvClipZ( const in float viewZ, const in float near, const in float far ) {
+  return (( near + viewZ ) * far ) / (( far - near ) * viewZ );
+}
+float invClipZToViewZ( const in float invClipZ, const in float near, const in float far ) {
+  return ( near * far ) / ( ( near - far ) * invClipZ - far );
+}

+ 0 - 22
src/renderers/shaders/ShaderLib.js

@@ -227,28 +227,6 @@ THREE.ShaderLib = {
 
 	},
 
-	/* Depth encoding into RGBA texture
-	 *
-	 * based on SpiderGL shadow map example
-	 * http://spidergl.org/example.php?id=6
-	 *
-	 * originally from
-	 * http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
-	 *
-	 * see also
-	 * http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
-	 */
-
-	'depthRGBA': {
-
-		uniforms: {},
-
-		vertexShader: THREE.ShaderChunk[ 'depthRGBA_vert' ],
-		fragmentShader: THREE.ShaderChunk[ 'depthRGBA_frag' ]
-
-	},
-
-
 	'distanceRGBA': {
 
 		uniforms: {

+ 0 - 23
src/renderers/shaders/ShaderLib/depthRGBA_frag.glsl

@@ -1,23 +0,0 @@
-#include <common>
-#include <packing>
-#include <logdepthbuf_pars_fragment>
-#include <clipping_planes_pars_fragment>
-
-void main() {
-
-	#include <clipping_planes_fragment>
-	#include <logdepthbuf_fragment>
-
-	#ifdef USE_LOGDEPTHBUF_EXT
-
-		float depth = gl_FragDepthEXT;
-
-	#else
-
-		float depth = gl_FragCoord.z;
-
-	#endif
-
-	gl_FragData[ 0 ] = packLinearUnitToRGBA( depth );
-
-}

+ 0 - 18
src/renderers/shaders/ShaderLib/depthRGBA_vert.glsl

@@ -1,18 +0,0 @@
-#include <common>
-#include <morphtarget_pars_vertex>
-#include <skinning_pars_vertex>
-#include <logdepthbuf_pars_vertex>
-#include <clipping_planes_pars_vertex>
-
-void main() {
-
-	#include <skinbase_vertex>
-
-	#include <begin_vertex>
-	#include <morphtarget_vertex>
-	#include <skinning_vertex>
-	#include <project_vertex>
-	#include <logdepthbuf_vertex>
-	#include <clipping_planes_vertex>
-
-}

+ 42 - 6
src/renderers/shaders/ShaderLib/depth_frag.glsl

@@ -1,8 +1,21 @@
-uniform float mNear;
-uniform float mFar;
-uniform float opacity;
+#if DEPTH_FORMAT != 3100
 
-varying float vViewZDepth;
+	uniform float mNear;
+	uniform float mFar;
+
+#endif
+
+#if DEPTH_PACKING == 3200
+
+	uniform float opacity;
+
+#endif
+
+#if DEPTH_FORMAT != 3100
+
+	varying float vViewZDepth;
+
+#endif
 
 #include <common>
 #include <packing>
@@ -14,7 +27,30 @@ void main() {
 	#include <clipping_planes_fragment>
 	#include <logdepthbuf_fragment>
 
-	float color = 1.0 - smoothstep( mNear, mFar, vViewZDepth );
-	gl_FragColor = vec4( vec3( color ), opacity );
+	float transformedDepth = 0.0;
+
+	#if DEPTH_FORMAT == 3100 // AutoDepthFormat
+
+		transformedDepth = gl_FragCoord.z;
+
+	#elif DEPTH_FORMAT == 3101
+
+		transformedDepth = viewZToLinearClipZ( vViewZDepth, mNear, mFar );
+
+	#elif DEPTH_FORMAT == 3102
+
+		transformedDepth = viewZToInvClipZ( vViewZDepth, mNear, mFar );
+
+	#endif
+
+	#if DEPTH_PACKING == 3200
+
+		gl_FragColor = vec4( vec3( transformedDepth ), opacity );
+
+	#elif DEPTH_PACKING == 3201
+
+		gl_FragColor = packLinearUnitToRGBA( transformedDepth );
+
+	#endif
 
 }

+ 14 - 2
src/renderers/shaders/ShaderLib/depth_vert.glsl

@@ -1,18 +1,30 @@
 #include <common>
 #include <morphtarget_pars_vertex>
+#include <skinning_pars_vertex>
 #include <logdepthbuf_pars_vertex>
 #include <clipping_planes_pars_vertex>
 
-varying float vViewZDepth;
+#if DEPTH_FORMAT != 3100
+
+	varying float vViewZDepth;
+
+#endif
 
 void main() {
 
+	#include <skinbase_vertex>
+
 	#include <begin_vertex>
 	#include <morphtarget_vertex>
+	#include <skinning_vertex>
 	#include <project_vertex>
 	#include <logdepthbuf_vertex>
 	#include <clipping_planes_vertex>
 
-	vViewZDepth = - mvPosition.z;
+	#if DEPTH_FORMAT != 3100
+
+		vViewZDepth = mvPosition.z;
+
+	#endif
 
 }

+ 4 - 0
src/renderers/webgl/WebGLProgram.js

@@ -426,6 +426,7 @@ THREE.WebGLProgram = ( function () {
 				parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
 				parameters.logarithmicDepthBuffer && renderer.extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
 
+				parameters.depthFormat ? "#define DEPTH_FORMAT " + material.depthFormat : '',
 
 				'uniform mat4 modelMatrix;',
 				'uniform mat4 modelViewMatrix;',
@@ -546,6 +547,9 @@ THREE.WebGLProgram = ( function () {
 				parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
 				parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
 
+				parameters.depthPacking ? "#define DEPTH_PACKING " + material.depthPacking : '',
+				parameters.depthFormat ? "#define DEPTH_FORMAT " + material.depthFormat : '',
+
 				'\n'
 
 			].filter( filterEmptyLine ).join( '\n' );

+ 5 - 2
src/renderers/webgl/WebGLPrograms.js

@@ -25,7 +25,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 		"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
 		"numDirLights", "numPointLights", "numSpotLights", "numHemiLights",
 		"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
-		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes"
+		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "depthPacking", "depthFormat"
 	];
 
 
@@ -182,7 +182,10 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 
 			alphaTest: material.alphaTest,
 			doubleSided: material.side === THREE.DoubleSide,
-			flipSided: material.side === THREE.BackSide
+			flipSided: material.side === THREE.BackSide,
+
+			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false,
+			depthFormat: ( material.depthFormat !== undefined ) ? material.depthFormat : false
 
 		};
 

+ 7 - 10
src/renderers/webgl/WebGLShadowMap.js

@@ -46,8 +46,10 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 	// init
 
-	var depthShader = THREE.ShaderLib[ "depthRGBA" ];
-	var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
+	var depthMaterialTemplate = new THREE.MeshDepthMaterial();
+	depthMaterialTemplate.depthFormat = THREE.AutoDepthFormat;
+	depthMaterialTemplate.depthPacking = THREE.RGBADepthPacking;
+	depthMaterialTemplate.clipping = true;
 
 	var distanceShader = THREE.ShaderLib[ "distanceRGBA" ];
 	var distanceUniforms = THREE.UniformsUtils.clone( distanceShader.uniforms );
@@ -57,14 +59,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 		var useMorphing = ( i & _MorphingFlag ) !== 0;
 		var useSkinning = ( i & _SkinningFlag ) !== 0;
 
-		var depthMaterial = new THREE.ShaderMaterial( {
-			uniforms: depthUniforms,
-			vertexShader: depthShader.vertexShader,
-			fragmentShader: depthShader.fragmentShader,
-			morphTargets: useMorphing,
-			skinning: useSkinning,
-			clipping: true
-		} );
+		var depthMaterial = depthMaterialTemplate.clone();
+		depthMaterial.morphTargets = useMorphing;
+		depthMaterial.skinning = useSkinning;
 
 		_depthMaterials[ i ] = depthMaterial;
 

+ 0 - 2
utils/build/includes/common.json

@@ -211,8 +211,6 @@
 	"src/renderers/shaders/ShaderLib/cube_vert.glsl",
 	"src/renderers/shaders/ShaderLib/depth_frag.glsl",
 	"src/renderers/shaders/ShaderLib/depth_vert.glsl",
-	"src/renderers/shaders/ShaderLib/depthRGBA_frag.glsl",
-	"src/renderers/shaders/ShaderLib/depthRGBA_vert.glsl",
 	"src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl",
 	"src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl",
 	"src/renderers/shaders/ShaderLib/equirect_frag.glsl",