源码 / shaders/Ch30/PixelValidator.glsl
shaders/Ch30/PixelValidator.glsl
// 30.7 节:像素校验全屏 Pass——把 NaN / Inf / 负数 / 超范围的像素涂成醒目的颜色。(GLSL 版,对应 Ch30/PixelValidator.shader) // 与 Rendering Debugger 里的 “Highlight NaN, Inf and Negative Values” 思路相同,但可以放进任何管线阶段。 Shader "Cookbook/Ch30/PixelValidator" { SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" } ZWrite Off ZTest Always Cull Off Blend Off Pass { Name "Validate" GLSLPROGRAM uniform float _MaxValue; VARYING vec2 texcoord; #ifdef VERTEX void main() { vec2 p = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2); texcoord = p * _BlitScaleBias.xy + _BlitScaleBias.zw; gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0); } #endif #ifdef FRAGMENT // core 包 Common.hlsl 的 AnyIsNaN / AnyIsInf:GLSL 有内置的 isnan / isinf bool AnyIsNaN(vec4 v) { return any(isnan(v)); } bool AnyIsInf(vec4 v) { return any(isinf(v)); } void main() { vec4 c = texelFetch(_BlitTexture, ivec2(texcoord * _BlitTexture_TexelSize.zw), 0); // 背景压暗、去色,让标记更显眼 vec3 bg = vec3(Luminance(saturate(c.rgb)) * 0.35); if (AnyIsNaN(c)) { fragColor = vec4(1, 0, 1, 1); return; } // 品红:NaN if (AnyIsInf(c)) { fragColor = vec4(0, 1, 1, 1); return; } // 青:Inf if (any(lessThan(c.rgb, vec3(0.0)))) { fragColor = vec4(1, 1, 0, 1); return; } // 黄:负数 if (any(greaterThan(c.rgb, vec3(_MaxValue)))) { fragColor = vec4(1, 0.3, 0, 1); return; } // 橙:异常大的 HDR 值 fragColor = vec4(bg, 1.0); } #endif ENDGLSL } } }