2012-03-23 14 views
6

私は、単純なオブジェクトの色収差をシミュレートするGLSLシェーダーを作成しています。私はOpenGL 2.0と互換性があるので、組み込みのOpenGLマトリックススタックを使用しています。これは、単純な頂点シェーダである:1が想像として色収差補正による反射/屈折

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は、描画オブジェクトの環境からのライブレンダリングされるキューブマップです。それは今で指すようにカメラは、その標的の周りに180度回転されたとき、しかし、

correct shader behavior

:期待されるような通常の状況下で

、シェーダは、この結果を得た(と思う)に振る舞います反対側からの目的は、屈折/反射された画像(これはもちろん、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

これはそれでした!明白な理由から 'gl_NormalMatrix'を' mat3(modelMatrix) 'に置き換えなければなりませんでした。私が「ポジション」変数のスペースを考慮する必要があることは私には決して打たれませんでした。何とか正しいと思われました。ありがとう! – dflemstr

関連する問題