Attributs de texture du shader Tilling (échelle) et Offset (décalage) dans Unity


Préface

Attributs de texture du shader Tilling (répétition) et Offset (décalage) dans Unity


1. Tilling (degré de mise à l'échelle), ma compréhension personnelle est un peu comme l'effet de la réduction de la période d'une fonction périodique (combien d'images de fonctions répétées peuvent être hébergées dans un espace unitaire)

2. Offset (degré de décalage), ma compréhension personnelle est la traduction de la fonction

Insérer la description de l'image ici

La fonction g est comprise comme la texture d'origine et la fonction f est comprise comme la texture après Tilling et Offset.

Le labourage est de 2 sur l'image, le décalage est de 0,2 sur l'image

Tilling contrôle le nombre de fois que la texture peut être répétée dans l'espace unitaire, et Offset contrôle le degré de décalage de la texture.

URL de la calculatrice graphique : https://www.geogebra.org/graphing

3. Lorsque vous utilisez Tilling et Offset dans Shader, vous devez déclarer un vecteur à quatre dimensions après la texture (car il s'agit d'une texture, il doit être plus précis. Généralement, le vecteur à quatre dimensions float4 est utilisé et le nom est ajouté avec _ST après le nom de la texture)

1. Ensuite, nous utilisons ici comme exemple la carte de bruit de l'effet d'ablation. Dans le fragment shader, lors de l'échantillonnage de la carte de bruit, utilisez le vecteur bidimensionnel uv * XX_ST.xy + XX_ST.zw de la carte de bruit (ici xy représente le xy du Tilling, zw représente le xy du Offset)

Insérer la description de l'image ici

Exemple de code :

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

Effet
Insérer la description de l'image ici

2. Optimiser le code

Lors de l'échantillonnage dans le fragment shader, le calcul de la mise à l'échelle et du décalage pour chaque point d'échantillonnage entraînera une perte de performances importante, cette opération est donc effectuée dans le vertex shader.

Code réécrit :

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

Optimiser à nouveau

Unityt fournit des fonctions de mise à l'échelle et de décalage
// Transforme les UV 2D par propriété d'échelle/biais
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

Pour réaliser l'étape o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;, remplacez-le donc par cette fonction

TRANSFORM_TEX(o.uv,_DissolveTex);

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

Je suppose que tu aimes

Origine blog.csdn.net/qq_51603875/article/details/132527176
conseillé
Classement