浏览代码

Improve packing (#28789)

WestLangley 1 年之前
父节点
当前提交
a38bbdd6fb

+ 26 - 6
examples/webgl_materials_channels.html

@@ -9,8 +9,8 @@
 	<body>
 
 		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - <span id="description">Normal, Velocity, Depth, DepthRGBA, DepthRGBAUnpacked, Materials</span><br/>
-			by <a href="https://Clara.io">Ben Houston</a>. ninja head from <a href="https://gpuopen.com/archive/gamescgi/amd-gpu-meshmapper/" target="_blank" rel="noopener">AMD GPU MeshMapper</a>
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - <span id="description">Normal, Velocity, and Depth Materials</span><br/>
+			ninja head from <a href="https://gpuopen.com/archive/gamescgi/amd-gpu-meshmapper/" target="_blank" rel="noopener">AMD GPU MeshMapper</a>
 		</div>
 
 		<script type="importmap">
@@ -53,7 +53,7 @@
 			let cameraOrtho, cameraPerspective;
 			let controlsOrtho, controlsPerspective;
 
-			let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialNormal, materialVelocity;
+			let mesh, materialStandard, materialDepthBasic, materialDepthRGBA, materialDepthRGB, materialDepthRG, materialNormal, materialVelocity;
 
 			const SCALE = 2.436143; // from original model
 			const BIAS = - 0.428408; // from original model
@@ -90,13 +90,11 @@
 				controlsPerspective = new OrbitControls( cameraPerspective, renderer.domElement );
 				controlsPerspective.minDistance = 1000;
 				controlsPerspective.maxDistance = 2400;
-				controlsPerspective.enablePan = false;
 				controlsPerspective.enableDamping = true;
 
 				controlsOrtho = new OrbitControls( cameraOrtho, renderer.domElement );
 				controlsOrtho.minZoom = 0.5;
 				controlsOrtho.maxZoom = 1.5;
-				controlsOrtho.enablePan = false;
 				controlsOrtho.enableDamping = true;
 
 				// lights
@@ -165,6 +163,26 @@
 					side: THREE.DoubleSide
 				} );
 
+				materialDepthRGB = new THREE.MeshDepthMaterial( {
+					depthPacking: THREE.RGBDepthPacking,
+
+					displacementMap: displacementMap,
+					displacementScale: SCALE,
+					displacementBias: BIAS,
+
+					side: THREE.DoubleSide
+				} );
+
+				materialDepthRG = new THREE.MeshDepthMaterial( {
+					depthPacking: THREE.RGDepthPacking,
+
+					displacementMap: displacementMap,
+					displacementScale: SCALE,
+					displacementBias: BIAS,
+
+					side: THREE.DoubleSide
+				} );
+
 				materialNormal = new THREE.MeshNormalMaterial( {
 					displacementMap: displacementMap,
 					displacementScale: SCALE,
@@ -213,7 +231,7 @@
 				//
 
 				const gui = new GUI();
-				gui.add( params, 'material', [ 'standard', 'normal', 'velocity', 'depthBasic', 'depthRGBA' ] );
+				gui.add( params, 'material', [ 'standard', 'normal', 'velocity', 'depthBasic', 'depthRGBA', 'depthRGB', 'depthRG' ] );
 				gui.add( params, 'camera', [ 'perspective', 'ortho' ] );
 				gui.add( params, 'side', [ 'front', 'back', 'double' ] );
 
@@ -263,6 +281,8 @@
 						case 'standard': material = materialStandard; break;
 						case 'depthBasic': material = materialDepthBasic; break;
 						case 'depthRGBA': material = materialDepthRGBA; break;
+						case 'depthRGB': material = materialDepthRGB; break;
+						case 'depthRG': material = materialDepthRG; break;
 						case 'normal': material = materialNormal; break;
 						case 'velocity': material = materialVelocity; break;
 

+ 2 - 0
src/constants.js

@@ -154,6 +154,8 @@ export const TriangleStripDrawMode = 1;
 export const TriangleFanDrawMode = 2;
 export const BasicDepthPacking = 3200;
 export const RGBADepthPacking = 3201;
+export const RGBDepthPacking = 3202;
+export const RGDepthPacking = 3203;
 export const TangentSpaceNormalMap = 0;
 export const ObjectSpaceNormalMap = 1;
 

+ 45 - 13
src/renderers/shaders/ShaderChunk/packing.glsl.js

@@ -9,36 +9,68 @@ vec3 unpackRGBToNormal( const in vec3 rgb ) {
 
 const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1)
 const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1)
+const float ShiftRight8 = 1. / 256.;
+const float Inv255 = 1. / 255.;
 
-const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
-const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
+const vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );
 
-const float ShiftRight8 = 1. / 256.;
+const vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );
+const vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );
+const vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );
 
 vec4 packDepthToRGBA( const in float v ) {
-	vec4 r = vec4( fract( v * PackFactors ), v );
-	r.yzw -= r.xyz * ShiftRight8; // tidy overflow
-	return r * PackUpscale;
+	if( v <= 0.0 )
+		return vec4( 0., 0., 0., 0. );
+	if( v >= 1.0 )
+		return vec4( 1., 1., 1., 1. );
+	float vuf;
+	float af = modf( v * PackFactors.a, vuf );
+	float bf = modf( vuf * ShiftRight8, vuf );
+	float gf = modf( vuf * ShiftRight8, vuf );
+	return vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );
+}
+
+vec3 packDepthToRGB( const in float v ) {
+	if( v <= 0.0 )
+		return vec3( 0., 0., 0. );
+	if( v >= 1.0 )
+		return vec3( 1., 1., 1. );
+	float vuf;
+	float bf = modf( v * PackFactors.b, vuf );
+	float gf = modf( vuf * ShiftRight8, vuf );
+	// the 0.9999 tweak is unimportant, very tiny empirical improvement
+	// return vec3( vuf * Inv255, gf * PackUpscale, bf * 0.9999 );
+	return vec3( vuf * Inv255, gf * PackUpscale, bf );
+}
+
+vec2 packDepthToRG( const in float v ) {
+	if( v <= 0.0 )
+		return vec2( 0., 0. );
+	if( v >= 1.0 )
+		return vec2( 1., 1. );
+	float vuf;
+	float gf = modf( v * 256., vuf );
+	return vec2( vuf * Inv255, gf );
 }
 
 float unpackRGBAToDepth( const in vec4 v ) {
-	return dot( v, UnpackFactors );
+	return dot( v, UnpackFactors4 );
 }
 
-vec2 packDepthToRG( in highp float v ) {
-	return packDepthToRGBA( v ).yx;
+float unpackRGBToDepth( const in vec3 v ) {
+	return dot( v, UnpackFactors3 );
 }
 
-float unpackRGToDepth( const in highp vec2 v ) {
-	return unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) );
+float unpackRGToDepth( const in vec2 v ) {
+	return v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;
 }
 
-vec4 pack2HalfToRGBA( vec2 v ) {
+vec4 pack2HalfToRGBA( const in vec2 v ) {
 	vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );
 	return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );
 }
 
-vec2 unpackRGBATo2Half( vec4 v ) {
+vec2 unpackRGBATo2Half( const in vec4 v ) {
 	return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
 }
 

+ 8 - 0
src/renderers/shaders/ShaderLib/depth.glsl.js

@@ -91,6 +91,14 @@ void main() {
 
 		gl_FragColor = packDepthToRGBA( fragCoordZ );
 
+	#elif DEPTH_PACKING == 3202
+
+		gl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );
+
+	#elif DEPTH_PACKING == 3203
+
+		gl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );
+
 	#endif
 
 }