1

私は現在、gsl と Phong モデルを使用して、球体に鏡面照明を作成しようとしています。

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

#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;
}

sunPosition は移動しておらず、値 (2.0f、3.0f、-1.0f) に設定されています。

問題は、鏡面反射計算が正しかった場合に想定されるように、画像が何も見えないことです。

これはどのように見えるかです: http://i.imgur.com/Na2C6.png

このコードにアンビエント/エミッシブ/デフューズ ライティングがない理由は、スペキュラー ライトの部分を最初に動作させたいからです。

助けてくれてありがとう!

編集:@Darcy Raynerそのindeadは、まだ正しくないものであると思われます...

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

頂点シェーダー:

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;
}

そして、球は次のようになります。

-->画像リンク<--

太陽の位置: sunPosition = new Vector(12.0f, 15.0f, -1.0f);

4

1 に答える 1

0

gl_FragCoord は画面座標に格納されるため、使用しないでください (modelViewMatrix で変換してもビュー座標に戻るとは思いません)。最も簡単なことは、頂点シェーダーで viewSpacePosition を次のように設定することです。

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

これにより、ビュー座標で viewSpacePosition が取得されます (つまり、投影が適用される前)。その後、フラグメント シェーダーで viewSpacePosition を正規化できます。太陽ベクトルをワールド座標に格納しているかどうかはわかりませんが、おそらくそれをビュー空間に変換してから正規化することもできます。試してみて、何が起こるか見てみましょう。これらのことは、非常にエラーが発生しやすい傾向があります。

于 2011-12-19T01:11:37.593 に答える