1

現在、OpenGL ES 2.0 で単純なポイント ライトを含むシェーダーを作成しようとしていますが、うまくいきません。

独自の小さな SceneGraph を作成し、各オブジェクト (現在はボックスのみ) に独自の移動/回転/スケールを設定でき、レンダリングは正常に機能します。各ボックスは独自の modelView と法線行列を割り当て、それらはすべて同じ射影行列を使用します。

オブジェクトごとに、マトリックスとライトの位置をユニフォームとしてシェーダーに渡します。

オブジェクトが回転しない場合、ライトは正常に機能しますが、オブジェクトが回転するとすぐに、ライトは同じ位置にとどまるのではなく、オブジェクトとともに回転するように見えます。

ここにいくつかのコードがあります。最初に行列を作成します。

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);

各ノードは、平行移動/回転/スケールを含む独自の変換行列を計算し、それを modelViewMatrix で乗算します。

modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, transformation);

このマトリックスはシェーダーに渡され、オブジェクトがレンダリングされた後、古いマトリックスが復元されます。

正規行列は次のように計算されます。

GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);

頂点シェーダー:

attribute vec4 Position;
attribute vec2 TexCoordIn;
attribute vec3 Normal;

uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat3 normalMatrix;

uniform vec3 lightPosition;

varying vec2 TexCoordOut;
varying vec3 n, PointToLight;

void main(void) {
    gl_Position =  modelViewProjectionMatrix * Position;
    n = normalMatrix * Normal;

    PointToLight = ((modelViewMatrix * vec4(lightPosition,1.0)) - (modelViewMatrix * Position)).xyz;

    // Pass texCoord
    TexCoordOut = TexCoordIn;
}

フラグメントシェーダー:

varying lowp vec2 TexCoordOut;
varying highp vec3 n, PointToLight;

uniform sampler2D Texture;

void main(void) {
    gl_FragColor = texture2D(Texture, TexCoordOut);

    highp vec3 nn = normalize(n);
    highp vec3 L = normalize(PointToLight);

    lowp float NdotL = clamp(dot(n, L), -0.8, 1.0);
    gl_FragColor *= (NdotL+1.)/2.;
}

PointToLight の計算が間違っていると思いますが、何が問題なのかわかりません。

4

1 に答える 1

3

私はついに何が悪かったのかを理解しました。

lightPositionにmodelViewMatrixを掛ける代わりに、viewMatrixを掛ける必要があります。これには、カメラの変換のみが含まれ、ボックスの変換は含まれていません。

PointToLight = ((viewMatrix * vec4(lightPosition,1.0)) - (viewMatrix * modelMatrix * Position)).xyz;

今では正常に動作します。

于 2012-10-31T22:21:35.587 に答える