现在有这么一个 urp 的 Pass 类,它已经被添加到了每帧的渲染队列中:

public class RipplePass : ScriptableRenderPass
{
    private Material rippleMaterial;

    public RipplePass(Material material)
    {
        rippleMaterial = material;
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        Debug.LogError('执行渲染后处理');
        
        CommandBuffer cmd = CommandBufferPool.Get('Ripple Pass');

        // 将输入纹理和输出纹理传递给材质
        cmd.Blit(renderingData.cameraData.renderer.cameraColorTarget,
            renderingData.cameraData.renderer.cameraColorTarget, rippleMaterial);

        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}

它所持有的材质 rippleMaterial 是没问题的。该材质对应的 shader 为:

Shader "Custom/RippleEffect"
{
    Properties
    {
        _MainTex("Base", 2D) = "white" {}
        _GradTex("Gradient", 2D) = "white" {}
        _Reflection("Reflection Color", Color) = (0, 0, 0, 0)
        _Params1("Parameters 1", Vector) = (1, 1, 0.8, 0)
        _Params2("Parameters 2", Vector) = (1, 1, 1, 0)
        _Drop1("Drop 1", Vector) = (0.49, 0.5, 0, 0)
        _Drop2("Drop 2", Vector) = (0.50, 0.5, 0, 0)
        _Drop3("Drop 3", Vector) = (0.51, 0.5, 0, 0)
		_SeaLevel("SeaVevel", Float) = -1.0
    }
    CGINCLUDE
    #include "UnityCG.cginc"

    sampler2D _MainTex;//输入源图像(后处理中相机绘制的原始画面)
    float2 _MainTex_TexelSize;
    sampler2D _GradTex;//涟漪振幅
    half4 _Reflection;
    float4 _Params1;    // [ aspect, 1, scale, 0 ]
    float4 _Params2;    // [ 1, 1/aspect, refraction, reflection ]
    float3 _Drop1;//涟漪1
    float3 _Drop2;//涟漪2
    float3 _Drop3;//涟漪3
	float _SeaLevel;

    float wave(float2 position, float2 origin, float time) //当前点位置, 出发点位置, 时间
    {
        float d = length(position - origin);
        float t = time - d * _Params1.z;
		if (_SeaLevel > 0 && position.y > _SeaLevel)// 超过海平面则不再扩散
		{
			return 0;
		}
		return (tex2D(_GradTex, float2(t, 0)).a - 0.5f) * 2;
    }
    float allwave(float2 position)// 计算当前点在三个涟漪下的共同作用效果(因为涟漪之间可能相交)
    {
		return
			wave(position, _Drop1.xy, _Drop1.z) +
			wave(position, _Drop2.xy, _Drop2.z) +
			wave(position, _Drop3.xy, _Drop3.z);
    }
    
	//伪代码 [RippleEffect.shader]  
    half4 frag(v2f_img i) : SV_Target
    {
        const float2 dx = float2(0.01f, 0);//delta x
        const float2 dy = float2(0, 0.01f);// delta y
        float2 p = i.uv * _Params1.xy;//根据比例变换uv
        float w = allwave(p);//振幅,用振幅来对当前点做UV上面的偏移,即可产生涟漪效果
        float2 dw = float2(allwave(p + dx) - w, allwave(p + dy) - w);//xy上振幅
        float2 duv = dw * _Params2.xy * 0.2f * _Params2.z; //ux上振幅
        half4 c = tex2D(_MainTex, i.uv + duv);//在原图上做偏移
        float fr = pow(length(dw) * 3 * _Params2.w, 3);
        return lerp(c, _Reflection, fr);//lerp来实现反射效果,优化表现
    }
    ENDCG
	
    SubShader
    {
        Pass
        {
            ZTest Always Cull Off ZWrite Off
            Fog { Mode off }
            CGPROGRAM
            #pragma fragmentoption ARB_precision_hint_fastest
            #pragma target 3.0
            #pragma vertex vert_img
            #pragma fragment frag
            ENDCG
        }
    } 
}

但是这个 Pass 并没有成功把图像后处理成我想要的效果,是什么原因呢?需要重写 shader 为 urp 格式下的 shader 吗?如果是,请返回修改后的 shader,unity 2020.3.33 可用的内容:根据给出的代码和问题描述,我注意到您正在使用的是传统的 ShaderLab 语法和内置的渲染管线(Built-in Render Pipeline)。然而,您正在使用的是 URP(Universal Render Pipeline)的渲染队列和渲染通道。

为了使您的 RipplePass 正常工作并实现您想要的效果,您需要将您的 ShaderLab 代码转换为 URP 的 Shader Graph。

下面是一个示例 URP Shader Graph,用于实现相同的涟漪效果:

Shader "Custom/RippleEffectURP"
{
    Properties
    {
        _MainTex("Base", 2D) = "white" {}
        _GradTex("Gradient", 2D) = "white" {}
        _Reflection("Reflection Color", Color) = (0, 0, 0, 0)
        _Params1("Parameters 1", Vector) = (1, 1, 0.8, 0)
        _Params2("Parameters 2", Vector) = (1, 1, 1, 0)
        _Drop1("Drop 1", Vector) = (0.49, 0.5, 0, 0)
        _Drop2("Drop 2", Vector) = (0.50, 0.5, 0, 0)
        _Drop3("Drop 3", Vector) = (0.51, 0.5, 0, 0)
        _SeaLevel("SeaVevel", Float) = -1.0
    }
    SubShader
    {
        Tags
        {
            "RenderType"="Opaque"
        }
        Stencil
        {
            Ref 0
            Comp always
        }
        Pass
        {
            Name "Base"
            Tags
            {
                "LightMode" = "ForwardBase"
            }
            Cull Off
            ZWrite Off
            ZTest Always
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            sampler2D _GradTex;
            float4 _Params1;
            float4 _Params2;
            float3 _Drop1;
            float3 _Drop2;
            float3 _Drop3;
            float _SeaLevel;

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                UNITY_TRANSFER_FOG(o, o.vertex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                const float2 dx = float2(0.01f, 0);
                const float2 dy = float2(0, 0.01f);
                float2 p = i.uv * _Params1.xy;
                float w = allwave(p);
                float2 dw = float2(allwave(p + dx) - w, allwave(p + dy) - w);
                float2 duv = dw * _Params2.xy * 0.2f * _Params2.z;
                fixed4 c = tex2D(_MainTex, i.uv + duv);
                float fr = pow(length(dw) * 3 * _Params2.w, 3);
                fixed4 reflection = _Reflection;
                return lerp(c, reflection, fr);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

请将此代码添加到您的项目中并应用到材质上,并使用新的 Shader 来构建 RipplePass。这将确保您的 RipplePass 在 URP 管线中正确工作,并实现您想要的效果。

请注意,此代码仅提供了一个基本的 URP Shader Graph 实现,您可能需要根据自己的需求进行调整和优化。

URP 中的涟漪后处理效果实现 -  RipplePass 类和 Shader Graph

原文地址: https://www.cveoy.top/t/topic/ol0O 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录