我在"参数"中定义了广告牌的角落。空间。要从参数空间转换为世界空间,我使用一个名为T:
的矩阵bbCorners[i] = T*pBbCorners[i] + center; // billboard corner i transformed into world space
现在我按如下方式渲染这些角落:
glBegin(GL_QUADS);
for (unsigned i = 0; i < 4; i++)
glVertex3f(bbCorners[i].x, bbCorners[i].y, bbCorners[i].z);
glEnd();
当我的顶点着色器看起来像这样时,一切都呈现得很好(我确保上传制服的参数空间角落):
#version 120
#extension GL_EXT_gpu_shader4 : enable
// Parameter space billboard corners
uniform vec4 pBBTopLeft;
uniform vec4 pBBBottomLeft;
uniform vec4 pBBBottomRight;
uniform vec4 pBBTopRight;
// Parameter to world space matrix
uniform mat4 T;
// Center of ellipsoid
uniform vec4 center;
// Parameter space position of fragment on billboard
varying vec4 pPosBB;
void main() {
switch (gl_VertexID) {
case 0: pPosBB = pBBTopLeft; break;
case 1: pPosBB = pBBBottomLeft; break;
case 2: pPosBB = pBBBottomRight; break;
case 3: pPosBB = pBBTopRight; break;
default: pPosBB = vec4(vec3(0), 1); break;
}
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
现在,问题如下。当我用顶点位置的相同计算替换 gl_Vertex 时,但在着色器中,我得到不同的结果。
vec4 worldPos = transpose(T) * pPosBB + center; // Transpose because column major
gl_Position = gl_ModelViewProjectionMatrix * worldPos;
有谁知道为什么转换会有所不同?
编辑:这是计算T的方式:
// Specify orientation matrix by axes of ellipsoid
float fO[16] = {
axis1.x, axis2.x, axis3.x, 0.f,
axis1.y, axis2.y, axis3.y, 0.f,
axis1.z, axis2.z, axis3.z, 0.f,
0.f, 0.f, 0.f, 1.f};
qfeMatrix4f O;
qfeMatrix4f::qfeSetMatrixElements(O, fO);
// Specify radius matrix (lengths of axes)
float fLambda[16] = {
lambda1, 0.f, 0.f, 0.f,
0.f, lambda2, 0.f, 0.f,
0.f, 0.f, lambda3, 0.f,
0.f, 0.f, 0.f, 1.f};
qfeMatrix4f Lambda;
qfeMatrix4f::qfeSetMatrixElements(Lambda, fLambda);
// Calculate transformation matrix
T = O*Lambda;
编辑: 解决了!
原来 T * pPosBB 和 center 都有 w = 1 。将它们添加到一起会导致 worldPos =(x,y,z,2),这会弄乱我们的坐标。