Optimización de efectos visuales de ablación de Shader smoothstep(min,max,x) en Unity


Prefacio

Optimización de los efectos visuales de ablación de Shader en Unity

1. Utilice smoothstep(min,max,x) según el clip(value) y agregue una textura degradada para optimizar visualmente el borde de ablación.

Por favor agregue la descripción de la imagen.
Por favor agregue la descripción de la imagen.
Utilice la textura de ruido para muestrear la textura degradada y deje que las partes negras de la textura de ruido correspondan a las partes negras de la textura degradada para lograr el efecto de gradiente de borde.Después del muestreo, simplemente agréguelo al resultado del muestreo 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
        }
    }
}

Efecto

Insertar descripción de la imagen aquí

2. Optimizar

Funciones incluidas en la función smoothstep:

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

Puede utilizar la siguiente figura para comprender
Insertar descripción de la imagen aquí

La función t es antes del suavizado y
la función f es después del suavizado.
Debido a que no necesitamos suavizado en este momento, podemos usar smoothstep directamente para consumir rendimiento, por lo que debemos optimizarlo.

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
        }
    }
}


Optimización final:

Debido a que cuando se usa la textura degradada, solo se usa la coordenada u de la textura degradada, reemplace sampler2D con sampler

Modifique los siguientes dos lugares

muestreador2D _RampTex; -->muestreador _RampTex;

fijo4 rampTex = tex2D(_RampTex,dissolveValue); -->fixed4 rampTex = tex1D(_RampTex,dissolveValue.r);

Insertar descripción de la imagen aquí

Supongo que te gusta

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