2012-05-31 49 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