Atributos de textura de sombreador Labranza (escala) y Desplazamiento (desplazamiento) en Unity


Prefacio

Atributos de textura de sombreador Labrado (repetición) y Desplazamiento (desplazamiento) en Unity


1. Labranza (grado de escala), mi comprensión personal es un poco como el efecto de reducir el período de una función periódica (cuántas imágenes de funciones repetidas se pueden acomodar en una unidad de espacio)

2. Compensación (grado de compensación), mi comprensión personal es la traducción de la función.

Insertar descripción de la imagen aquí

La función g se entiende como la textura original y la función f se entiende como la textura después de Tilling y Offset.

La labranza es 2 en la imagen, el desplazamiento es 0,2 en la imagen

El labrado controla cuántas veces se puede repetir la textura dentro de la unidad de espacio, y el Desplazamiento controla cuánto se desplaza la textura.

URL de la calculadora gráfica: https://www.geogebra.org/graphing

3. Cuando use Tilling y Offset en Shader, debe declarar un vector de cuatro dimensiones después de la textura (debido a que es una textura, debe ser más preciso. Generalmente, se usa el vector de cuatro dimensiones float4, y el nombre se agrega con _ST después del nombre de la textura)

1. Luego aquí usamos el mapa de ruido del efecto de ablación como ejemplo. En el sombreador de fragmentos, al muestrear el mapa de ruido, use el vector bidimensional uv * XX_ST.xy + XX_ST.zw del mapa de ruido (aquí xy representa el xy de Tilling, zw representa el xy de Offset)

Insertar descripción de la imagen aquí

Ejemplo de código:

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

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

            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);
                o.uv = v.uv;
                return o;
            }

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

Efecto
Insertar descripción de la imagen aquí

2. Optimizar el código

Al muestrear en el sombreador de fragmentos, calcular la escala y el desplazamiento de cada punto de muestreo provocará una gran pérdida de rendimiento, por lo que esta operación se realiza en el sombreador de vértices.

Código reescrito:

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

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

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

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

            
            

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = 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;
                return o;
            }

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

Optimizar de nuevo

Unityt proporciona funciones para escalar y compensar
// Transforma UV 2D mediante la propiedad de escala/sesgo
#define TRANSFORM_TEX(tex,name) (tex.xy * nombre##_ST.xy + nombre##_ST.zw)

Para realizar el paso o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;, entonces reemplázalo con esta función

TRANSFORM_TEX(o.uv,_DissolveTex);

código final

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

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

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

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

            
            

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = 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;
				//存储使用 Tilling 和 Offset 参数后的结果
                o.uv.zw = TRANSFORM_TEX(o.uv,_DissolveTex);
                return o;
            }

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

Supongo que te gusta

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