时间:2025-08-25 16:18
人气:
作者:admin
ZWrite On/Off控制这一写入行为,影响渲染顺序和半透明效果的正确性。【从UnityURP开始探索游戏渲染】专栏-直达
ZWrite状态通过ShaderLab命令设置,直接影响渲染效果:ZWrite On:开启深度写入(默认值),将片元深度值写入深度缓冲ZWrite Off:关闭深度写入,常用于透明物体渲染ZWrite On|Off声明,或在材质球暴露开关(如[Enum(Off,0,On,1)]_ZWrite)实现动态控制。URP中,半透明物体常采用双Pass策略:第一Pass仅写入深度(ZWrite On),第二Pass关闭写入并进行颜色混合RenderQueue标签控制渲染顺序,例如透明物体通常设置为"Queue"="Transparent"并关闭深度写入Camera.depthTextureMode生成深度纹理,用于屏幕空间效果(如雾效、边缘检测)深度写入技术在Unity中的演变反映了渲染管线的优化:
默认开启ZWrite On,将深度值写入缓冲区,配合ZTest LEqual实现遮挡。
StandardOpaque.shader
Geometry队列,符合URP的UniversalPipeline标签规范Shader "Custom/StandardOpaque" {
Properties { _BaseColor ("Color", Color) = (1,1,1,1) }
SubShader {
Tags {
"RenderType"="Opaque"
"RenderPipeline"="UniversalPipeline"
"Queue"="Geometry"
}
Pass {
ZWrite On
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes { float4 positionOS : POSITION; };
struct Varyings { float4 positionHCS : SV_POSITION; };
Varyings vert(Attributes IN) {
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
return OUT;
}
half4 _BaseColor;
half4 frag(Varyings IN) : SV_Target { return _BaseColor; }
ENDHLSL
}
}
}
ZWrite On),第二Pass关闭写入并混合颜色。Core.hlsl库,支持纹理采样与Alpha混合 "Custom/TransparentPrepass" {
Properties {
_BaseColor ("Color", Color) = (1,0,0,0.5)
_MainTex ("Texture", 2D) = "white" {}
}
SubShader {
Tags {
"RenderType"="Transparent"
"RenderPipeline"="UniversalPipeline"
"Queue"="Transparent"
}
// Pass 1: 仅写入深度
Pass {
ZWrite On
ColorMask 0
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes { float4 positionOS : POSITION; };
struct Varyings { float4 positionHCS : SV_POSITION; };
Varyings vert(Attributes IN) {
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
return OUT;
}
half4 frag(Varyings IN) : SV_Target { return 0; }
ENDHLSL
}
// Pass 2: 混合颜色
Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
struct Attributes {
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings {
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings vert(Attributes IN) {
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = IN.uv;
return OUT;
}
half4 _BaseColor;
half4 frag(Varyings IN) : SV_Target {
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _BaseColor;
return col;
}
ENDHLSL
}
}
}
ZWrite,通过_CameraDepthTexture计算水体与场景的深度差。DeclareDepthTexture.hlsl访问深度图,需在URP设置中启用深度纹理Shader "Custom/WaterEffect" {
Properties {
_WaterColor ("Color", Color) = (0,0.5,1,0.8)
_DepthFade ("Depth Fade", Range(0,1)) = 0.5
}
SubShader {
Tags {
"RenderType"="Transparent"
"RenderPipeline"="UniversalPipeline"
"Queue"="Transparent+100"
}
Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
struct Attributes { float4 positionOS : POSITION; };
struct Varyings {
float4 positionHCS : SV_POSITION;
float4 screenPos : TEXCOORD0;
};
Varyings vert(Attributes IN) {
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.screenPos = ComputeScreenPos(OUT.positionHCS);
return OUT;
}
half4 _WaterColor;
half _DepthFade;
half4 frag(Varyings IN) : SV_Target {
float2 uv = IN.screenPos.xy / IN.screenPos.w;
float sceneDepth = LinearEyeDepth(SampleSceneDepth(uv), _ZBufferParams);
float waterDepth = IN.screenPos.w;
float depthDiff = saturate((sceneDepth - waterDepth) * _DepthFade);
return half4(_WaterColor.rgb, _WaterColor.a * depthDiff);
}
ENDHLSL
}
}
}
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,????)