2011-12-19 7 views
2

私は現在、glslを使ってPhongモデルを使って球上に鏡面照明を作ろうとしています。 sunPositionが動いていないと値(2.0f、3.0F、-1.0f)に設定されているglsl(lwjgl)のフォンスペキュラライティング

#version 120 
uniform vec4 color; 
uniform vec3 sunPosition; 
uniform mat4 normalMatrix; 
uniform mat4 modelViewMatrix; 
uniform float shininess; 
// uniform vec4 lightSpecular; 
// uniform vec4 materialSpecular; 

varying vec3 viewSpaceNormal; 
varying vec3 viewSpacePosition; 

vec4 calculateSpecular(vec3 l, vec3 n, vec3 v, vec4 specularLight, vec4 materialSpecular) { 
    vec3 r = -l+2*(n*l)*n; 
    return specularLight * materialSpecular * pow(max(0,dot(r, v)), shininess); 
} 

void main(){ 
    vec3 normal = normalize(viewSpaceNormal); 
    vec3 viewSpacePosition = (modelViewMatrix * vec4(gl_FragCoord.x, gl_FragCoord.y, gl_FragCoord.z, 1.0)).xyz; 
    vec4 specular = calculateSpecular(sunPosition, normal, viewSpacePosition, vec4(0.3,0.3,0.3,0.3), vec4(0.3,0.3,0.3,0.3)); 
    gl_FragColor = color+specular; 
} 

これは私のフラグメントシェーダがどのように見えるかです。

鏡面の計算が正しければ、画像は何も表示されません。私が最初に取り組ん鏡面反射光の一部を取得したいので、私はこのコードで任意のambient-/emissiv-/deffuse-照明を持っていない理由がある http://i.imgur.com/Na2C6.png

:これは、それがどのように見えるかです

ありがとうございました!

編集:それはまだ右ではない何かをする縫い目たくさんの厳しい助けindead @Darcyレイナー ...

現在のコードは次のようになります。

バーテックスシェーダ:

viewSpacePosition = (modelViewMatrix*gl_Vertex).xyz; 
viewSpaceSunPosition = (modelViewMatrix*vec4(sunPosition,1)).xyz; 
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
viewSpaceNormal = (normalMatrix * vec4(gl_Position.xyz, 0.0)).xyz; 

フラグメントシェーダ:

vec4 calculateSpecular(vec3 l, vec3 n, vec3 v, vec4 specularLight, vec4 materialSpecular) { 
    vec3 r = -l+2*(n*l)*n; 
    return specularLight * materialSpecular * pow(max(0,dot(r, v)), shininess); 
} 

void main(){ 
    vec3 normal = normalize(viewSpaceNormal); 
    vec3 viewSpacePosition = normalize(viewSpacePosition); 
    vec3 viewSpaceSunPosition = normalize(viewSpaceSunPosition); 
    vec4 specular = calculateSpecular(viewSpaceSunPosition, normal, viewSpacePosition,  vec4(0.7,0.7,0.7,1.0), vec4(0.6,0.6,0.6,1.0)); 
    gl_FragColor = color+specular; 
} 

は、そして球は次のようになります。太陽の位置と

-->Picture-link<--

:sunPosition =新しいベクトル(12.0f、15.0f、-1.0f)。

答えて

0

gl_FragCoordは画面座標に格納されているため、使用しないでください(modelViewMatrixで変換しても表示座標に戻らないと思いません)。 、ビューの座標にあなたviewSpacePositionを取得する必要があります

// Change gl_Vertex to whatever attribute you are using. 
viewSpacePosition = (modelViewMatrix * gl_Vertex).xyz; 

これ(すなわち投影が適用される前に。):一番簡単な方法は、あなたのように頂点シェーダにviewSpacePositionを設定します。その後、フラグメントシェーダでviewSpacePositionを正規化して正規化することができます。太陽のベクトルをワールド座標に格納するかどうかは不明ですが、それをビュー空間に変換して正規化することもできます。それを行って何が起こるか見てみましょう。これらは非常に誤りがちです。

0

