2012-03-25 85 views
4

作爲試圖產生一個非常簡單的外觀天空的一部分,我創建了一個天空盒(基本上是一個從(-1,-1,-1)到(1,1,1)的立方體,這畢竟是我的幾何圖形繪製,被迫通過以下簡單的頂點着色器的背面:簡單程序skybox

#version 330 
layout(location = 0) in vec4 position; 
layout(location = 1) in vec4 normal; 

out Data 
{ 
    vec4 eyespace_position; 
    vec4 eyespace_normal; 
    vec4 worldspace_position; 
    vec4 raw_position; 
} vtx_data; 

uniform mat4 model; 
uniform mat4 view; 
uniform mat4 projection; 

void main() 
{ 
    mat4 view_without_translation = view; 
    view_without_translation[3][0] = 0.0f; 
    view_without_translation[3][1] = 0.0f; 
    view_without_translation[3][2] = 0.0f; 

    vtx_data.raw_position = position; 
    vtx_data.worldspace_position = model * position; 
    vtx_data.eyespace_position = view_without_translation * vtx_data.worldspace_position; 

    gl_Position = (projection * vtx_data.eyespace_position).xyww; 
} 

從此,我試圖讓我的天空顯示爲從在一個深藍色的一個非常簡單的梯度頂部到地平線上的淺藍色

顯然,根據每個片段的Y座標簡單地混合我的兩種顏色看起來會非常糟糕:事實上,您正在查看盒子而不是圓頂立即清理R,因爲在這裏看到:

wrong skybox

注意相當明顯的「角落」在框的左上角和右上角。

本能地說,我認爲明顯的解決辦法是規範化每個片段的位置,以獲得單位球體上的位置,然後取其Y座標。如果這是有道理的,我認爲這會導致對於給定的「高度」而言恆定的值。就像這樣:

#version 330 
in Data 
{ 
    vec4 eyespace_position; 
    vec4 eyespace_normal; 
    vec4 worldspace_position; 
    vec4 raw_position; 
} vtx_data; 

out vec4 outputColor; 

const vec4 skytop = vec4(0.0f, 0.0f, 1.0f, 1.0f); 
const vec4 skyhorizon = vec4(0.3294f, 0.92157f, 1.0f, 1.0f); 

void main() 
{ 
    vec4 pointOnSphere = normalize(vtx_data.worldspace_position); 
    float a = pointOnSphere.y; 
    outputColor = mix(skyhorizon, skytop, a); 
} 

但是結果是一樣一樣的,第一個屏幕(如果需要的話我可以發佈,但由於它是視覺上相似於第一,我跳過它縮短這個問題現在)。

一些隨機擺弄後(貨物崇拜編程,我知道:/),我才意識到,這個工程:

void main() 
{ 
    vec3 pointOnSphere = normalize(vtx_data.worldspace_position.xyz); 
    float a = pointOnSphere.y; 
    outputColor = mix(skyhorizon, skytop, a); 
} 

唯一的區別是,我沒有正常化它的成分W的位置。

而這裏的工作結果:(所不同的是在屏幕截圖微妙,但在運動相當明顯) correct skybox

所以,最後,我的問題:爲什麼這個工作的時候以前的版本失敗?我必須誤解一些關於同質座標的非常基本的東西,但是我的大腦現在不會點擊!

回答

3

GLSL normalize本身不處理齊次座標。它將座標解釋爲屬於R^4。這通常不是你想要的。但是,如果vtx_data.worldspace_position.w == 0,則標準化應產生相同的結果。

我不知道vec3 pointOnSphere = normalize(vtx_data.worldspace_position);是什麼意思,因爲左邊也應該有vec4

+0

vec3 pointOnSphere = normalize(vtx_data.worldspace_position)是我的部分拼寫錯誤,而用代碼來生成此問題的屏幕截圖:o對不起!並感謝您的答案! – 2012-03-26 09:21:33