OpenGL ES vertex shader and a built-in variables matrix transformation

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/afei__/article/details/89520350

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_mvpMatrixintroduced 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);

Guess you like

Origin blog.csdn.net/afei__/article/details/89520350