2017-05-06 12 views
0

私は光源と3Dボックスを追加した3Dシーンを作成しました。これは光源によって照らされるべきです。 AmbientとDiffuseの両方の色が正しく動作しているように見えますが、スペキュラの色が正しく計算されていないようです。光源を使ってカメラを側面の前に移動すると、スペキュラの「ドット」は見えません。しかし、カメラをキューブの上部に向かって動かし、原点(0、0、0)を見ると、キューブの照明された側に微妙な鏡面の「ドット」が見えます。鏡面照明が動作しない

私の質問は次のとおりです。何が間違っているのですか?

以下のコードのすべてはmodelMatrixで発生し、_navメンバーはカメラの動きを管理します。

光源とキューブ側に向け
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
gluLookAt(_nav->getCamPosx(), _nav->getCamPosy(), _nav->getCamPosz(), 
      _nav->getCamViewx(), _nav->getCamViewy(), _nav->getCamViewz(), 
      _nav->getCamUpx(), _nav->getCamUpy(), _nav->getCamUpz()); 

glEnable(GL_LIGHTING); 
glEnable(GL_LIGHT0); 

GLfloat qaAmbientLight[] = {0.2f, 0.2f, 0.2f, 1.0f}; 
GLfloat qaDiffuseLight[] = {0.8f, 0.8f, 0.8f, 1.0f}; 
GLfloat qaSpecularLight[] = {1.0f, 0.0f, 0.0f, 1.0f}; //red for testing 
glLightfv(GL_LIGHT0, GL_AMBIENT, qaAmbientLight); 
glLightfv(GL_LIGHT0, GL_DIFFUSE, qaDiffuseLight); 
glLightfv(GL_LIGHT0, GL_SPECULAR, qaSpecularLight); 

// Set the light position 
GLfloat qaLightPosition[] = {0.5f, 0.5f, 1.2f, 1.0f}; 
glLightfv(GL_LIGHT0, GL_POSITION, qaLightPosition); 

GLfloat cyan[] = {0.f, .8f, .8f, 1.f}; 
GLfloat white[] = {0.8f, 0.8f, 0.8f, 1.0f}; 
//GLfloat dark[] = {0.0, 0.0, 0.0, 1.0}; 
glMaterialfv(GL_FRONT, GL_AMBIENT, cyan); 
glMaterialfv(GL_FRONT, GL_DIFFUSE, cyan); 
glMaterialfv(GL_FRONT, GL_SPECULAR, white); 
GLfloat shininess[] = {80}; 
glMaterialfv(GL_FRONT, GL_SHININESS, shininess); 

glBegin(GL_QUADS); 

    glNormal3f(0.0f, -1.0f, 0.0f); 
    glVertex3f(0.1f, 0.0f, 0.1f); 
    glVertex3f(1.0f, 0.0f, 0.1f); 
    glVertex3f(1.0f, 0.0f, 1.0f); 
    glVertex3f(0.1f, 0.0f, 1.0f); 

    glNormal3f(0.0f, 0.0f, -1.0f); 
    glVertex3f(0.1f, 0.0f, 0.1f); 
    glVertex3f(1.0f, 0.0f, 0.1f); 
    glVertex3f(1.0f, 1.0f, 0.1f); 
    glVertex3f(0.1f, 1.0f, 0.1f); 

    glNormal3f(-1.0f, 0.0f, 0.0f); 
    glVertex3f(0.1f, 0.0f, 0.1f); 
    glVertex3f(0.1f, 0.0f, 1.0f); 
    glVertex3f(0.1f, 1.0f, 1.0f); 
    glVertex3f(0.1f, 1.0f, 0.1f); 

    //face that gets illuminated 
    glNormal3f(0.0f, 0.0f, 1.0f); 
    glVertex3f(1.0f, 0.0f, 1.0f); 
    glVertex3f(0.1f, 0.0f, 1.0f); 
    glVertex3f(0.1f, 1.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 

    glNormal3f(1.0f, 0.0f, 0.0f); 
    glVertex3f(1.0f, 0.0f, 0.1f); 
    glVertex3f(1.0f, 0.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 
    glVertex3f(1.0f, 1.0f, 0.1f); 

    glNormal3f(0.0f, 1.0f, 0.0f); 
    glVertex3f(0.1f, 1.0f, 0.1f); 
    glVertex3f(1.0f, 1.0f, 0.1f); 
    glVertex3f(1.0f, 1.0f, 1.0f); 
    glVertex3f(0.1f, 1.0f, 1.0f); 

glEnd(); 

は、ここでは、コードです

:キューブの

Facing cube side with light source

トップビュー、かすかな赤は、鏡面 'ドット' です

Top view of the cube, the faint red is the specular 'dot'

答えて

0

固定関数では、OpenGL照明は頂点でのみ計算され、その結果の色は面全体に補間されます。鏡面反射が現れるには、実際に十分な空間サンプリングができるように、十分に多くの頂点が必要です。

明らかに、メッシュを細分することは、照明のために十分なサンプリングポイントを提供するだけでは効率的ではありません。だから、何年にもわたって、ピクセルごとの照明技術が開発されました。シェーダ(https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/lighting.php)を使用して実装するのはかなり簡単です。

関連する問題