现在有这么一个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,unity2020.3.33可用的内容:

根据您提供的信息,我注意到您的Shader是一个传统的着色器,而您正在使用的是Universal Render Pipeline (URP)。URP使用自己的渲染管线和着色器语言,因此需要对原始着色器进行修改以使其与URP兼容。

要将着色器转换为URP格式,您需要进行以下更改:

  1. 删除包含UnityCG.cginc的CGINCLUDE部分。在URP中,不再需要该文件并且不应使用。

  2. 在SubShader块之前添加URP的引用:URP之前的引用可以是:

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  1. 在SubShader块中,将Pass的渲染目标更改为URP的渲染目标。这可以通过将Pass块中的片段函数的输入和输出更改为URP的约定来完成。

下面是修改后的Shader代码:

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("SeaLevel", Float) = -1.0
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            
            #pragma vertex vert
            #pragma fragment frag
            
            #pragma target 3.0
            #pragma multi_compile_instancing
            #pragma shader_feature _ _ALPHATEST_ON _ALPHABLEND_ON _ALPHAPREMULTIPLY_ON
            #pragma shader_feature _SURFACE_TYPE_TRANSPARENT
            #pragma shader_feature _ENABLE_FOG_ON

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

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

            sampler2D _MainTex;
            sampler2D _GradTex;
            float4 _Reflection;
            float4 _Params1;
            float4 _Params2;
            float3 _Drop1;
            float3 _Drop2;
            float3 _Drop3;
            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);
            }
            
            v2f vert(appdata_t v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv * _Params1.xy;
                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);
                return lerp(c, _Reflection, fr);
            }
            ENDHLSL
        }
    }
}

请注意,这只是一个基本的转换示例。根据您的需求,您可能需要进行其他更改和调整以获得所需的效果。同时,也请确保将此修改后的Shader与URP的版本兼容。

URP 后处理:涟漪效果实现及Shader优化

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

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