gl_FragCoordは、フラグメントのウィンドウ相対座標(x、y、z、1/w)値を含む入力変数です。 ...この値は、頂点処理後にプリミティブを補間してフラグメントを生成する固定機能の結果です。

gl_FragCoordの最初の2つの値(x、y)には、フラグメントがレンダリングされるピクセルの中心座標が含まれます。例えば、800×600のフレームバッファ解像度では、左下隅にレンダリングされるフラグメントがピクセル位置(0.5,0.5)に落ちる。最も右上に表示されるフラグメントは、座標(799.5,599.5)を持つことになります。第3の値(z)は、非線形範囲[0,1]にマッピングされたフラグメントの深さである。フラグメントの深さを[znear、zfar]から[0,1]にマップします。

これによると、vec3 viewSpacePosition = (modelViewMatrix * vec4(gl_FragCoord.x, gl_FragCoord.y, gl_FragCoord.z, 1.0)).xyz;はあなたが期待したことをしません。 gl_FragCoordは頂点位置であり、gl_ModelViewProjectionMatrixで変換され、三角形プリミティブ上のフラグメントの偏心座標で補間され、ビューポートサイズでスケーリングされます。モデルビューマトリックス(modelView Matrix)によるさらなる変換は意味をなさない。 3つのベクトルが必要とされる正反射光(場合Phong reflection model)を算出する

  1. この場合normalize(viewSpaceNormal)ある表面の法線ベクトル、。
  2. frgmentsの位置からカメラまでのベクトル。カメラはビュー空間内の位置(0、0、0)を持ちます。 したがって、ビューベクトルはnormalize(vec3(0.0) - viewSpacePosition)です。
  3. frの位置から光源までのベクトルである光のベクトル。したがって、光ベクトルはnormalize(viewSpaceSunPosition - viewSpacePosition)によって計算されます。
    計算はビュー空間(viewSpaceNormalviewSpacePositionがビュースペースにある)で行われるため、ライトベクトルと光​​源(viewSpaceSunPosition)の位置もビュースペース内にある必要があります。これは、均一な変数viewSpaceSunPositionに設定する前に、光源の位置をビュー行列で変換する必要があることを意味します。

ビューマトリックスとモデルビューマトリックスは同じであってはならないことに注意してください。モデルビュー行列は、モデル行列とビュー行列から構成されます。通常、モデル行列は、単一のオブジェクト(例えば、シーン内のオブジェクト上のアニメーション)に対する追加の変換を含む。

これとは別に、反射ベクトルの計算に誤りがあると次のように、計算式は次のとおり

incidentVector - 2.0 * dot(incidentVector, normalVector) * normalVector; 

注意、GLSLで仕事をするであろう機能reflectがあります。

頂点とフラグメントシェーダは次のように何とかなります。

頂点シェーダ

varying vec3 viewSpacePosition; 
varying vec3 viewSpaceNormal; 

void main() 
{ 
    viewSpacePosition = (modelViewMatrix*gl_Vertex).xyz; 
    viewSpaceNormal = (normalMatrix * vec4(gl_Position.xyz, 0.0)).xyz; 
    gl_Position  = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

フラグメントシェーダ

varying vec3 viewSpacePosition; 
varying vec3 viewSpaceNormal; 

uniform vec3 viewSpaceSunPosition; 
uniform float shininess; 

vec4 calculateSpecular(vec3 L, vec3 N, vec3 V, vec4 specularLight, vec4 materialSpecular) 
{ 
    vec3 R = -L - 2.0 * dot(N, -L) * N; 
    // vec3 R = reflect(-L, N); 
    return specularLight * materialSpecular * pow(max(0,dot(R, V)), shininess); 
} 

void main() 
{ 
    vec3 N = normalize(viewSpaceNormal); 
    vec3 V = normalize(-viewSpacePosition); 
    vec3 L = normalize(viewSpaceSunPosition - viewSpacePosition); 
    vec4 specular = calculateSpecular(L, N, V, vec4(0.7,0.7,0.7,1.0), vec4(0.6,0.6,0.6,1.0)); 
    gl_FragColor = color+specular; 
} 

も、この質問に対する回答を参照してください。