Frage

Ich bin neu in OpenGl ES und entwickelt sich in Objective-C für iPhone.

Ich versuche zu verstehen, wie Licht in meinem Frustum positioniert ist. So mache ich es:

Ich erstelle ein Quadrat und setze es als "Boden" in meinem Frustum. Ich lege das Licht direkt darüber in die Mitte des Bodens und zeige die Richtung des Lichts direkt unten. Jetzt erwarte ich, dass der Lichtkreis auf dem Boden in der Mitte ist. Aber es ist nicht, es ist mehr auf dem Rücken (futher weg). Woher?

near = 8.0
far = 28
light position = {0.0, 0.0, -10.0}
light direction = {0.0, -1.0, 0.0}

Floor coordinates = {-0.3153, -0.473, -20.0},
{-0.3153, -0.473, 0.0},
{0.3153, -0.473, -20.0},
{0.3153, -0.473, 0.0},

Sollte dies nicht zusammen den Lichtkreis in der Mitte des Bodens und nicht nach hinten positioniert?

Hier ist mein bedeutender Code:

Einrichten der Ansicht:

 -(void)setupView:(TDRoomView*)view
    {


    const GLfloat zNear = 8, zFar = 28, fieldOfView = 5; 

 GLfloat size; 
 glEnable(GL_DEPTH_TEST);
 glMatrixMode(GL_PROJECTION); 
 size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0); 
 NSLog(@"tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0); %f ", tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0));

 CGRect rect = view.bounds; 
 glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / 
      (rect.size.width / rect.size.height), zNear, zFar);  
 glViewport(-size, size, rect.size.width, rect.size.height);  
 glMatrixMode(GL_MODELVIEW);
    glShadeModel(GL_SMOOTH);
 glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);

    glEnable(GL_LIGHT0);

 static const Color3D light0Ambient[] = {{1.0, 1.0, 1.0, 1.0}};
 glLightfv(GL_LIGHT0, GL_AMBIENT, (const GLfloat *)light0Ambient);

    static const Color3D light0Diffuse[] = {{0.5, 0.5, 0.5, 1.0}};
 glLightfv(GL_LIGHT0, GL_DIFFUSE, (const GLfloat *)light0Diffuse);

    static const Color3D light0Specular[] = {{0.5, 0.5, 0.5, 1.0}};
    glLightfv(GL_LIGHT0, GL_SPECULAR, (const GLfloat *)light0Specular);

    static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};
 glLightfv(GL_LIGHT0, GL_POSITION, (const GLfloat *)light0Position); 

 static const Vertex3D lightVector= {0.0, -1.0, 0.0};

    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, (GLfloat *)&lightVector);

    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 85);

 glLoadIdentity(); 
 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 

    }

Und Zeichnung:

     -(void)drawView:(TDRoomView*)view
    {

        static const Vertex3D vertices[]= {
  {-0.3153, -0.473, -20.0},
  {-0.3153, -0.473, 0.0},
  {0.3153, -0.473, -20.0},
  {0.3153, -0.473, 0.0},
  {-0.1, -0.25, -3.0},
  {0.0, 0.0, -10.0},
  {0.1, -0.25, -3.0}
 };

 static const Color3D colors[] = {
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {0.7, 0.7, 0.7, 1.0},
  {1.0, 0.0, 0.0, 1.0},
  {0.0, 1.0, 0.0, 1.0},
  {0.0, 0.0, 1.0, 1.0}
       };


 static const GLubyte roomFaces[] = {
  0, 1, 2,
  1, 2, 3};


        static const Vector3D normals[] = {
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000},
  {0.000000, 1.000000, 0.000000}
 };

    glLoadIdentity();

    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnableClientState(GL_VERTEX_ARRAY);
 glEnableClientState(GL_COLOR_ARRAY);
 glEnableClientState(GL_NORMAL_ARRAY);

        glVertexPointer(3, GL_FLOAT, 0, vertices);
 glColorPointer(4, GL_FLOAT, 0, colors);
 glNormalPointer(GL_FLOAT, 0, normals);
 glDrawElements(GL_TRIANGLE_STRIP, 8, GL_UNSIGNED_BYTE, roomFaces);

        glDisableClientState(GL_NORMAL_ARRAY);
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_COLOR_ARRAY); }

