OpenGL ES 3.0编程指南:第五章. OpenGL ES Shading Language --- (四)

[TOC]

15. Vertex and Fragment Shader Inputs/Outputs

Shader语言中的另一个特殊变量类型是顶点输入变量(也叫顶点属性)。顶点输入变量使用 in限定符,用来指明每个顶点的输入,通常储存位置、法线、颜色等内容。

#version 300 es

uniform mat4 u_matViewProjection;
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_color;
out vec3 v_color;
void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_color = a_color;
}

上面例子中的两个变量a_positiona_color就是顶点输入变量,由应用程序给这两个变量加载数据。最终,应用程序会创建一个顶点数组,数组里的每个顶点都包含位置信息和颜色信息。Layout限定符用于指明顶点输入变量的索引位置,这个是可选的,如果没有使用layout限定符,链接器会自动为每个顶点属性分配索引位置。

顶点属性的数量也是有限制的,可以通过内置变量gl_MaxVertexAttrinbs查询(或者使用glGetIntegerv调用GL_MAX_VERTEX_ATTRIBS查询)。任何一个OpenGL ES 3.0的实现都最少支持16个顶点属性。

顶点shader的输出变量用out限定符来声明,上面例子中的v_clolor就是一个输出变量。每个顶点shader将它需要传递给片段shader的数据通过一个或多个输出变量来传送。这些顶点输出变量在片段shader中用in限定符声明为片段输入变量,并且在光栅化阶段会进行线性插值。

需要注意,顶点输出变量和片段输入变量不同使用layout限定符,应用程序会自动为它们分配位置。顶点输出变量的限制数量可以通过内置变量gl_MaxVertexOutputVectors查询(或者使用glGetIntegerv调用GL_MAX_VERTEX_OUTPUT_COMPONENTS查询,注意这个获得的是总的分量的数量,而不是向量的数量),任何实现所支持的最小数是16。片段输入变量的限制数量可以通过内置变量gl_MaxFragmentInputVectors查询(或者使用glGetIntegerv调用GL_MAX_FRAGMENT_INPUT_COMPONENTS查询,注意这个获得的是总的分量的数量,而不是向量的数量),任何实现所支持的最小数是15 。

// Vertex shader
#version 300 es

uniform mat4 u_matViewProjection;

// vertex shader output
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_color;

// vertex shader output
out vec3 v_color;

void main(void)
{
    gl_Position = u_matViewProjection * a_position;
    v_color = a_color;
}


// Fragment shader
#version 300 es
precision mediump float;

// input from vertex shader
in vec3 v_color;

// output of fragment shader
layout(location = 0) out vec4 o_fragColor;

void main()
{
    o_fragColor = vec4(v_color, 1.0);
}

片段shader输出一个或多个颜色。一般情况下,我们只会渲染到一个颜色缓冲区中,这种情况下,layout限定符是可选的(输出变量渲染到位置0)。然而,当渲染到多个目标时(MRTs),我们通过layout限定符指明每个输出变量渲染到哪一个渲染目标中。

16. Interpolation Qualifiers

当顶点输出变量和片段输入变量没有指明限定符时,默认采用平滑着色,也就是线性插值。我们也可以明确指明使用平滑着色:

// vertex shader output
smooth out vec3 v_color;
...

// fragment shader input
smooth in vec3 v_color;

OpenGL ES 3.0同时也引入了另一种插值方式:平面着色(flat)。在平面着色中,不在图元内进行插值运算,而是根据图元类型将图元的一个顶点视为驱动顶点,这个驱动顶点的值被所有片段所使用:

// vertex shader output
flat out vec3 v_color;

// fragment shader input
flat in vec3 v_color;

最后,还有另一个限定符:质心采样(centroid)。质心采样的具体定义会在第11章进行介绍,简单来说就是,在使用多重采样时,centroid限定符会强制插值发生在图元内部(否则,在图元边缘就会发生伪像):

// vertex shader output
smooth centroid out vec3 v_color;

// fragment shader input
smooth centroid in vec3 v_color;

你可能感兴趣的:(OpenGL ES 3.0编程指南:第五章. OpenGL ES Shading Language --- (四))