我正试图让我的程序中的灯光和反射正确。我有一个大球体,我可以移动鼠标,它应该是一个光源(LIGHT0),并且较小的球体会反射光线。我还需要一个方向灯,我可以用键盘改变方向
我定义了一些颜色:
float whitish[] = {0.8f, 0.8f, 0.8f, 1};
float white[] = {1, 1, 1, 1};
float blackish[] = {0.2f, 0.2f, 0.2f, 1};
float black[] = {0, 0, 0, 1}
我用
创建定向灯gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, spot_position,0);
spot_position最初是[0,0,1,0],但可以通过按键盘键来改变。按键将0.05添加到位置矢量的特定组件,直到达到1,然后重置为-1(没什么特别的)。
中心球的光是:
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, position,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, blackish,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, white,0);
gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, white,0);
此灯的位置始终位于我的大透明球体内。位置向量的w分量为1。
我有这个代码在后面绘制图片
gl.glBegin(GL_QUADS);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, white,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, white,0);
// Back Face
gl.glNormal3f(0, 0, 1);
gl.glTexCoord2f(texRight, texBottom);
gl.glVertex3f(rx2, ry1, rz1);
gl.glTexCoord2f(texRight, texTop);
gl.glVertex3f(rx2, ry2, rz1);
gl.glTexCoord2f(texLeft, texTop);
gl.glVertex3f(rx1, ry2, rz1);
gl.glTexCoord2f(texLeft, texBottom);
gl.glVertex3f(rx1, ry1, rz1);
要绘制球体,我使用以下功能:
public void drawtriangle(float[] v1, float[] v2, float[] v3) {
gl.glBegin(GL.GL_TRIANGLES);
gl.glNormal3fv(v1, 0);
gl.glVertex3fv(v1, 0);
gl.glNormal3fv(v2, 0);
gl.glVertex3fv(v2, 0);
gl.glNormal3fv(v3, 0);
gl.glVertex3fv(v3, 0);
gl.glEnd();
}
private void subdivideSphere2(float v1[], float v2[], float v3[], long depth) {
float v12[] = new float[3];
float v23[] = new float[3];
float v31[] = new float[3];
int i;
if (depth==0) {
float[] color= {v1[0]*v1[0], v2[1]*v2[1], v3[2]*v3[2], alpha};
gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, blackish,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, color,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, color,0);
gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, color,0);
drawtriangle(v1, v2, v3);
return;
}
for (i = 0; i<3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
normalize(v12);
normalize(v23);
normalize(v31);
subdivideSphere2(v1, v12, v31, depth-1);
subdivideSphere2(v2, v23, v12, depth-1);
subdivideSphere2(v3, v31, v23, depth-1);
subdivideSphere2(v12, v23, v31, depth-1);
}
public void drawSphere() {
subdivideSphere2(sVdata[0], sVdata[1], sVdata[2], depth);
subdivideSphere2(sVdata[0], sVdata[2], sVdata[4], depth);
subdivideSphere2(sVdata[0], sVdata[4], sVdata[5], depth);
subdivideSphere2(sVdata[0], sVdata[5], sVdata[1], depth);
subdivideSphere2(sVdata[3], sVdata[1], sVdata[5], depth);
subdivideSphere2(sVdata[3], sVdata[5], sVdata[4], depth);
subdivideSphere2(sVdata[3], sVdata[4], sVdata[2], depth);
subdivideSphere2(sVdata[3], sVdata[2], sVdata[1], depth);
}
我的问题是,小球根本没有反射光。它们一直非常明亮。当我将大球体移近它们时,我可以看到一点点光线反射在立方体的绿线上,但对球体没有任何影响。此外,当我移动定向灯(LIGHT1)时,我看不出任何差异。我没有看到立方体线条,大球体,小球体或背面图片的任何反射。下面是我的程序的截图。如何让我的球体不发光,反射定向光和大球体的光?任何帮助将不胜感激。谢谢。
答案 0 :(得分:1)
在追踪你的小球体时,看起来闪电被禁用了。我没有看到你调用drawSphere的代码,但它看起来好像你正在跟踪启用了GL_LIGHTING的Big球体以及禁用了GL_LIGHTING的小球体。
答案 1 :(得分:0)
通过反射光线,你的意思是它被照亮了吗?反射涉及光线追踪,是一个更大的主题。
我没有JOGL的直接经验,但是我已经使用了相当数量的jME3,这种问题通常是由于使用了一种不亮的材料(这里似乎不是这种情况)由于物体上的法线不正确,或者仅仅是环境光和/或材料的环境颜色过高而被点亮了。
答案 2 :(得分:0)
据我所知,你没有正确设置法线。法线应该基本上指向你想要反射光的方向,这通常是距离三角形“90°”(使用十字产品)。然后,OpenGL将使用该法线计算表面反射的实际光照。有关详细说明,请参阅this tutorial。
另一个问题是你使用过时的OpenGL 2.0功能,它执行基于顶点的光照,因此有效地将球体中的每个三角形减轻到相同的值。如果您正在寻找使用过时功能几乎不可能的逐像素照明,除非球体的顶点与屏幕上的像素一样多,您需要更新代码并使用着色器。
This tutorial不是Java,但它很好地解释了现代OpenGL的基础知识,并且应该可以轻松地转换为JOGL。