瀏覽代碼

Merge pull request #18696 from higharc/high-precision-z

MeshDepthMaterial: Compute depth manually rather than using gl_FragCoord.z
Mr.doob 5 年之前
父節點
當前提交
f57665fe24

+ 7 - 2
src/renderers/shaders/ShaderLib/depth_frag.glsl.js

@@ -13,6 +13,8 @@ export default /* glsl */`
 #include <logdepthbuf_pars_fragment>
 #include <clipping_planes_pars_fragment>
 
+varying vec2 vHighPrecisionZW;
+
 void main() {
 
 	#include <clipping_planes_fragment>
@@ -31,13 +33,16 @@ void main() {
 
 	#include <logdepthbuf_fragment>
 
+	// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.
+	float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
+
 	#if DEPTH_PACKING == 3200
 
-		gl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );
+		gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );
 
 	#elif DEPTH_PACKING == 3201
 
-		gl_FragColor = packDepthToRGBA( gl_FragCoord.z );
+		gl_FragColor = packDepthToRGBA( fragCoordZ );
 
 	#endif
 

+ 7 - 0
src/renderers/shaders/ShaderLib/depth_vert.glsl.js

@@ -7,6 +7,11 @@ export default /* glsl */`
 #include <logdepthbuf_pars_vertex>
 #include <clipping_planes_pars_vertex>
 
+// This is used for computing an equivalent of gl_FragCoord.z that is as high precision as possible.
+// Some platforms compute gl_FragCoord at a lower precision which makes the manually computed value better for
+// depth-based postprocessing effects. Reproduced on iPad with A10 processor / iPadOS 13.3.1.
+varying vec2 vHighPrecisionZW;
+
 void main() {
 
 	#include <uv_vertex>
@@ -29,5 +34,7 @@ void main() {
 	#include <logdepthbuf_vertex>
 	#include <clipping_planes_vertex>
 
+	vHighPrecisionZW = gl_Position.zw;
+
 }
 `;