ainatipen 发表于 2022-10-7 16:10

Unity面试题学习笔记(10)——Shader入门操作篇

1.矩阵转换:


[*]第一步,将物体从局部空间转到世界空间(model matrix)
Vector3 worldPos = transform.parent.localToWorldMatrix.MultiplyPoint(transform.localPosition);

[*]第二步,将物体从世界空间转到相机的观察空间(view matrix)
Vector3 viewPos = cameraTrans.worldToLocalMatrix.MultiplyPoint(worldPos);
2.顶点波动:


[*]在顶点着色器中对顶点的位置进行修改。
[*]_Time:



Unity手册中介绍的时间相关参数


[*]使用sin函数实现顶点的波动(把vertex.y看作sin函数的y轴,把vertex.x看作sin函数的x轴)
v.vertex.y += _A * sin(_Time.y + v.vertex.x);



sin函数的图形表示

3.uv滚动:

在片元着色器中,对纹理进行采样之前,让uv坐标随时间而发生改变:
i.uv.x += _Time.y;
fixed4 col = tex2D(_MainTex, i.uv);



滚动效果

4.uv旋转:

因为uv坐标是在(0,1)范围内的二维坐标系中,可以通过三角函数的方式得到旋转后的点的坐标。(注意,下图中r是指斜边的长,也就是原点到uv点的长)



计算新uv坐标(x',y')的过程

在片元着色器中,对用于采样的uv坐标进行修改,用传入的uv坐标使用上述公式计算得到新的uv坐标(旋转量等于时间变化量)
                float angle = _Time.y;
                float2 uv = (0,0);
                uv.x = i.uv.x * cos(angle) + i.uv.y * sin(angle);
                uv.y = i.uv.y * cos(angle) + i.uv.x * sin(angle);
                fixed4 col = tex2D(_MainTex, uv);
默认旋转中心为原点,如果我们希望旋转中心从原点变为(0.5,0.5),可以将整个uv坐标空间向左下方移动0.5(所有uv坐标减去(0.5,0.5)),此时原点就变成了原来的(0.5,0.5)。在结束旋转操作后,再将其复原。
                float angle = _Time.y;
                float2 uv = (0,0);
                i.uv -= float2(0.5,0.5);



                uv.x = i.uv.x * cos(angle) + i.uv.y * sin(angle);
                uv.y = i.uv.y * cos(angle) + i.uv.x * sin(angle);

                uv += float2(0.5,0.5);
                fixed4 col = tex2D(_MainTex, uv);
由于旋转过程中,坐标可能超过(0,1)范围,我们可以在旋转前判断uv坐标是否越界,如果越界了就将其舍弃(返回fixed4(0,0,0,0))。注意,length是库提供的方法,可以计算向量的长度。
                if(length(i.uv) > 0.5) {
                  return fixed4(0,0,0,0);
                }
页: [1]
查看完整版本: Unity面试题学习笔记(10)——Shader入门操作篇