光效三要素
在 OpenGL ES中,光由三个元素组成,分别是环境元素(ambient component), 散射元素(diffuse component)和 高光元素(specular component)。我们使用颜色来设定光线元素,这看上去有些奇怪,但是由于它允许你同时指定各光线元素的颜色和相对强度,这个方法工作得很好。明亮的白色光定义为白色 ({1.0, 1.0, 1.0, 1.0}),而暗白色可能定义为灰色 ({0.3, 0.3, 0.3 1.0})。 你还可以通过改变红,绿,蓝元素的百分比来调整色偏。
下图说明了各要素产生的效果。
高光元素定义了光线直接照射并反射到观察者从而形成了物体上的“热点”或光泽。光点的大小取决于一些因素,但是如果你看到如上图黄球所示一个区域明显的光斑,那通常就是来自于一个或多个光源的高光部分。
散射元素定义了比较平均的定向光源,在物体面向光线的一面具有光泽。
环境光则没有明显的光源。其光线折射与许多物体,因此无法确定其来源。环境元素平均作用于场景中的所有物体的所有面。
环境光
你的光效中有越多的环境元素,那么就越不会产生引入注目的效果。所有光线的环境元素会融合在一起产生效果,意思是场景中的总环境光效是由所有启动光源的环境光组合在一起所决定的。如果你使用了不止一个光源,那么最好是只指定一个光源的环境元素,而设定其他所有光源的环境因素为黑 ({0.0, 0.0, 0.0, 1.0}),从而很容易地调整场景的环境光效。
下面演示了怎样指定一个很暗的白色光源:
float lightAmbient[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f }; //环境光 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient,
0);
使用像这样的很低的环境元素值使场景看上去更引入注目,但同时也意味着物体没有面向光线的面或者有其他物体挡住的物体将在场景中看得不是很清楚。
散射光
在OpenGL ES中可以设定的第二个光线元素是 散射元素(diffuse component)。在现实世界里,散射光线是诸如穿透光纤或从一堵白墙反射的光线。散射光线是发散的,因而参数较柔和的光,一般不会像直射光一样产生光斑。如果你曾经观察过职业摄影家使用摄影室灯光,你可能会看到他们使用 或者反光伞。两者都会穿透像白布之类的轻型材料并反射与轻型有色材料从而使光线发散以产生令人愉悦的照片。在OpenGL ES中,散射元素作用类似,它使光线均匀地散布到物体之上。然而,不像环境光,由于它是定向光,只有面向光线的物体面才会反射散射光,而场景中的所有多面体都会被环境光照射。
下面的例子演示了设定场景中的第一个散射元素:
float lightDiffuse[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };//漫反射光 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse,
0);
位置还需要设定光效的另一个重要属性,即光源3D空间中的位置。这不会影响环境元素,但其他两个元素由于其本性,只有在OpenGL在知道了场景中物体与光的相对位置后才能计算。例如:
float[] lightPos = new float[] {0,0,3,1}; //光源位置 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0)
关于光效的设置还有很多,大家有兴趣可以自己研究,这里有篇不错的文章,大家可以看看http://hsw625728.blog.163.com/blog/static/39570728200885104210400/
我们今天例子的效果:
实例代码:
- public class CubeRenderer implements Renderer {
-
- float box[] = new float[] {
-
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- -0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
-
- 0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
-
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
-
- -0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, -0.5f,
- };
- float lightAmbient[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };
- float lightDiffuse[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };
- float[] lightPos = new float[] {0,0,3,1};
-
-
-
- float norms[] = new float[] {
-
- 0f, 0f, 1f,
- 0f, 0f, 1f,
- 0f, 0f, 1f,
- 0f, 0f, 1f,
-
- 0f, 0f, -1f,
- 0f, 0f, -1f,
- 0f, 0f, -1f,
- 0f, 0f, -1f,
-
- -1f, 0f, 0f,
- -1f, 0f, 0f,
- -1f, 0f, 0f,
- -1f, 0f, 0f,
-
- 1f, 0f, 0f,
- 1f, 0f, 0f,
- 1f, 0f, 0f,
- 1f, 0f, 0f,
-
- 0f, 1f, 0f,
- 0f, 1f, 0f,
- 0f, 1f, 0f,
- 0f, 1f, 0f,
-
- 0f, -1f, 0f,
- 0f, -1f, 0f,
- 0f, -1f, 0f,
- 0f, -1f, 0f
- };
-
-
- FloatBuffer cubeBuff;
- FloatBuffer normBuff;
-
- float xrot = 0.0f;
- float yrot = 0.0f;
-
-
-
-
-
-
- public FloatBuffer makeFloatBuffer(float[] arr) {
- ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
- bb.order(ByteOrder.nativeOrder());
- FloatBuffer fb = bb.asFloatBuffer();
- fb.put(arr);
- fb.position(0);
- return fb;
- }
-
- public CubeRenderer() {
-
- cubeBuff = makeFloatBuffer(box);
- normBuff = makeFloatBuffer(norms);
- }
-
-
- protected void init(GL10 gl) {
- gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-
- gl.glEnable(GL10.GL_LIGHTING);
- gl.glEnable(GL10.GL_LIGHT0);
-
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
- gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);
-
- gl.glNormalPointer(GL10.GL_FLOAT, 0, normBuff);
- gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
-
- gl.glEnable(GL10.GL_DEPTH_TEST);
- gl.glEnable(GL10.GL_CULL_FACE);
- gl.glClearDepthf(1.0f);
- gl.glDepthFunc(GL10.GL_LEQUAL);
- gl.glShadeModel(GL10.GL_SMOOTH);
- }
-
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
-
- init(gl);
- }
-
- @Override
- public void onSurfaceChanged(GL10 gl, int w, int h) {
-
- gl.glViewport(0, 0, w, h);
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- GLU.gluPerspective(gl, 45.0f, ((float) w) / h, 0.1f, 10f);
- }
-
- @Override
- public void onDrawFrame(GL10 gl) {
-
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-
- gl.glMatrixMode(GL10.GL_MODELVIEW);
- gl.glLoadIdentity();
- GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);
-
- gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-
- gl.glRotatef(xrot, 1, 0, 0);
- gl.glRotatef(yrot, 0, 1, 0);
-
- gl.glColor4f(1.0f, 0, 0, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);
-
- gl.glColor4f(0, 1.0f, 0, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);
-
- gl.glColor4f(0, 0, 1.0f, 1.0f);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
- gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
-
- xrot += 0.5f;
- yrot += 0.5f;
- }
-
- }
阅读(1754) | 评论(0) | 转发(0) |