Otimização de efeitos visuais de ablação do Shader smoothstep (min, max, x) no Unity


Prefácio

Otimização dos efeitos visuais de ablação do Shader no Unity

1. Use smoothstep(min,max,x) com base no clip(value) e adicione uma textura gradiente para otimizar visualmente a borda da ablação.

Adicione a descrição da imagem
Adicione a descrição da imagem
Use a textura de ruído para amostrar a textura gradiente e deixe as partes pretas da textura de ruído corresponderem às partes pretas da textura gradiente para obter o efeito gradiente de borda. Após a amostragem, basta adicioná-lo ao resultado da amostragem de textura original.

Shader "MyShader/P0_7_9"
{
    Properties
    {
        //使用这个标签,可以使外部暴露属性,有标题
        [Header(Base)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        _Clip("Clip",Range(0,1)) = 0

        
        //使用这个标签可以 在两行暴露属性之间加 间隙
        [Space(10)]
        [Header(Dissolve)]
        _DissolveTex("DissolveTex",2D) = "white"{}

        [NoScaleOffset]_RampTex("RampTex",2D) = "black" {}

    }
    SubShader
    {
      
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            sampler2D _MainTex;
            float _Clip;
            sampler2D _DissolveTex; 
           

            //这个四维向量,xyzw分别表示 Tilling 和 Offset 的 xy ,命名方式 在纹理名 后加 _ST
            float4 _DissolveTex_ST;

            sampler2D _RampTex;

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

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            
            

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                
                //为了减少传入的值 ,所以就不创建新变量来存储,而是把 uv 改为  四维向量 来用
                //使用 o.uv 的 xy 来存放 原人物贴图
                //使用 o.uv 的 zw 来存放 噪波贴图缩放 和 偏移 后的值
                o.uv.xy = v.uv.xy;
                //o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;

                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col;

                fixed4 _mainTex = tex2D(_MainTex, i.uv.xy);
                col = _mainTex;
               
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                //片段的取舍
                clip(dissolveTex.r -  _Clip);

                //进行视觉上的优化
                //smoothstep(min,max,x)
                //x < min ,y = min;
                //x > max ,y = max;
                //min < x < max,y = x;
                fixed4 rampTex = tex2D(_RampTex,smoothstep(_Clip,_Clip + 0.1,dissolveTex.r));
                col += rampTex;
                return col;
            }
            ENDCG
        }
    }
}

Efeito

Insira a descrição da imagem aqui

2. Otimize

Funções incluídas na função smoothstep:

float smoothstep(min,max,x)
{
	//归一化(线性插值)
	float t = saturate(x - min) / (max - min);
	//平滑
	return t * t * (3 - 2 * t);
}

Você pode usar a figura a seguir para entender
Insira a descrição da imagem aqui

A função t é antes da suavização e
a função f é depois da suavização.
Como não precisamos de suavização no momento, podemos usar smoothstep diretamente para comparar o desempenho, por isso precisa ser otimizado.

Código modificado:

Shader "MyShader/P0_7_9"
{
    Properties
    {
        //使用这个标签,可以使外部暴露属性,有标题
        [Header(Base)]
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        _Clip("Clip",Range(0,1)) = 0
        //使用这个标签可以 在两行暴露属性之间加 间隙
        [Space(10)]
        [Header(Dissolve)]
        _DissolveTex("DissolveTex",2D) = "white"{}

        [NoScaleOffset]_RampTex("RampTex(RGB)",2D) = "black" {}

    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            sampler2D _MainTex;
            float _Clip;
            sampler2D _DissolveTex; 
            //这个四维向量,xyzw分别表示 Tilling 和 Offset 的 xy ,命名方式 在纹理名 后加 _ST
            float4 _DissolveTex_ST;

            sampler2D _RampTex;

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

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                
                //为了减少传入的值 ,所以就不创建新变量来存储,而是把 uv 改为  四维向量 来用
                //使用 o.uv 的 xy 来存放 原人物贴图
                //使用 o.uv 的 zw 来存放 噪波贴图缩放 和 偏移 后的值
                o.uv.xy = v.uv.xy;
                //o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;

                o.uv.zw = TRANSFORM_TEX(v.uv,_DissolveTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv.xy);
                //外部获取的 纹理 ,使用前都需要采样
                fixed4 dissolveTex = tex2D(_DissolveTex,i.uv.zw);
                //片段的取舍
                clip(dissolveTex.r -  _Clip);

                //进行归一化
                fixed4 dissolveValue = saturate((dissolveTex.r - _Clip) / (_Clip + 0.1 - _Clip));

                fixed4 rampTex = tex2D(_RampTex,dissolveValue);

                col += rampTex;
                return col;
            }
            ENDCG
        }
    }
}


Otimização final:

Porque ao usar a textura gradiente, apenas a coordenada u da textura gradiente é usada, então substitua sampler2D por sampler

Modifique os dois locais a seguir

sampler2D _RampTex; -> amostrador _RampTex;

fixo4 rampaTex = tex2D(_RampTex,dissolveValue); -> fixo4 rampaTex = tex1D(_RampTex,dissolveValue.r);

Insira a descrição da imagem aqui

Acho que você gosta

Origin blog.csdn.net/qq_51603875/article/details/132550675
Recomendado
Clasificación