2011-12-15 21 views
3

を働いていない座標私はNVIDIAの素敵なGPU Gemsのウェブサイトから「神線」シェーダ実装:とにかくhttp://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.htmlGLSLコンピューティング画面が世界から座標が正しく

を、それが1つの欠陥を除いて、ほぼ完璧です。何とか光の位置が残りのシーンと一緒に動かされていません。

画像の例:

これは正確に見えます。

enter image description here

これはしていません。光は白い球から外側に放射されるはずですが、最初の画像から位置が変わっていないように見えます。

enter image description here

私は頂点シェーダに変換をやってる:

uniform vec4 light_coords; 
varying vec2 light_pos; 

void main() 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    light_pos = vec2(gl_ModelViewProjectionMatrix * light_coords) * 0.5 + 0.5; 
} 

は、これは正しいですか?

ワールド座標のライトの位置は(0、0、-2)です。エラーはコードのどこか他の場所にある可能性がありますが、ダイビングする前に頂点シェーダの計算が正しいことを確認したかった残りの部分に

編集:私はニコール・ボラスが以下に示唆したことに基づいていくつかの変更を加えましたが、これは改善されましたが、それでも正しくはありません。

カメラが元の位置になってもまだうまく見えますが、シーンを回転させると、計算された光の位置が左側にずれているように見えます。ここで

enter image description here

は、私が使用しているGLSLコードです:light_coords vec4

均一。 uniform mat4 light_modelview; 変化するvec2 light_pos;

void main() 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    light_pos = vec2(gl_ProjectionMatrix * light_modelview * light_coords) * 0.5 + 0.5; 
} 

light_modelviewここで得られる:

glPushMatrix() 
glTranslatef(self.position[0], self.position[1], self.position[2]) 
glScalef(2, 2, 2)  
self.modelview = glGetFloatv(GL_MODELVIEW_MATRIX) 
glCallList(self.sphere) 
glLightfv(self.light_id, GL_POSITION, self.position) 
glPopMatrix() 

position[0, 0, -2]です。それは、画面上だし、それよりも大きいか小さい場合、それは私が(0,0)にどこかにあるとlight_posをたいと思い、理想的にはlight_coords

としてシェーダに渡されています(1、1)それは、画面オフの場合。

私は間違って何をしているのか?私はまだOpenGLを少し新しくしているので、何が何をしているのか少し不明です。

答えて

4

light_coordsは、ワールド空間内にある場合gl_Vertexワールド空間内であれば、その後、gl_ModelViewProjectionMatrixを掛けることにのみ意味があります。どういうわけか、私はそれが疑わしいです。

一般に、光の方向、または世界の空間にあると思われるものを渡すことはありません。light_coordsビュー空間に渡します。ワールド空間からCPU上の空間を見るために変換し、ビュー空間の座標をシェーダに置きます。

+0

Hmm。その変換を効率的に行う方法はありますか?私はOpenGLのPythonバインディングを使用していますので、シェイダーやOpenGL呼び出しでできるだけ多くのものを保ちたいと思います。 –

+1

@DaneLarsen:1フレームにつき1回です。私はあなたのCPUが、たとえPythonであっても、フレームごとに1回の行列乗算を行うことができると確信しています。私はシェイダーでどのように行うのか教えてもらえますが、CPU上に置くのではなく、それが何に影響を与えないかを見るのではなく、むしろそうするでしょう。また、GPU上で決して良いことではないワールド空間行列を明示的に使用する必要があります。 –

+0

十分に良い。私は明日それを試してみましょう。助けてくれてありがとう! –

関連する問題