Außerdem ändere ich die Veränderung der

static const Vertex3D light0Position[] = {{0.0, 0.473, -10.0}};

zu

static const Vertex3D light0Position[] = {{0.0, 0.473, -8.0}}; 

Das Bord wird dunkel, kein Licht scheint darauf. Warum, ich habe das Licht nur zwei Schritte näher bewegt ...? Die gleichen Dinge passieren, wenn ich es zwei Schritte weiter entfernt wie folgt bewege:

static const Vertex3D light0Position[] = {{0.0, 0.473, -12.0}};

Jede Hilfe, um "SOM Light" in meinem Problem zu "abgeben", wird sehr geschätzt! (Konnte nicht anders ...;))

Danke im Voraus!

War es hilfreich?

Lösung

Ich schlage vor, Sie machen ein größeres Gitter mit mehr Eckpunkten, vorzugsweise n von N -Quadraten. Versuchen Sie, nicht zu lange dünne Dreiecke zu haben. Dies erleichtert es einfacher zu erkennen, wo das Licht so zu sein scheint, dass das Licht für jeden Scheitelpunkt und nicht pro Pixel für die Oberfläche berechnet wird.

http://www.opengl.org/resources/features/kilgardtechniques/oglpitfall/

2. Schlechte Tessellation schadet der Beleuchtung

Die Beleuchtungsberechnungen von OpenGL werden pro Vertex durchgeführt. Dies bedeutet, dass die Schattierungsberechnungen aufgrund von Lichtquellen, die mit dem Oberflächenmaterial eines 3D -Objekts interagieren, nur an den Eckpunkten des Objekts berechnet werden. In der Regel interpoliert oder glätte OpenGL zwischen den Scheitelpunktfarben oder glatt. OpenGLs pro-tex-Beleuchtung funktioniert ziemlich gut, außer wenn ein Beleuchtungseffekt wie ein Spiegellicht oder ein Scheinwerferlicht verloren geht oder verschwommen ist, da der Effekt nicht von den Eckpunkten eines Objekts ausreicht. Eine solche Unterabtastung von Beleuchtungseffekten tritt auf, wenn Objekte grob modelliert werden, um eine minimale Anzahl von Eckpunkten zu verwenden.

:

Anfänger OpenGL -Programmierern sind oft versucht, OpenGLs Rampenlight -Funktionalität zu ermöglichen und ein Scheinwerfer an einer Wand zu leuchten, die als einzelnes riesiges Polygon modelliert ist. Leider erscheint kein scharfer Scheinwerfermuster wie der Anfänger beabsichtigt. Sie werden wahrscheinlich überhaupt keinen Rampenlicht sehen. Das Problem ist, dass der Grenzwert des Spotlight bedeutet, dass die extremen Ecken der Wand, in denen die Eckpunkte angegeben werden, keinen Beitrag aus dem Rampenlicht erhalten, und da dies die einzigen Eckpunkte sind, die die Wand hat, gibt es kein Scheinwerfermuster an der Wand.

Andere Tipps

GL_POSITION wird in homogenen Koordinaten angegeben, was bedeutet, dass vier Werte und nicht drei erforderlich sind. Sie müssen angeben w = 1.0 für Ihre Lichtquelle, aber Ihre w Die Komponente kommt stattdessen von allem, was als neben light0Position in Erinnerung.

(Teil des Grundes, dass das GL_POSITION In homogenen Koordinaten ist es, Richtlichter zu definieren, indem Sie eine Position mit festlegen w = 0.0.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top