在顶点着色器和片元着色器中我们都要使用的着色器语言,我们先来看下常用的限定符:
attribute :仅仅可以在顶点着色器中被访问。attribute 是在随着每一个顶点不同而会发生变动的输入值,例如顶点的位置和纹理坐标等。数据中有多少个顶点,管线就调用多少次顶点着色器,每次将顶点的各个属性数据传递给顶点着色器中对应的 attribute 变量;因此,顶点着色器每次执行将完成对一个顶点各项属性数据的处理。
private static final String VERTEX_SHADER_SOURCE = "attribute vec4 aPosition;" +
"void main() {" +
" gl_Position = aPosition;" +
"}";
例如三角形有三个顶点,我们把顶点数组转化为FloatBuffer后,会分3次调用以上的顶点着色器,每次会会把一个顶点数据传到 aPosition 变量中;
所以 attribute 接收的是那种会变的值,例如位置顶点,顶点颜色和纹理顶点等;
uniform :可用在顶点着色器和片元着色器,是为在一个渲染循环里不变的输入值设计的,比如你的每个顶点或片元对应相同的变量,你可以把这个变量设置成uniform,如变换矩阵等;
private static final String FRAGMENT_SHADER_SOURCE = "uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
以上代码说明每个片元的颜色都相同,所以用到了 uniform 来声明;
varying :在顶点着色器和片段着色器都会出现。varying 是用来在顶点着色器和片段着色器传递信息的;
顶点着色器
uniform mat4 uMVPMatrix;
attribute vec3 aPosition;
attribute vec4 aColor;
varying vec4 vColor;
void main() {
gl_Position = uMVPMatrix * vec4(aPosition,1);
vColor = aColor;
}
片元着色器
precision mediump float;
varying vec4 vColor;
varying vec3 vPosition;
void main() {
gl_FragColor = vColor;
}
由上面代码可以看出, vColor 值由顶点着色器传到了片元着色器,但不是一一对应的传,由于三角型的顶点只有三个,所以对应3个顶点颜色,光栅化后产生了多个片元,就会插值计算出多少套 varying 变量,渲染管线就会调用多少次片元着色器。