代码之家  ›  专栏  ›  技术社区  ›  Nicsoft

OpenGL ES Light问题

  •  2
  • Nicsoft  · 技术社区  · 16 年前

    我是OpenGLES的新手,正在为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}};
    

    我非常感谢您为我的问题提供任何帮助!(忍不住…;)

    事先谢谢!

    2 回复  |  直到 16 年前
        1
  •  4
  •   epatel    16 年前

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

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

    2。不好的镶嵌会伤害照明

    OpenGL的照明计算是按顶点进行的。这意味着,由于光源与三维对象的表面材料相互作用而产生的着色计算仅在对象的顶点处进行计算。通常,OpenGL只是在顶点颜色之间插入或平滑着色。OpenGL的逐顶点照明效果非常好,除非由于对象顶点没有对效果进行足够的采样而使镜面高光或聚光灯等照明效果丢失或模糊。当对象粗略地建模为使用最少数量的顶点时,就会出现这种欠采样的照明效果。

    :

    初学的OpenGL程序员经常会尝试启用OpenGL的聚光灯功能,并将聚光灯照射到一个建模为单个巨大多边形的墙上。不幸的是,没有锐利的聚光灯模式会像初学者预期的那样出现;您可能根本看不到任何聚光灯影响。问题是聚光灯的截止点意味着指定顶点的墙的极端角不会从聚光灯中得到贡献,并且因为这些是墙唯一具有的顶点,所以墙上不会有聚光灯图案。

        2
  •  3
  •   Pivot    16 年前

    GL_POSITION 在齐次坐标中指定,这意味着它需要四个值,而不是三个。您需要指定 W =1.0表示光源,但 W 相反,组件来自 light0Position 在记忆中。

    (部分原因是 格氏位置 是在均匀坐标系下,允许您通过设置一个位置来定义方向灯 W = 0)。