OpenGL顶点着色器非线性变换

时间:2018-02-19 21:31:41

标签: opengl vertex-shader

当我想进行线性变换时,我可以将变换矩阵传递给顶点着色器来做矩阵乘积。

gl_Position = gl_ModelViewMatrix * gl_Vertex

但是,如果我想进行非线性变换怎么办?例如,我想围绕x轴旋转一个立方体角度θ= 0.1 * x,因此最终可以扭曲立方体。

1 个答案:

答案 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));

你也可以创建四个转换矩阵并将它们链接起来,但这很可能会变慢并且需要花费更多的操作。