Unity URP Shader 修改深度让人物不再被地面遮挡

Unity URP Shader 修改深度让人物不再被地面遮挡

前言

遇到一个小问题,人物总是被XY平面的地面遮挡,于是在Shader中改一下深度输出,这样地面再也不会挡住人物了。
遮挡示意

项目

场景布置

将人物放到XY平面的后面

人物放到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 On
            ColorMask 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_END

            Varyings 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"
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现一个在 Unity URP 中不被任何物体遮挡的着色器,你可以按照以下步骤进行: 1. 在 Unity 中创建一个新的 Shader Graph。右键点击项目资源面板,选择 "Create" -> "Shader" -> "Universal Render Pipeline" -> "PBR Graph"。 2. 打开创建的 PBR Graph,在 Shader Graph 编辑器中,你将看到一个图形编辑器界面。 3. 在编辑器界面的左侧面板中,选择 "Master" 节点,然后在右侧面板中选择 "Unlit" 选项,这将创建一个无光照的着色器。 4. 接下来,你需要添加一个自定义的节点。在编辑器界面的左侧面板中,右键点击并选择 "Create Node" -> "Miscellaneous" -> "Depth Mask" 节点。 5. 将 "Depth Mask" 节点连接到 "Alpha Clip Threshold" 输入端口。 6. 将 "Alpha Clip Threshold" 的值设置为一个接近 1 的小数(例如0.99),以确保物体不被遮挡。 7. 如果你想要添加纹理或其他效果,可以继续在图形编辑器中添加和连接其他节点。 8. 最后,点击编辑器界面右上角的 "Compile and Show Code" 按钮,将图形编辑器中的节点转换为着色器代码。 9. 将生成的着色器代码保存为一个 .shader 文件,并将其添加到 Unity 项目中的合适位置。 完成上述步骤后,你就创建了一个不会被任何物体遮挡的着色器。你可以将这个着色器应用于你想要达到这种效果的对象上的材质中。请注意,具体的效果可能需要根据你的需求进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值