Android の OpenGL ライティングで直面している興味深い問題を調べています。私は、3D オブジェクトを追加および操作できる 3D Viewer に取り組んでいます。さまざまな属性を持つライトを設定することもできます。Viewer で直面していた問題は、ライト (ポイント ライト) からの 3D オブジェクトのハイライトが奇妙な動作をすることでした。光源がカメラとまったく同じポイントにある場合、ハイライトは予想とは反対の方向に移動します。(したがって、オブジェクトを左に移動すると、ハイライトはオブジェクトの右端ではなく左端にも移動します。これは私が期待していたものです。)
そこで、問題をさらに絞り込むために、正方形のみをレンダリングする小さなサンプル アプリケーションを作成し、その正方形をカメラ位置 (原点) を中心に回転させます。これは、ライトが配置される場所でもあります。これにより、すべての正方形がカメラに直接面するようになり、完全に強調表示されます。結果は次のようになりました。
これらのアーティファクトは、投影によって境界線に歪みが生じたために発生するのでしょうか?
最初の画像では、球体とカメラの間の距離は約 20 単位で、球体のサイズは約 2 です。ライトをオブジェクトに近づけると、期待どおりにハイライトがよりよく見えます。 . 2 番目のイメージでは、正方形が配置されている半径は 25 単位です。Android 3.1でOpenGL ES 1.1を使用しています(ES 2.0のシェーダーで動作させるのに苦労していたため)
ここに私が使用しているコードの一部があります:
public void onDrawFrame(GL10 gl) {
// Setting the camera
GLU.gluLookAt(gl, 0, 0, 0, 0f, 0f, -1f, 0f, 1.0f, 0.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
for (int i = 0; i < 72; i++) {
gl.glPushMatrix();
gl.glRotatef(5f * i, 0, 1, 0);
gl.glTranslatef(0, 0, -25);
draw(gl);
gl.glPopMatrix();
}
}
public void draw(GL10 gl) {
setMaterial(gl);
gl.glEnable(GL10.GL_NORMALIZE);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glFrontFace(GL10.GL_CCW);
// Enable the vertex and normal state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glNormalPointer(GL10.GL_FLOAT, 0, mNormalBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, mIndexBuffer.capacity(), GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
// Setting the light
private void drawLights(GL10 gl) {
// Point Light
float[] position = { 0, 0, 0, 1 };
float[] diffuse = { .6f, .6f, .6f, 1f };
float[] specular = { 1, 1, 1, 1 };
float[] ambient = { .2f, .2f, .2f, 1 };
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glLightfv(GL10.GL_LIGHT0, GL_POSITION, position, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL_DIFFUSE, diffuse, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL_AMBIENT, ambient, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL_SPECULAR, specular, 0);
}
private void setMaterial(GL10 gl) {
float shininess = 30;
float[] ambient = { 0, 0, .3f, 1 };
float[] diffuse = { 0, 0, .7f, 1 };
float[] specular = { 1, 1, 1, 1 };
gl.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse, 0);
gl.glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient, 0);
gl.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular, 0);
gl.glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
}
アクティビティが開始されたとき(onSurfaceCreatedで)、最初にライトを設定し、正方形を描くたびにマテリアルを設定しています。