私はOpenGLES2.0のチュートリアルに従い、 developer.apple.comの便利なユタティーポットを使用して、見つけたGLSL照明のチュートリアルと組み合わせています。
たくさんのいじりと実験の後、ティーポットを画面上に適度に正しく描画し、照明チュートリアルの「トゥーンシェーディング」を使用して3つの軸すべてを中心に回転させます。頂点リスト全体を三角ストリップとして描画するだけなので、ジオメトリにいくつかの不具合があります(teapot.hファイルを見ると、新しい三角ストリップを開始するはずの場所に「-1」が埋め込まれていますが、これはテストデータのみで、私の問題には関係ありません)。
私が本当に混乱しているのは、シーンにライトを配置する方法です。私のObjective-Cコードには、{0,1,0}を含むfloat 3ベクトルがあり、それをシェーダーに渡して、光の強度を計算します。
シーン内でもライトが動いているように見えるのはなぜですか?つまり、ライトは、ティーポットがどの方向を向いていても、常に同じ側を指している、見えないスティックによってティーポットに取り付けられているかのように機能します。
これは頂点シェーダーです
attribute vec4 Position;
attribute vec4 SourceColor;
attribute vec3 Normal;
uniform mat4 Projection;
uniform mat4 Modelview;
varying vec3 normal;
void main(void) {
normal = Normal;
gl_Position = Projection * Modelview * Position;
}
「Position」はObj-Cコードによって設定され、オブジェクトの頂点です。「Normal」は頂点配列(VBO)からの法線のリストであり、「Projection」と「Modelview」は次のように計算されます。
(CC3GLMatrixは、上記のリンク先のGLESチュートリアルで説明されているCocos3Dライブラリからのものです)
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:1 andFar:100];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(0, 0, -7)];
[modelView scaleBy:CC3VectorMake(30, 30, 30)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, _currentRotation)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
そして、私はシーンに光を当てます
float lightDir[] = {1,0,1};
glUniform3fv(_lightDirUniform, 1, lightDir);
フラグメントシェーダーは次のようになります
varying lowp vec4 DestinationColor; // 1
varying highp vec3 normal;
uniform highp vec3 LightDir;
void main(void) {
highp float intensity;
highp vec4 color;
intensity = dot(LightDir,normal);
if (intensity > 0.95)
color = vec4(1.0,0.5,0.5,1.0);
else if (intensity > 0.5)
color = vec4(0.6,0.3,0.3,1.0);
else if (intensity > 0.25)
color = vec4(0.4,0.2,0.2,1.0);
else
color = vec4(0.2,0.1,0.1,1.0);
gl_FragColor = color;
}
これを解決しようとしているときに、(GLESには存在しない)'gl_LightSource'と'gl_NormalMatrix'を参照するコードに出くわしましたが、コードからシェーダーに渡さなければならない同等のものに何を入れるべきかわかりません。「アイスペース」「カメラスペース」「ワールドスペース」などへの参照は混乱を招きます。おそらくそれらの間で物事を変換する必要があることはわかっていますが、コード内またはシェーダー内の理由や方法(および場所)がわかりません。 ?)
フレームごとに光源を変更する必要がありますか?それを設定するために私が持っているコードはあまりにも単純に見えます。私は実際にティーポットを動かしているのではありません。代わりに、シーン全体を動かしています。