OpenGL ES 光照问题

发布于 2024-08-18 23:50:02 字数 3867 浏览 2 评论 0原文

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

非常感谢任何帮助“阐明”我的问题! (没办法……;))

提前致谢!

I am new to OpenGL ES and are developing in Objective-C for iPhone.

What I am trying to understand is how light is positioned in my frustum. This is how I do it:

I create a square and put it as "floor" in my frustum. I am putting the light, right above, in the middle of the floor and point the direction of the light right down. Now, I expect the light circle on the floor to be in the middle. But it's not, it'r more to the back (futher away). How come?

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

Shouldn't this together make the circle of light to be in the middle of the floor and not positioned a bit backwards?

Here's my significant code:

Setting up the view:

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

    }

And drawing:

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

Also, I recon changing the

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

to

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

the bord turns dark, no light shines on it. Why, I only moved the light two steps closer...? The same things happen if I move it two steps further away like this:

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

Any help in order to "shed som light" on my problem is greatly appreciated! (Couldn't help it... ;) )

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一直在等你来 2024-08-25 23:50:02

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

http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/< /a>

2。不良的镶嵌会损害照明

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

新手 OpenGL 程序员经常会想要启用 OpenGL 的聚光灯功能,并将聚光灯照射在建模为单个巨大多边形的墙上。不幸的是,新手不会看到清晰的聚光灯图案。您可能根本看不到任何聚光灯的影响。问题在于,聚光灯的截止意味着指定顶点的墙壁的极端角落不会受到聚光灯的影响,并且由于这些是墙壁仅有的顶点,因此墙壁上不会有聚光灯图案。

I suggest you do a larger grid with more vertices, preferably n by n squares. Try not to have too long thin triangles. This will make it easier to see where the light seem to be as the light is calculated for each vertex and not per pixel for the surface.

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

2. Poor Tessellation Hurts Lighting

OpenGL's lighting calculations are done per-vertex. This means that the shading calculations due to light sources interacting with the surface material of a 3D object are only calculated at the object's vertices. Typically, OpenGL just interpolates or smooth shades between vertex colors. OpenGL's per-vertex lighting works pretty well except when a lighting effect such as a specular highlight or a spotlight is lost or blurred because the effect is not sufficiently sampled by an object's vertices. Such under-sampling of lighting effects occurs when objects are coarsely modeled to use a minimal number of vertices.

:

Novice OpenGL programmers are often tempted to enable OpenGL's spotlight functionality and shine a spotlight on a wall modeled as a single huge polygon. Unfortunately, no sharp spotlight pattern will appear as the novice intended; you probably will not see any spotlight affect at all. The problem is that the spotlight's cutoff means that the extreme corners of the wall where the vertices are specified get no contribution from the spotlight and since those are the only vertices the wall has, there will be no spotlight pattern on the wall.

失与倦" 2024-08-25 23:50:02

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

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

GL_POSITION is specified in homogeneous coordinates, which means that it requires four values, not three. You need to specify w = 1.0 for your light source, but your w component is instead coming from whatever happens to be next to light0Position in memory.

(Part of the reason that GL_POSITION is in homogeneous coordinates is to allow you to define directional lights by setting a position with w = 0.0.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文