描述:
今天看第十一章,其中 11.2.1 中的片元着色器看了很久才看明白,终于搞明白了为什么没有取余操作,特来记录下。
代码:
fixed4 frag (v2f i) : SV_Target {
float time = floor(_Time.y * _Speed);
float row = floor(time / _HorizontalAmount);
float column = time - row * _HorizontalAmount;
half2 uv = float2(i.uv.x /_HorizontalAmount, i.uv.y / _VerticalAmount);
uv.y -= row / _VerticalAmount;
uv.x += column / _HorizontalAmount;
fixed4 c = tex2D(_MainTex, uv);
c.rgb *= _Color;
return c;
}
理解:
- 核心就是用之前对整个纹理的采样坐标映射为对纹理中某一块的采样坐标。
- 首先代码中的纹理采用的是 Repeat 模式,这也就意味着 uv 坐标超出 1 的部分会直接取其余数很重要。
- 由于是 Repeat 模式,上方示意图中每个大的正方形代表用到的纹理,纵向重复排列,红色方块代表当前选中的关键帧。计算过程如下。
- 首先
time
取整后可以简单看作从左往右,从上往下选中第几张图中的某一块,也就是块号。 row
就可以代表行数,col
代表列数,如图。- 接着将
uv
坐标范围映射到小方块中,例如图中红色部分。 - 然后我们加上偏移量就可以得到真正的
uv
坐标了。直觉上直接加上对应的row
与col
即可,但是不要忘了uv
采样坐标是0~1范围内的,因此要把row
与col
分别除以行数和列数,这个量才可以表示为真正的偏移量。 - 因此书中还有一种计算方式,将
uv
坐标直接与行列偏移量相加,然后再映射到小方块中(除以行数和列数)
half2 uv = i.uv + half2(column, -row);
uv.x /= _HorizontalAmount;
uv.y /= _VerticalAmount;
类似下面的图
最后,repeat 模式会自动取超过1的小数部分,就可以得到正确的 uv
坐标了。
如果发现描述有误,请在评论区指正,欢迎一起交流。