OpenGL方向型光源问题

Cricketol 2008-08-04 04:22:13
我这样设置方向型光源:
private float light_position[] = {0.5f ,0.0f ,5.0f ,0.0f};
private float light_ambient[] = {0.6f ,0.6f ,0.6f ,1.0f};
private float light_deffuse[] = {0.5f ,0.5f ,1.0f ,1.0f};
private float light_specular[] = {1.0f ,1.0f ,1.0f ,1.0f};

gl.glEnable(GL.GL_DEPTH);
gl.glEnable(GL.GL_LIGHTING);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_deffuse, 0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light_specular, 0);
gl.glEnable(GL.GL_LIGHT0);

当我把物体从原点不停地向一个方向移动的时候,影子就越来越少,最后整个物体都变成一片同样的颜色,根本没有影子
在方向型光源照射下,在任何地方影子都是一样的才对啊,我这个怎么还会变化的?
...全文
429 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
needallcodes 2008-08-27
  • 打赏
  • 举报
回复
gluLookAt要类似这样用:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspactive(...);//为避免模型被切掉,近视点设成0.1,远视点100或者更高

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt();

//下面是每帧的渲染
glPushMatrix();
drawTheWorld();
glPopMatrix();
glutSwapBuffers();
//帧结束

上面的过程能保证了, 问题可能就是lookat.
每次设定gluLookAt,必须保证在单位化的model view矩阵下进行
另外,它的三个参数要搞明白:
eye,center是两个坐标, 向量center-eye指示了脸朝向的方向
up是头的正上方,对于所有视角,你要想想成你是个没有身体的头......囧, 而且眼珠子是死的...虽然很恐怖,但这样比较不容易出错....
一般对于第一人称free cam:
up恒等(0,1,0)
平移的时,eye和center坐标要同时更新,以保证脸的朝向不变(与原方向平行),
身体左右旋转的时候, 要绕up更新center坐标, freecam视角比较简单,绕Y轴转就可以了
眼睛上下旋转的时候, 要绕up X (center-eye)更新center坐标,且旋转角度不能超多-90~+90范围, 这个要相对麻烦些...


下面的过程是和gluLookAt等效的, 且使用于所有视角:
f = center - eye;
r = f x up;
t = r x f;
将三个向量单位化后,组成矩阵M:
M[] = {r.x, r.y, r.z, 0,
t.x, t.y, t.z, 0,
-f.x, -f.y, -f.z, 0,
-eye.x, -eye.y, -eye.z, 1};
用一句glMultiMatrix(M);替换掉gluLookAt
其实就是让头的原坐标系X Y Z的方向变成r, t, -f, 原点有O移动到eye
needallcodes 2008-08-25
  • 打赏
  • 举报
回复
楼上的请赐教!
Cricketol 2008-08-25
  • 打赏
  • 举报
回复
我的眼睛没有移动,只是转动眼睛看的方向,反射光就变了
这种现象怎么回事?我想改掉它
yale13 2008-08-25
  • 打赏
  • 举报
回复
哈哈,那个每个顶点都调用一次glnormal只是理论上的吧,一个3ds物体,上百个面,上千个点,这样搞,会死人的~
needallcodes 2008-08-25
  • 打赏
  • 举报
回复
你是不是按照书上的例子做的, 我抄了个C++的你试试
因为是靠glu画的曲面,所以只能是用自动NORMALIZE来设置normal的,
这样做的话显卡的负担会加重,而且光照的效果也不好, 不过在java上就不清楚了:
[code=C/C++]
#include <stdlib.h>
#include <ctype.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

struct {
float ex, ey, ez;
float cx, cy, cz;
float ux, uy, uz;
} camera = { .0f, .0f, 2.0f, .0f, .0f, 1.0f, .0f, .1f, .0f };

float ctrl[4][4][3] = {
-3.0f,-3.0f,-3.0f, -3.0f,-1.0f,-3.0f, -3.0f, 1.0f,-3.0f, -3.0f, 3.0f,-3.0f,
-1.0f,-3.0f,-3.0f, -1.0f,-1.0f, 3.0f, -1.0f, 1.0f, 3.0f, -1.0f, 3.0f,-3.0f,
1.0f,-3.0f,-3.0f, 1.0f,-1.0f, 3.0f, 1.0f, 1.0f, 3.0f, 1.0f, 3.0f,-3.0f,
3.0f,-3.0f,-3.0f, 3.0f,-1.0f,-3.0f, 3.0f, 1.0f,-3.0f, 3.0f, 3.0f,-3.0f
};
GLUnurbsObj *nurb;

void init(void) {
glDepthFunc( GL_LEQUAL );
glEnable( GL_DEPTH_TEST );
glShadeModel( GL_SMOOTH );
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glEnable(GL_COLOR_MATERIAL);

GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
GLfloat lightColor0[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat lightPos0[] = {20.0f, 20.0f, 0.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

//cpu or gpu 帮你生成normal
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);

glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

nurb = gluNewNurbsRenderer();
gluNurbsProperty(nurb, GLU_SAMPLING_TOLERANCE, 25.0);
gluNurbsProperty(nurb, GLU_DISPLAY_MODE, GLU_FILL);
gluNurbsCallback(nurb, GLU_ERROR, NULL);
}

void lookat(void) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
camera.ex, camera.ey, camera.ez,
camera.cx, camera.cy, camera.cz,
camera.ux, camera.uy, camera.uz
);
}

