第四章 增加颜色和着色
本章的开发计划:
首先,我们会学习如何把每个点上的颜色定义为一个顶点属性,而不是整个对象都使用一种单一的颜色。
然后,我们会学习如何在构成一个物体的不同顶点之间平滑的混合这些颜色。
1.平滑着色
在第2章中,我们了解到如何在一个uniform里用单一的颜色绘制物体。我们已经知道,我们只能画点、直线以及三角形,并且所有物体都以它们为基础构建。既然受限于这三个基本的图元,我们怎样用许多不同的颜色和着色表达一个复杂的场景呢?
我们能使用的一个方法是用上百万个小三角形,每个三角形都有一个不同的颜色。如果使用足够多的三角形,我们就能欺骗观察者,让他们看到一幅美丽的、复杂的、有丰富颜色变化的场景。尽管这在技术上是可行的,但是性能和内存的开销也是非常恐怖的。
不绘制大量的平面三角形,如果有一个方法可以在同一个三角形中混合不同的颜色,如何?如果在一个三角形的每个点上都有一个不同的颜色,并在三角形的表面上混合这些颜色,我们最终将得到一个平滑着色的三角形。
平滑着色是在顶点之间完成的
OpenGL给了我们一个方法,它可以平滑地混合一条直线或一个三角形的表面上的每个顶点的颜色。我们要使用这种类型的着色使桌子中心表现得更加明亮,而其边缘处显得比较暗淡,这就好像有一盏灯挂在桌子中间的上方一样。
2.引入三角形扇
一个三角形扇以一个中心顶点作为起始,使用相邻的两个顶点创建第一个三角形,接下来的每个顶点都会创建一个三角形,围绕起始的中心点按扇形展开。为了使这个扇形闭合,我们只需要在最后重复第二个点。
3.增加一个新的颜色属性
float[] tableVerticesWithTriangles= { 0f,0f, 1f, 1f, 1f, -0.5f,-0.5f, 0.7f,0.7f, 0.7f, 0.5f,-0.5f, 0.7f,0.7f, 0.7f, 0.5f,0.5f, 0.7f,0.7f, 0.7f, -0.5f,0.5f, 0.7f,0.7f, 0.7f, -0.5f,-0.5f, 0.7f,0.7f, 0.7f, -0.5f,0f, 1f, 0f, 0f, 0.5f,0f, 1f, 0f, 0f, 0f,-0.25f, 0f, 0f, 1f, 0f,0.25f, 1f, 0f, 0f };
下一步就是从着色器中去掉uniform定义的颜色,并用一个属性替换它。接下来会更新java代码以体现这段新的着色器代码。
attribute vec4 a_Position; attribute vec4 a_Color; varying vec4 v_Color; void main() { v_Color = a_Color; gl_Position = a_Position; gl_PointSize = 10.0; }
varying 是一个特殊的变量类型,它把给它的那些值进行混合,并把这些混合后的值发送给片段着色器。使用上面的直线作为一个例子,如果顶点0的a_Color是红色,且顶点1的a_Color是绿色,然后,通过把a_Color赋值给v_Color,来告诉OpenGL我们需要每个片段都接手一个混合后的颜色。接近顶点0的片段,混合后的颜色显得更红,而越接近顶点1的片段,颜色就会