我不是歪神 2026-02-09 16:09 采纳率: 75%
浏览 2
已采纳

unity6000.0.3版本URP下ScriptableRendererFeature怎么实现这个效果

在shader里可以直接 TEXTURE2D(_CameraDepthTexture); 这样来访问到,怎么在ScriptableRendererFeature中让一张贴图也能这样直接访问,网上的方法都是6+之前的方法现在都用不了,要么过时要么报错,6+的少之又少,找了两天也没找到能用的方法qwq,感谢大家帮忙解惑了awa

  • 写回答

1条回答 默认 最新

  • 檀越@新空间 2026-02-09 16:10
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    Unity 6000.0.3(假设你指的是 Unity 2021 或更高版本,因为 6000.0.3 并不是官方版本号)的 URP(Universal Render Pipeline) 中,如果你希望在 ScriptableRendererFeature 中访问类似于 TEXTURE2D(_CameraDepthTexture) 的深度纹理,需要通过 RenderTextureShaderGraph自定义着色器 来实现。


    ✅ 核心问题分析

    你在 Shader 中可以直接使用 TEXTURE2D(_CameraDepthTexture); 是因为 URP 提供了内置的 Camera Depth Texture,但在 ScriptableRendererFeature 中不能直接使用该变量,因为它属于 Shader 内部变量,而你需要的是在 C# 程序中访问这个纹理。


    🧠 解决方案

    1. 在 ScriptableRendererFeature 中获取 Camera Depth Texture

    ✅ 步骤一:创建一个自定义的 RenderFeature

    在你的 ScriptableRendererFeature 类中,可以通过 GetCameraDepthTexture() 方法来获取深度纹理:

    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    public class CustomDepthFeature : ScriptableRendererFeature
    {
        private RenderTexture _depthTexture;
    
        public override void Create()
        {
            // 创建一个 RenderTexture 用于保存深度信息
            _depthTexture = new RenderTexture(
                Screen.width, 
                Screen.height, 
                24, 
                RenderTextureFormat.Depth,
                RenderTextureReadWrite.Linear
            );
            _depthTexture.name = "CustomDepthTexture";
            _depthTexture.filterMode = FilterMode.Bilinear;
            _depthTexture.wrapMode = TextureWrapMode.Clamp;
        }
    
        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            var pass = new CustomDepthPass(renderer, _depthTexture);
            renderer.AddRenderPass(pass);
        }
    }
    

    2. 创建一个 RenderPass 来复制深度信息

    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    public class CustomDepthPass : ScriptableRenderPass
    {
        private RenderTexture _depthTexture;
        private Material _copyMaterial;
    
        public CustomDepthPass(ScriptableRenderer renderer, RenderTexture depthTexture)
        {
            _depthTexture = depthTexture;
            _copyMaterial = new Material(Shader.Find("Hidden/CustomDepthCopy"));
            _copyMaterial.hideFlags = HideFlags.HideAndDontSave;
        }
    
        public override void Configure(CommandBuffer cmd, RenderTextureDescriptor descriptor)
        {
            // 设置渲染目标为我们的自定义深度贴图
            cmd.SetRenderTarget(_depthTexture);
            cmd.ClearRenderTarget(true, true, Color.clear);
        }
    
        public override void Execute(ScriptableRenderContext context, CommandBuffer cmd, RuntimeObject[] renderObjects)
        {
            // 执行复制操作
            cmd.DrawMesh(
                MeshHelper.fullscreenMesh,
                Matrix4x4.identity,
                _copyMaterial,
                0,
                0
            );
        }
    
        public override void Cleanup()
        {
            if (_copyMaterial != null)
            {
                Object.DestroyImmediate(_copyMaterial);
            }
            if (_depthTexture != null)
            {
                _depthTexture.Release();
                Object.DestroyImmediate(_depthTexture);
            }
        }
    }
    

    3. 编写一个 Shader 来复制深度信息

    创建一个 CustomDepthCopy.shader 文件,内容如下:

    Shader "Hidden/CustomDepthCopy"
    {
        SubShader
        {
            Tags { "RenderType"="Transparent" }
            LOD 100
    
            Pass
            {
                ZTest Always
                ZWrite Off
                Cull Off
    
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 pos : SV_POSITION;
                };
    
                v2f vert (appdata v)
                {
                    v2f o;
                    o.pos = TransformVertexToHClip(v.vertex);
                    o.uv = v.uv;
                    return o;
                }
    
                sampler2D _CameraDepthTexture; // 原始深度纹理
    
                fixed4 frag (v2f i) : SV_Target
                {
                    // 将原始深度值复制到我们自己的 RenderTexture 中
                    float depth = tex2D(_CameraDepthTexture, i.uv).r;
                    return float4(depth, depth, depth, 1.0);
                }
                ENDCG
            }
        }
    }
    

    4. 在 Shader 中使用你自己的深度贴图

    现在你可以在其他 Shader 中使用你创建的 _CustomDepthTexture

    TEXTURE2D(_CustomDepthTexture);
    SAMPLER(texture_sampler);
    
    float4 frag (v2f i) : SV_Target
    {
        float depth = SAMPLE_TEXTURE2D(_CustomDepthTexture, texture_sampler, i.uv);
        return float4(depth, depth, depth, 1.0);
    }
    

    ✅ 总结

    | 步骤 | 描述 | |------|------| | 1 | 在 ScriptableRendererFeature 中创建一个 RenderTexture 用于保存深度信息 | | 2 | 创建一个 ScriptableRenderPass 来将原始深度信息复制到该纹理 | | 3 | 编写一个 Shader 来实现深度信息的复制 | | 4 | 在其他 Shader 中使用你创建的纹理 |


    🔧 注意事项

    • 确保你的项目使用的是 URP,并且启用了 Depth Texture
    • 如果你没有启用深度纹理,请在 URP Asset 中开启:
      • Universal Render Pipeline > Renderer Settings > Enable Depth Texture
    • 如果你在使用 Shader Graph,可以使用 Sample Depth 节点来获取深度信息。

    💡 额外建议

    如果你只是想在 Shader 中使用类似 _CameraDepthTexture 的方式访问深度,建议使用 Shader Graph,它已经封装好了这些功能。


    如需进一步帮助,比如如何在 Shader Graph 中使用自定义深度贴图,也可以继续提问!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月9日
  • 创建了问题 2月9日