OpenGL ES Light Question - PullRequest
       17

OpenGL ES Light Question

2 голосов
/ 24 января 2010

Я новичок в OpenGL ES и развиваюсь в Objective-C для iPhone.

Что я пытаюсь понять, так это то, как свет расположен в моем усечённом месте. Вот как я это делаю:

Я создаю квадрат и помещаю его как "пол" в мою усеченную фигуру. Я помещаю свет прямо над серединой пола и указываю направление света прямо вниз. Теперь я ожидаю, что круг света на полу будет посередине. Но это не так, это больше назад (дальше). Как так?

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},

Разве это не должно сделать круг света таким, чтобы он находился посередине пола и не располагался немного назад?

Вот мой важный код:

Настройка вида:

 -(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); 

    }

И рисунок:

     -(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); }

Кроме того, я повторно изменяю

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

до

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

борд темнеет, на нем нет света. Почему я только подвинул свет на два шага ближе ...? То же самое происходит, если я переместлю его на два шага дальше, как это:

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

Любая помощь, чтобы "пролить свет" на мою проблему, очень ценится! (Ничего не мог поделать ...;))

Заранее спасибо!

Ответы [ 2 ]

4 голосов
/ 24 января 2010

Я предлагаю вам сделать большую сетку с большим количеством вершин, предпочтительно n на n квадратов. Старайтесь не иметь слишком длинных тонких треугольников. Это позволит легче увидеть, где находится свет, так как свет рассчитывается для каждой вершины, а не на пиксель для поверхности.

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

2. Плохая тесселяция Hurts Lighting

Расчеты освещения OpenGL выполняются для каждой вершины. Это означает, что вычисления затенения из-за источников света, взаимодействующих с поверхностным материалом трехмерного объекта, рассчитываются только по вершинам объекта. Как правило, OpenGL просто интерполирует или сглаживает тени между цветами вершин. Освещение на каждой вершине в OpenGL работает довольно хорошо, за исключением случаев, когда эффект освещения, такой как зеркальная подсветка или прожектор, теряется или размыт, потому что эффект недостаточно отражается вершинами объекта. Такая недостаточная выборка световых эффектов происходит, когда объекты грубо моделируются для использования минимального количества вершин.

:

Начинающие программисты OpenGL часто испытывают искушение включить функциональность прожектора OpenGL и осветить прожектор на стене, смоделированной как один огромный многоугольник. К сожалению, никакой резкий узор прожектора не появится так, как задумал новичок; вы, вероятно, не увидите никакого эффекта прожектора вообще. Проблема заключается в том, что отсечение прожектора означает, что крайние углы стены, где указаны вершины, не получают вклада от прожектора, и, поскольку это единственные вершины, которые имеет стена, на стене не будет рисунка прожектора.

3 голосов
/ 24 января 2010

GL_POSITION указывается в однородных координатах, что означает, что для него требуется четыре значения, а не три. Вам нужно указать w = 1.0 для вашего источника света, но вместо этого ваш w компонент прибывает из того, что находится рядом с light0Position в памяти.

(Часть причины, по которой GL_POSITION находится в однородных координатах, заключается в том, что вы можете определять направленное освещение, устанавливая положение с помощью w = 0.0.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...