OpenGL ES 光照问题
我是 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议你做一个更大的网格,有更多的顶点,最好是 n × n 的正方形。尽量不要有太长的细三角形。这将使您更容易看到光线似乎在哪里,因为光线是针对每个顶点计算的,而不是针对表面的每个像素计算的。
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/< /a>
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/
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 tolight0Position
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.)