2012-05-31 51 views
0

我有一个装载网格,地平面和天空盒的小场景。我正在生成一个立方体,并使用顶点位置作为立方体贴图纹理坐标。Skybox旋转与世界不同步

水平旋转(围绕Y轴)完美地工作,世界运动与天空盒对齐。垂直旋转(关于相机的X轴)似乎与其他物体的移动不匹配,除了奇怪的是,当相机看着立方体脸部的中心时,一切似乎都对齐了。换句话说,运动是非线性的,我会尽我所能,以说明一些图像效果:

首先,水平移动,其只要我可以告诉是正确的:

面对前进:Facing forward

向左几乎45Deg: Facing left at almost 45Deg

向左在90度: Facing left at 90Deg

而现在这似乎垂直运动有运动有一定差距:

又向前朝向: Facing forward again

注意接地平面相对于该图像中的天空盒的位置。我稍微向左旋转,以便更明显地看到太阳不应该被遮挡。

面对略有下降: Facing slightly down

最后,图直线上升,以显示视图被正确地集中在(天空盒)立方体的表面。

面对直线上升: Facing straight up

这里是我的绘制代码,与地平面和网格绘制不再赘述。 (请注意,中心的立方体是一个加载的网格,并不是由天空箱的相同功能生成的)。

void MeshWidget::draw() { 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glPushMatrix(); 

    glRotatef(-rot_[MOVE_CAMERA][1], 0.0f, 1.0f, 0.0f); 
    glRotatef(-rot_[MOVE_CAMERA][0], 1.0f, 0.0f, 0.0f); 
    glRotatef(-rot_[MOVE_CAMERA][2], 0.0f, 0.0f, 1.0f); 

    glDisable(GL_DEPTH_TEST); 
    glUseProgramObjectARB(shader_prog_ids_[2]); 
    glBindBuffer(GL_ARRAY_BUFFER, SkyBoxVBOID); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glVertexPointer(3, GL_FLOAT, sizeof(Vec3), BUFFER_OFFSET(0)); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, SkyIndexVBOID); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); 
    glUseProgramObjectARB(shader_prog_ids_[0]); 
    glEnable(GL_DEPTH_TEST); 

    glPopMatrix(); 

    glTranslatef(0.0f, 0.0f, -4.0f + zoom_factor_); 

    glRotatef(rot_[MOVE_CAMERA][0], 1.0f, 0.0f, 0.0f); 
    glRotatef(rot_[MOVE_CAMERA][1], 0.0f, 1.0f, 0.0f); 
    glRotatef(rot_[MOVE_CAMERA][2], 0.0f, 0.0f, 1.0f); 

    glPushMatrix(); 

    // Transform light to be relative to world, not camera. 
    glRotatef(rot_[MOVE_LIGHT][1], 0.0f, 1.0f, 0.0f); 
    glRotatef(rot_[MOVE_LIGHT][0], 1.0f, 0.0f, 0.0f); 
    glRotatef(rot_[MOVE_LIGHT][2], 0.0f, 0.0f, 1.0f); 

    float lightpos[] = {10.0f, 0.0f, 0.0f, 1.0f}; 
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos); 

    glPopMatrix(); 

    if (show_ground_) { 

     // Draw ground... 
    } 

    glPushMatrix(); 

    // Transform and draw mesh... 

    glPopMatrix(); 
} 

最后,以下是天空盒的GLSL代码,它生成的纹理坐标:

顶点着色器:

void main() 
{ 
    vec4 vVertex = vec4(gl_ModelViewMatrix * gl_Vertex); 

    gl_TexCoord[0].xyz = normalize(vVertex).xyz; 
    gl_TexCoord[0].w = 1.0; 

    gl_TexCoord[0].x = -gl_TexCoord[0].x; 

    gl_Position = gl_Vertex; 
} 

片段着色器:

uniform samplerCube cubeMap; 

void main() 
{ 
    gl_FragColor = texture(cubeMap, gl_TexCoord[0]); 
} 

我也想知道如果对所有相机和物体旋转使用四元数会有所帮助。

如果您需要更多信息(或图片),请询问!

回答

0

我想你应该根据世界空间矢量(gl_Vertex?)而不是视图空间矢量(vVertex)来生成你的天空盒纹理查找。

我假设你的天空盒坐标已经在世界空间中定义了,因为在绘制之前我没有看到模型矩阵变换(只有相机旋转)。在这种情况下,您应该根据顶点的世界空间位置对天空盒纹理进行采样,而不需要由相机进行变换。您已经通过摄像头翻译顶点,您也不需要翻译查找矢量。

尝试normalize(gl_Vertex)更换normalize(vVertex),看看是否能提高的东西。

我也可能摆脱X = -x的事情,我怀疑是投入,以弥补该纹理是在错误的方向旋转原来的事实呢?

我也想知道是否所有相机和物体旋转使用四元数会有所帮助。

帮助如何?它不提供任何使用矩阵的新功能。我听说过的参数两种方式,以矩阵或四元数是否有更好的表现,但我认为没有必要使用它们。

+0

我已经删除了X = -x的一部分,这是我原来在我之前使用的是天空盒,由于加入翻转纹理 - 我假定所有DDS纹理进行格式化这种方式,但事实证明这只是特定的一个。 我已经用你所建议的世界空间矢量替换了视图空间矢量,但无论我的观点如何,空间框现在都是静态背景。根据我的理解,相机旋转确实会影响模型视图矩阵,所以我期望得到结果。 – usm