I. Introduction
Vertex shader operations for the vertex-based, for example, by changing positions matrix calculated by the illumination color generated equations to generate or transform the vertex and texture coordinates.
Common concepts:
- Properties: vertex data providing vertex array (keywords: attribute / in)
- Output: calculating vertex shader stage in FIG grating element is the output generated by each segment, and to input the fragment shader (keyword: varying / out)
- Uniform variables: the same data (keyword: uniform) using the vertex shader
- Unified variable type vertex shader using the special texture: sampler (keyword: sampler2d / sampler3d)
- Shader program: shader source code or executable file
Second, the built-in variables
1. Built-in special variables
variable | description |
---|---|
gl_VertexID | Input variables, save for the integer index of vertices. highp precision integer variable |
gl_InstanceID | Input variables, for example the number of primitives stored instantiated draw call. highp precision integer variable, usually 0 |
gl_Position | Output variables, as vertex coordinates for clipping the output. highp precision floating-point variables |
gl_PointSize | It is used to specify point size sprite, in pixels. highp precision floating-point variables |
gl_FrontFacing | Help vertex shader written directly, but generating the position value generated by the vertex shader and rendering primitive type, which is a Boolean variable |
2. Built-in unified state
Vertex shader is only the built-in a state of unity in the depth range window coordinates, given by the variable name unified built gl_DepthRange, the variable is declared as a unified type variable gl_DepthRangeParameters
struct gl_DepthRangeParameters {
highp float near; // near z
highp flaot far; // far z
highp float diff; // far - near
}
uniform gl_DepthRangeParameters gl_DepthRange;
3. Built-in constants
In all ES 3.0 implementation, the following minimum constants are supported, but the actual value of the specified interface requires the use of a query.
Types of | name | Minimum | description |
---|---|---|---|
const mediump int | gl_MaxVertexAttribs | 16 | The maximum number of vertex shader properties |
const mediump int | gl_MaxVertexUniformVectors | 256 | The maximum number of vertex shader uniform variable |
const mediump int | gl_MaxVertexoutputVectors | 16 | The maximum number of vertex shader output vector |
const mediump int | gl_MaxTextureImageUnits | 16 | The maximum number of vertex shader texture units |
const mediump int | gl_MaxCombinedTextureImageUnits | 32 | The sum of the vertex shader and fragment shader maximum number of texture units |
Third, a unified variable quantitative restrictions
We know that the above described maximum gl_MaxVertexUniformVectors vertex shader variables uniform, unified storage variable the following variables:
- Variable uniform qualifier declares
- const qualifier declares a constant variable
- Literals (e.g., 0.0 or 1.0, etc.)
- Implementation-specific constants
For literal, ES 3.0 specification makes no constant propagation. The result is a plurality of instances literal will be calculated multiple times, i.e., we should state variable instead constants corresponding literal, a literal value can be avoided with the calculated times.
Examples
A vertex shader is as follows:
#version 300 es
#define NUM_TEXTURES 2
uniform mat4 tex_matrix[NUM_TEXTURES];
uniform bool enable_tex[NUM_TEXTURES];
uniform bool enable_tex_matrix[NUM_TEXTURES];
in vec4 a_texcoord0; // available if enable_tex[0] is true
in vec4 a_texcoord1; // available if enable_tex[1] is true
out vec4 v_textcoord[NUM_TEXTURES];
void main() {
v_textcoord[0] = vec4(0.0, 0.0, 0.0, 1.0);
if (enable_tex[0]) {
if (enable_tex_matrix[0]) {
v_textcoord[0] = tex_matrix[0] * a_texcoord0;
} else {
v_textcoord[0] = a_texcoord0;
}
}
v_textcoord[1] = vec4(0.0, 0.0, 0.0, 1.0);
if (enable_tex[1]) {
if (enable_tex_matrix[1]) {
v_textcoord[1] = tex_matrix[1] * a_texcoord1;
} else {
v_textcoord[1] = a_texcoord1;
}
}
}
In the embodiment 0,1,0.0,1.0 each literal reference will be collectively stored variables taken into account, in order to ensure that these literals only counted once, may be used instead of the constant variable, for example:
#version 300 es
#define NUM_TEXTURES 2
uniform mat4 tex_matrix[NUM_TEXTURES];
uniform bool enable_tex[NUM_TEXTURES];
uniform bool enable_tex_matrix[NUM_TEXTURES];
in vec4 a_texcoord0; // available if enable_tex[0] is true
in vec4 a_texcoord1; // available if enable_tex[1] is true
out vec4 v_textcoord[NUM_TEXTURES];
const int zero = 0;
const int one = 1;
void main() {
v_textcoord[zero] = vec4(float(zero), float(zero), float(zero), float(one));
if (enable_tex[zero]) {
if (enable_tex_matrix[zero]) {
v_textcoord[zero] = tex_matrix[zero] * a_texcoord0;
} else {
v_textcoord[zero] = a_texcoord0;
}
}
v_textcoord[one] = vec4(float(zero), float(zero), float(zero), float(one));
if (enable_tex[one]) {
if (enable_tex_matrix[one]) {
v_textcoord[one] = tex_matrix[one] * a_texcoord1;
} else {
v_textcoord[one] = a_texcoord1;
}
}
}
Fourth, the matrix transformation
1. Transform the vertex shader matrix position
#version es 300
unidorm mat4 u_mvpMatrix // 把坐标从模型空间转换到裁剪空间的矩阵
layout(location = 0) in vec4 a_position; // 输入的位置值
layout(location = 1) in vec4 a_color; // 输入的颜色值
out vec4 v_color; // 输出的颜色值,将是片段着色器的输入值
void main() {
v_color = a_color;
gl_Position = u_mvpMatrix * a_position;
}
In the embodiment unified variables u_mvpMatrix
introduced the concept of "Model - Projection (the MVP) - View" matrix. Save location for the vertex shader input object coordinates, saved as a crop output position coordinates. MVP for this transformation matrix is the product of three 3D graphics transformation matrix is very important: model matrix, and projection matrices attempt.
Related concepts:
- Model matrix: the object coordinates to world coordinates
- View matrix: the world coordinates to eye coordinates
- Projection matrix: the eye coordinate change cropping coordinates
- Model - View Matrix: model and view matrices into a single matrix, object vertex position coordinates transformed from the coordinates of the eyes, a composition changes from object coordinates to world coordinates and the world coordinates to the eye.
2. Example
A common process MVP matrix is generated:
private final float[] mProjectionMatrix = new float[16]; // 投影矩阵
private final float[] mModelMatrix = new float[16]; // 模型矩阵
private final float[] mViewMatrix = new float[16]; // 视图矩阵
private final float[] mViewProjectionMatrix = new float[16];
private final float[] mModelViewProjectionMatrix = new float[16]; // MVP矩阵
// 1.投影矩阵
// 以45度的视野创建一个投影矩阵,视锥体从z值为-1的位置开始,在z值为-10的位置结束
Matrix.perspectiveM(mProjectionMatrix, 0, 45, (float) width / (float) height, 1f, 10f);
// 2.视图矩阵
// 把眼睛设为(0,1.2,2.2)的位置,即眼睛在x-z平面三方1.2个单位,向后2.2个单位
Matrix.setLookAtM(mViewMatrix, 0, 0f, 1.2f, 2.2f, 0f, 0f, 0f, 0f, 1f, 0f);
// 3. 模型矩阵
// 初始化模型矩阵为一个单位矩阵
Matrix.setIdentityM(mModelMatrix, 0);
// 将模型沿着z轴平移-2个单位,使得我们可以看见它
Matrix.translateM(mModelMatrix, 0, 0f, 0f, -2f);
// 将模型绕着x轴旋转-60度
Matrix.rotateM(mModelMatrix, 0, -60, 1f, 0f, 0f);
// 4.MVP矩阵
// 将投影和视图矩阵相乘,并缓存到mViewProjectionMatrix中
Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
// 将模型矩阵和上述ViewProjectionMatrix矩阵相乘,即是MVP矩阵
Matrix.multiplyMM(mModelViewProjectionMatrix, 0, mViewProjectionMatrix, 0, mModelMatrix, 0);