void reshape( GLsizei w,GLsizei h )
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glViewport(0, 0, w, -h);
gluPerspective( 65, 1.33, 8, 100);
lookat();//设置camera
}


void display(void) {
static GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
static float angle = .0f;

//angle=( (angle >= 360) ? 0 : (angle+=0.2f) );

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();
glTranslatef(0.0f, 0.0f, -12.0f);
//glRotatef(angle,1.0, 1.0, 1.0);

glColor4f(0.9f, 0.4f, 0.1f, 1.0f);

//
gluBeginSurface(nurb);
gluNurbsSurface(nurb,
8, knots, 8, knots,
4 * 3, 3, &ctrl[0][0][0],
4, 4, GL_MAP2_VERTEX_3);
gluEndSurface(nurb);
//
//一般的做法是下面这样:
//glBegin(GL_TRIANGLS);
//glNormal(...);
//glVertex?f(...);
//glEnd()
//glutSolidTeapot(2.0f);
glPopMatrix();

glutSwapBuffers();
}

void idle() {
glutPostRedisplay();
}

void keyboard( unsigned char Key, int Kx, int Ky ) {
static float step = .2f;
Key = tolower(Key);
switch (Key) {
case 27: exit(0);
//全部是与轴平行移动.....
case 'a': camera.ex -= step; camera.cx -= step; lookat(); break;
case 'd': camera.ex += step; camera.cx += step; lookat(); break;

case '2': camera.ey += step; camera.cy += step; lookat(); break;
case 'x': camera.ey -= step; camera.cy -= step; lookat(); break;

case 'w': camera.ez -= step; camera.cz -= step; lookat(); break;
case 's': camera.ez += step; camera.cz += step; lookat(); break;
}
}

int main(int, char**) {
glutInitDisplayMode( GLUT_DOUBLE|GLUT_RGBA );
glutInitWindowSize( 640,480);
glutCreateWindow( "look at the shade" );
glutReshapeFunc( reshape );
glutKeyboardFunc( keyboard );
glutDisplayFunc( display );
glutIdleFunc( idle );

init();
glutMainLoop();
return 0;
}
[code]

光照效果是需要法向才能完成的,如果顶点没有法相,看上去就是不会反光的, 理论上每个顶点之前都要设定法相, 当然你可以偷懒,每个三角形之前设置一次——前提是你要在之前把顶点、法相等等的数据都准备好,画的时候直接载入, 或者可以通过顶点数组避免函数调用的开销,除此之外别无他法, 不知道13楼说的是什么方法(.....囧??)
,我也很想知道(.....囧???)
Cricketol 2008-08-25
  • 打赏
  • 举报
回复
还有两位大侠能不能给一个光照合理的简单例子?小弟感激不尽
Cricketol 2008-08-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yale13 的回复:]
哈哈,那个每个顶点都调用一次glnormal只是理论上的吧,一个3ds物体,上百个面,上千个点,这样搞,会死人的~
[/Quote]

那怎么把它们分割成曲面片?
Cricketol 2008-08-24
  • 打赏
  • 举报
回复
问题是我的用太阳光照射一个正弦曲面,应该是所有的影子都一样的
needallcodes 2008-08-24
  • 打赏
  • 举报
回复
那我就只能想到法向量的问题了
glNormal要在正确的坐标系下使用正确的方向
对于曲面,我建议为每个顶点都调用一次glNormal
needallcodes 2008-08-24
  • 打赏
  • 举报
回复
你不是在移动物体,而是移动视点?

如果物体相对光源静止, 而你移动视点后阴影区域发生了变化, 这不是很正常吗?

你没必要怀疑你给出的这些代码,值得怀疑的是"你的到底在移动什么"

Cricketol 2008-08-23
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 needallcodes 的回复:]
你说的影子是什么意思? 没有照到光的部分?
[/Quote]
恩,我说的影子可以说是背光那一面


[Quote=引用 8 楼 needallcodes 的回复:]
是不是光的位置也随移动变化了? 改变了方向光源位置就等于是扭动了光的方向啊
你得保证translate的时候光的位置是固定的, 要不光的位置也被translate了, 不知道是不是这个问题...
[/Quote]
我是用gluLookat来移动视点的
needallcodes 2008-08-23
  • 打赏
  • 举报
回复
是不是光的位置也随移动变化了? 改变了方向光源位置就等于是扭动了光的方向啊
你得保证translate的时候光的位置是固定的, 要不光的位置也被translate了, 不知道是不是这个问题...
needallcodes 2008-08-23
  • 打赏
  • 举报
回复
你说的影子是什么意思? 没有照到光的部分?
Cricketol 2008-08-21
  • 打赏
  • 举报
回复
再来2个我就结贴
CodeMasterShiller 2008-08-20
  • 打赏
  • 举报
回复
opengl没用过,帮你up
Cricketol 2008-08-20
  • 打赏
  • 举报
回复
没人能解决我的问题???
结贴了
来的就给分
Cricketol 2008-08-05
  • 打赏
  • 举报
回复
我是在x轴正负方向上移动
向两边移动都会打成一片
打成一片之后转动光源又有影子了
我估计是矩阵受到视点移动的影响
不过不确定,也不知道怎么防止光源方向受影响
yale13 2008-08-05
  • 打赏
  • 举报
回复
你是不是往z轴的正方向移动了啊?如果往负方向移动,估计没这个问题~
wangjin540 2008-08-05
  • 打赏
  • 举报
回复
欢迎加入游戏开发交流超级群47602233
拥有1G学习资料共享空间!
大家一起努力把中国游戏产业壮大!

8,304

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