Unity中Shader 纹理属性 Tilling(缩放度) 和 Offset(偏移度)


前言

Unity中Shader 纹理属性 Tilling(重复度) 和 Offset(偏移度)


一、Tilling(缩放度),个人理解有点像减小周期函数的周期的效果(在单位空间内,容得下重复的函数图像的多少)

二、Offset(偏移度),个人理解是函数的平移

在这里插入图片描述

把 g 函数理解为 原贴图,f函数理解为 经过Tilling 和 Offset 后的贴图。

Tilling就是 图中 的 2 ,Offset就是图中的0.2

Tilling控制单位空间内,贴图可以重复几次,Offset控制贴图偏移多少

图形计算器网址:https://www.geogebra.org/graphing

三、在Shader中使用 Tilling 和 Offset 时,需要在纹理后申明一个 四维向量(因为是纹理,需要精确一点,一般使用float4这个四维向量,且名字在贴图名后加 _ST 即可)

1、然后这里用消融效果的噪波贴图做例子,就是在片元着色器中,对噪波贴图进行采样时,使用噪波贴图的二维向量 uv * XX_ST.xy + XX_ST.zw (这里的xy代表Tilling的xy,zw代表Offset的xy)

在这里插入图片描述

代码示例:

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

效果
在这里插入图片描述

2、优化代码

在片元着色器取样时,对每一个取样点都计算 缩放 和 偏移 对性能损耗较大,故在顶点着色器中进行该操作

改写后的代码:

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

再次优化

Unityt提供额缩放和偏移的函数
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)

来进行 o.uv.zw = v.uv * _DissolveTex_ST.xy + _DissolveTex_ST.zw;这步,所以替换为该函数

TRANSFORM_TEX(o.uv,_DissolveTex);

最终代码

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楠溪泽岸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值