Unity URP Shader 修改深度让人物不再被地面遮挡
- 前言
- 项目
- 场景布置
- 代码编写
前言
遇到一个小问题,人物总是被XY
平面的地面遮挡,于是在Shader
中改一下深度输出,这样地面再也不会挡住人物了。
项目
场景布置
将人物放到XY
平面的后面
配置Shader
参数
代码编写
Shader "Unlit/DepTest"
{Properties{[MainColor] _BaseColor("Base Color", Color) = (1, 1, 1, 1)[MainTexture] _MainTex("Main Texture", 2D) = "white" {}_DepthBias("Depth Bias", Float) = 0.01 // 深度偏移,确保在XY平面之前渲染}SubShader{Tags { "RenderType" = "Transparent" "RenderQueue"="Transparent" "RenderPipeline" = "UniversalPipeline" }Pass{Name "UnlitPass"Tags { "LightMode" = "UniversalForward" }Cull Off // 双面渲染Blend SrcAlpha OneMinusSrcAlpha // 混合模式,支持透明度ZTest LEqual // 深度测试,确保当前像素深度小于等于之前的像素才渲染// ZTest Always // 深度测试设置为Always,确保总是渲染ZWrite Off // 关闭深度写入,防止影响其他物体的深度排序// ZWrite OnColorMask RGBA // 允许写入颜色缓冲区的所有通道 (红、绿、蓝、透明)HLSLPROGRAM#pragma vertex vert // 定义顶点着色器方法名称#pragma fragment frag // 定义片元着色器方法名称#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"struct Attributes{float4 positionOS : POSITION; // 顶点位置,模型空间坐标float2 uv : TEXCOORD0; // 顶点纹理坐标};struct Varyings{float4 positionHCS : SV_POSITION; // 输出到片元着色器的顶点位置,裁剪空间坐标float2 uv : TEXCOORD0; // 传递给片元着色器的纹理坐标float depth : TEXCOORD1; // 存储深度值,供片元着色器使用};TEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);CBUFFER_START(UnityPerMaterial)half4 _BaseColor;float4 _MainTex_ST;float _DepthBias; // 深度偏移量CBUFFER_ENDVaryings vert(Attributes IN){Varyings OUT;// 获取对象在世界空间中的位置float4 worldPosition = mul(GetObjectToWorldMatrix(), IN.positionOS);// 将世界空间坐标转换为裁剪空间坐标OUT.positionHCS = TransformWorldToHClip(worldPosition);// 传递纹理坐标OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex);// 计算并存储深度值OUT.depth = OUT.positionHCS.z / OUT.positionHCS.w;return OUT;}struct FragmentOutput{half4 color : SV_Target; // 最终颜色输出float depth : SV_Depth; // 深度输出};FragmentOutput frag(Varyings IN){FragmentOutput OUT;OUT.color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv) * _BaseColor;OUT.depth = IN.depth - _DepthBias; // 深度偏移return OUT;}ENDHLSL}}FallBack "Unlit/Texture"
}