2012-03-23 67 views
6

我正在寫一個模擬簡單物體色差的GLSL着色器。我保持OpenGL 2.0兼容,所以我使用內置的OpenGL矩陣堆棧。這是一個簡單的頂點着色器:色差反射/折射 - 眼睛校正

uniform vec3 cameraPos; 

varying vec3 incident; 
varying vec3 normal; 

void main(void) { 
    vec4 position = gl_ModelViewMatrix * gl_Vertex; 
    incident = position.xyz/position.w - cameraPos; 
    normal = gl_NormalMatrix * gl_Normal; 

    gl_Position = ftransform(); 
} 

cameraPos制服相機在模型空間中的位置,作爲一個想象的。這裏是片段着色器:

const float etaR = 1.14; 
const float etaG = 1.12; 
const float etaB = 1.10; 
const float fresnelPower = 2.0; 
const float F = ((1.0 - etaG) * (1.0 - etaG))/((1.0 + etaG) * (1.0 + etaG)); 

uniform samplerCube environment; 

varying vec3 incident; 
varying vec3 normal; 

void main(void) { 
    vec3 i = normalize(incident); 
    vec3 n = normalize(normal); 

    float ratio = F + (1.0 - F) * pow(1.0 - dot(-i, n), fresnelPower); 

    vec3 refractR = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaR), 1.0)); 
    vec3 refractG = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaG), 1.0)); 
    vec3 refractB = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaB), 1.0)); 

    vec3 reflectDir = vec3(gl_TextureMatrix[0] * vec4(reflect(i, n), 1.0)); 

    vec4 refractColor; 
    refractColor.ra = textureCube(environment, refractR).ra; 
    refractColor.g = textureCube(environment, refractG).g; 
    refractColor.b = textureCube(environment, refractB).b; 

    vec4 reflectColor; 
    reflectColor = textureCube(environment, reflectDir); 

    vec3 combinedColor = mix(refractColor, reflectColor, ratio); 

    gl_FragColor = vec4(combinedColor, 1.0); 
} 

environment是從繪製對象的生活環境渲染的立方體貼圖。

在正常情況下,着色器如期望的那樣(我認爲),產生這樣的結果:

correct shader behavior

然而,當轉動相機圍繞其目標180度,從而使得它指向的從另一側的對象時,折射/反射的圖像被扭曲,像這樣(這逐漸發生爲0和180度之間的角度,當然):

incorrect shader behavior

當相機下降/升起時出現類似的人爲現象;當相機直接位於目標物體上時(指向負Z,在這種情況下),它似乎只能正確表現100%。

我很難弄清楚在着色器中哪個變形是造成這個變形的圖像的原因,但它應該與處理cameraPos有關。是什麼導致圖像以這種方式扭曲?

回答

2

這看起來犯罪嫌疑人對我說:

vec4 position = gl_ModelViewMatrix * gl_Vertex; 
incident = position.xyz/position.w - cameraPos; 

是您cameraPos在世界空間中定義的?你從一個所謂的世界空間cameraPos矢量中減去一個視圖空間矢量(position)。您需要在世界空間或視圖空間中進行計算,但不能混合使用。

要在世界空間中正確地做到這一點,您必須分別上傳模型矩陣以獲取世界空間事件向量。

+0

這就是它!我必須用'mat3(modelMatrix)'替換'gl_NormalMatrix',原因很明顯。它從來沒有讓我感到我應該考慮位置變量的空間,它似乎在某種程度上是微不足道的。謝謝! – dflemstr 2012-03-23 23:37:37