UnityShader中经常出现类似“float4 _MainTex_ST”、“float4 _BumpTex_ST;”的字段声明,但是却没有任何引用 ,找了下资源才知道是怎么回事,参考网址:传送门
下面是一个最简单的纹理采样Shader
Shader "Custom/MainTex_ST" { Properties { _MainTex("MainTex",2D) = "white"{} } SubShader { LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag uniform float4 _LightColor0; struct a2v { float4 model_vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 clip_pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; v2f vert(a2v v) { v2f o; o.uv = v.uv; o.clip_pos = UnityObjectToClipPos(v.model_vertex); return o; } fixed4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } }
我们使用该Shader创建一个材质球,点击该材质球,观察它的检视面板如下:
发现有一个Tiling与Offset属性的输入框,但是我们并没有在Properties中对其进行声明,也就是说只要你在
那么我们如何在Shader中获取这个变量的呢,方法就是 纹理的名称_ST,比如我在Properties定义的输入纹理名称为_MainTex,那么对应的平铺偏移控制变量名称为_MainTex_ST,变量类型为float4,其中_MainTex_ST.xy对应Tiling,_MainTex_ST.zw对应Offset
我们修改上面的Shader如下:
Shader "Custom/MainTex_ST" { Properties { _MainTex("MainTex",2D) = "white"{} } SubShader { LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag uniform float4 _LightColor0; struct a2v { float4 model_vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 clip_pos : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; float4 _MainTex_ST; v2f vert(a2v v) { v2f o; o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw; o.clip_pos = UnityObjectToClipPos(v.model_vertex); return o; } fixed4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDCG } } }
此时在回到检视面板发现修改Tiling与Offset属性,效果如下:
最后:
o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw;
等同于
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
这个宏被定义在UnityCG.cginc中,所以要使用记得#include "UnityCG.cginc"
这也是以为_MainTex_ST没有被引用的原因,事实上只是换了一种方式引用了,如果不声明_MainTex_ST,也无法使用下面这句话,会报"Shader error in 'Custom/MainTex_ST': undeclared identifier '_MainTex_ST' at line 35 (on d3d11)"的错误
补充:
o.uv = v.uv * _MainTex_ST.xy + _MainTex_ST.zw; 中 v.uv * _MainTex_ST.xy 结果超过1为什么会从头开始取,原因是贴图格式的默认设置 Warp Model 为 Repeat
参考:https://catlikecoding.com/unity/tutorials/rendering/part-2/
文章评论