OpenGL ES Light问题

时间:2010-01-24 16:27:46

标签: iphone objective-c 3d opengl-es opengl-es-lighting

我是OpenGL ES的新手,正在使用Objective-C for 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}}; 
bord变暗,没有光照在它上面。为什么,我只把灯光移近两步......?如果我将它移动两步,就会发生同样的事情:

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

非常感谢任何有助于“解决问题”的帮助! (无法帮助它......;))

提前致谢!

2 个答案:

答案 0 :(得分:4)

我建议你做一个更大的网格,有更多的顶点,最好是n个n个方格。尽量不要有太长的薄三角形。这样可以更容易地看到光线在每个顶点计算光线时的位置,而不是表面的每个像素。

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

  

2。差的细分伤害照明

     

OpenGL的光照计算是按顶点完成的。这意味着由于光源与3D对象的表面材质相互作用而产生的阴影计算仅在对象的顶点处计算。通常,OpenGL只是在顶点颜色之间插值或平滑阴影。 OpenGL的每顶点光照效果非常好,除非镜面效果(如镜面反射高光或聚光灯)丢失或模糊,因为对象的顶点未充分采样效果。当对象被粗略建模以使用最少数量的顶点时,会发生这种光照效果的欠采样。

     

     

新手OpenGL程序员经常试图启用OpenGL的聚光灯功能,并在一个模拟为单个巨大多边形的墙上成为焦点。不幸的是,新手不会出现尖锐的聚光灯模式;你可能根本看不到任何聚光灯影响。问题是聚光灯的截止意味着指定顶点的墙的极端角落没有得到聚光灯的贡献,因为那些是墙壁唯一的顶点,墙上就没有聚光灯图案。

答案 1 :(得分:3)

GL_POSITION在齐次坐标中指定,这意味着它需要四个值,而不是三个。您需要为光源指定 w = 1.0,但 w 组件来自内存中light0Position旁边的任何内容。

GL_POSITION在齐次坐标系中的部分原因是允许您通过设置 w = 0.0的位置来定义方向灯。)