2

我是 OpenGL ES 的新手,正在为 iPhone 开发 Objective-C。

我想了解的是光是如何定位在我的视锥体中的。我就是这样做的:

我创建了一个正方形并将其作为我的平截头体中的“地板”。我把灯放在地板中间,就在上面,把灯的方向指向正下方。现在,我希望地板上的光圈位于中间。但事实并非如此,它更靠后(更远)。怎么会?

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

非常感谢任何有助于“阐明”我的问题的帮助!(忍不住……;))

提前致谢!

4

2 回答 2

4

我建议你用更多的顶点做一个更大的网格,最好是 n x n 的正方形。尽量不要有太长的细三角形。这将使您更容易看到灯光的位置,因为灯光是针对每个顶点计算的,而不是针对表面的每个像素计算的。

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

2. 糟糕的镶嵌会伤害照明

OpenGL 的光照计算是按顶点完成的。这意味着由于光源与 3D 对象的表面材质交互而导致的着色计算仅在对象的顶点处计算。通常,OpenGL 只是在顶点颜色之间插入或平滑阴影。OpenGL 的逐顶点光照效果非常好,除非当一个光照效果(如镜面高光或聚光灯)丢失或模糊时,因为该效果没有被对象的顶点充分采样。当对象被粗略地建模以使用最少数量的顶点时,就会出现这种光照效果的欠采样。

新手 OpenGL 程序员通常很想启用 OpenGL 的聚光灯功能,并将聚光灯照射在建模为单个巨大多边形的墙壁上。不幸的是,不会像新手预期的那样出现尖锐的聚光灯图案;您可能根本看不到任何聚光灯的影响。问题是聚光灯的截止意味着指定顶点的墙的极端角落没有来自聚光灯的贡献,并且由于这些是墙上唯一的顶点,所以墙上不会有聚光灯图案。

于 2010-01-24T17:27:14.473 回答
3

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

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

于 2010-01-24T20:01:34.517 回答