当我想进行线性变换时,我可以将变换矩阵传递给顶点着色器来做矩阵乘积。
gl_Position = gl_ModelViewMatrix * gl_Vertex
但是,如果我想进行非线性变换怎么办?例如,我想围绕x轴旋转一个立方体角度θ= 0.1 * x,因此最终可以扭曲立方体。
答案 0 :(得分:3)
是的,这可以在顶点着色器中实现。如果先创建旋转矩阵并不重要,但为简单起见,我将展示如何直接应用旋转:
float theta = 0.1 * gl_Vertex.x;
vec4 twisted_vertex = vec4(
gl_Vertex.x,
cos(theta) * gl_Vertex.y - sin(theta) * gl_Vertex.z,
sin(theta) * gl_Vertex.y + cos(theta) * gl_Vertex.z,
gl_Vertex.w);
您现在可以执行已经在扭曲顶点而不是原始顶点上进行的常规计算,例如:
gl_Position = gl_ModelViewMatrix * twisted_vertex;
请注意,当您将其应用于简单的多维数据集(8个角,36个三角形)时,结果可能不是您所期望的。变换仅应用于顶点(8个角)而不应用于边。如果你想扭曲一个立方体,那么你必须确保它沿着x轴被镶嵌得足够高。
编辑:这里是沿y移动,沿x扭转,沿z移动,沿x扭转。基本上,您可以根据需要链接所有这些转换。
vec4 twist(vec4 v, float theta)
{
vec4 twisted_vertex = vec4(
v.x,
cos(theta) * v.y - sin(theta) * v.z,
sin(theta) * v.y + cos(theta) * v.z,
v.w);
return twisted_vertex;
}
//In main
//Move along y and first twist
vec4 v1 = twist(gl_Vertex + vec4(0, y_move, 0, 0));
//Move along z and second twist
vec4 v2 = twist(v1 + vec4(0, 0, z_move, 0));
你也可以创建四个转换矩阵并将它们链接起来,但这很可能会变慢并且需要花费更多的操作。