巨巨巨巨大花卷 2023-01-16 14:58 采纳率: 0%
浏览 44

Unity shader 内置管线 屏幕空间积雪特效 如何改成 urp 管线的特效

Unity shader 内置管线 屏幕空间积雪特效 如何改成 urp 管线的特效

原链接:https://blog.csdn.net/shenzhan168/article/details/77094983

尝试修改了shader脚本,如下,但是没有效果


```c#

Shader "Hidden/SnowImageEffectShader_Simple"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    }
        SubShader
    {

        Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
        LOD 100
        // No culling or depth
        //Cull Off ZWrite Off ZTest Always

        Pass
        {
            Tags{"LightMode" = "UniversalForward"}

            ZTest Always
            ZWrite Off
            Cull Off

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //#include "UnityCG.cginc"//升级URP
           #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
           //#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert(appdata v)
            {
                v2f o;
                //o.vertex = UnityObjectToClipPos(v.vertex);//升级urp

                VertexPositionInputs vertexInput = GetVertexPositionInputs(v.vertex.xyz);
                o.vertex = vertexInput.positionCS;

                o.uv = v.uv;
                return o;
            }

            //sampler2D _MainTex;
            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            

            //sampler2D _CameraDepthNormalsTexture; //深度纹理
            TEXTURE2D(_CameraDepthNormalsTexture);
            SAMPLER(sampler_CameraDepthNormalsTexture);


            float4x4 _CamToWorld;  //摄像机空间 到 世界空间的变换

            //sampler2D _SnowTex;
            TEXTURE2D(_SnowTex);
            SAMPLER(sampler_SnowTex);

            float4 _SnowColor;

            float _SnowButtom;  // 积雪的阈值设置
            float _SnowScale;


            float4 frag(v2f i) : SV_Target
            {

                float3 normal;
                float depth;

                float2 uv = float2(i.uv.x, i.uv.y);

                //获取像素的世界坐标空间的法线
                //DecodeDepthNormal(tex2D(_CameraDepthNormalsTexture, uv), depth, normal);//urp管线没有这个函数DecodeDepthNormal,不知道有没有替代的函数
//以下是从cg方法里面拷贝过来的算法
                float4 enc4 = SAMPLE_TEXTURE2D(_CameraDepthNormalsTexture, sampler_CameraDepthNormalsTexture, uv);

                //获得深度
                float2 kDecodeDot = float2(1.0, 1 / 255.0);
                depth = dot(enc4.zw, kDecodeDot);


                //获取像素的世界坐标空间的法线
                float kScale = 1.7777;
                float3 nn = enc4.xyz * float3(2 * kScale, 2 * kScale, 0) + float3(-kScale, -kScale, 1);
                float g = 2.0 / dot(nn.xyz, nn.xyz);
                float3 n;
                n.xy = g * nn.xy;
                n.z = g - 1;
                normal = n;
             
                normal = mul((float3x3)_CamToWorld, normal);


                //计算积雪阈值
                float snowAmount = normal.g * _SnowScale;
                if (snowAmount < _SnowButtom)
                {
                    snowAmount = 0;
                }

                //原本的贴图采样
                float4 snowColor = SAMPLE_TEXTURE2D(_SnowTex, sampler_SnowTex, uv) * _SnowColor;

                float4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
                return lerp(col, float4(snowColor.rgb,1), snowAmount);

            }
            ENDHLSL
        }
    }
}

摄像机脚本:

```c#

using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class SnowImageEffectScript_Simple : PostEffectsBase {

    public Shader shader;
    private Material _material = null;
    public Material material {  
        get {
            _material = CheckShaderAndCreateMaterial(shader, _material);
            return _material;
        }  
    }


    public Texture2D SnowTexture;
    public Color SnowColor = Color.white;


    [Range(0, 1)]
    public float _SnowButtom = 0f;
    [Range(0, 10)]
    public float _SnowScale = 1f;


    void OnEnable() {
        GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
    }


    void OnRenderImage (RenderTexture src, RenderTexture dest) {
        if (material != null) {

            // set shader properties
            _material.SetMatrix("_CamToWorld", GetComponent<Camera>().cameraToWorldMatrix);
            _material.SetColor("_SnowColor", SnowColor);
            _material.SetFloat("_SnowButtom", _SnowButtom);
            _material.SetFloat("_SnowScale", _SnowScale);
            _material.SetTexture("_SnowTex", SnowTexture);

            Graphics.Blit(src, dest, material);
        } else {
            Graphics.Blit(src, dest);
        }
    }

}

又改了一遍还是不行嘤嘤

  • 写回答

1条回答 默认 最新

  • cp0001cp 2023-01-17 12:36
    关注

    在使用URP管线时,需要注意一些细节的差异。首先需要确保你已经将URP管线设置为项目的渲染管线。

    在修改shader脚本中,需要使用URP相关的HLSL文件,例如#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"。这个文件中包含了URP管线的核心功能和宏定义。

    在顶点着色器的vert函数中,需要使用URP提供的GetVertexPositionInputs()函数来获取顶点的屏幕空间位置,而不是使用UnityCG.cginc中的UnityObjectToClipPos()函数。

    在片元着色器的frag函数中,需要使用URP提供的格式进行深度和法线信息的解码,例如使用DecodeDepthNormal()函数,而不是使用UnityCG.cginc中的tex2D()函数和自定义解码方式。

    另外还需要注意URP管线和内置管线在顶点着色器和片元着色器的宏定义和渲染标签的差异,需要对应的修改。

    建议可以先参考URP官方文档或者示例项目中的shader脚本来了解URP管线的使用方法。

    评论

报告相同问题?

问题事件

  • 修改了问题 1月17日
  • 创建了问题 1月16日

悬赏问题

  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并
  • ¥20 pcf8563时钟芯片不启振
  • ¥20 pip2.40更新pip2.43时报错