OpenGL ES 3.0 shading language basic grammar

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

Foreword

In OpenGL development, we have to mention shading languages, shading languages ​​for writing the vertex shader and fragment shader. Then we briefly explain some basic language syntax coloring.

Note: The content comes from "OpenGL ES 3.0 Programming Guide," a book.

First, the version specification

In OpenGL ES 3.0, the first row of the vertex shader and fragment shader declaration always shader version.
Use the following syntax for declaring shaders Shading Language version 3.00:

#version es 300

No declaration or statement #version es 100is identified as version 1.00 shading language use, that is used in OpenGL ES 2.0 version.

Second, variables and variable types

OpenGL ES shading language data types are as follows:

Variable Category Types of description
Scalar quantity float, int, uint, bool Floating-point, integer, unsigned integer, Boolean scalar type of
Vector Floating-Point float, vec2, vec3, vec4 1,2,3,4 components, based on the type of floating point vector
Integer vector int, ivec2, ivec3, ivec4 1,2,3,4 components, based on the type integer of the vector
Unsigned integer vector uint, uvec2, uvec3, uvec4 1,2,3,4 component, an unsigned integer type vector based on
Boolean vector bool, bvec2, bvec3, bvec4 1,2,3,4 component, based on Boolean vector types
matrix mat2x2 (mat2), mat2x3, mat2x4, mat3x2, mat3x3 (mat3), mat3x4, mat4x2, mat4x3, mat4x4 (mat4) Floating-point matrix of various sizes, the first number indicates the number of columns, the second number indicates the number of rows

Each variable must have type declarations, using the example:

float angle; // 浮点标量
vec4 vPosition; // 有4个分量的浮点向量
mat4 mViewProjection; // 4*4大小的浮点矩阵
ivec2 vOffset; // 有2个分量的整数向量

Third, the variable constructor

Coloring language for variable types have very restricted and can only be copied and operations between the same type of variable, does not allow implicit type conversion.

For conversion type, there may be configured to initialize variables, each type has a built-in variables associated constructor.

1. scalar constructor

float myFloat = 1.0;
float myFloat2 = 1; // 错误:非法的类型转换
int myInt = 1;
float myFloat3 = float(myInt); // 正确:将int转为float

2. vector constructor

Follow two basic methods:

  • If only one scalar parameter, all values ​​for the set of vectors.
  • If a plurality of scalar or vector parameter, press the left to right order assignment.

Example:

vec4 myVec4 = vec4(1.0); // myVec4 = {1.0, 1.0, 1.0, 1.0}
vec3 myVec3 = vec3(0.0, 0.5, 1.0); // myVec3 = {0.0, 0.5, 1.0}
vec2 myVec2 = vec2(myVec3); // myVec2 = {0.0, 0.5}
myVec4 = vec4(myVec2, myVec3); // myVec4 = {0.0, 0.5, 0.0, 0.5}

3. Matrix Builder

The basic principle:

  • If only one scalar parameter, the value for the diagonal matrix. For example, mat4(1.0)it will create a matrix of 4 * 4.
  • It can be configured using a plurality of vector parameter. For example, can be constructed from two mat2 vec2.
  • There are a plurality of scalar parameters can be configured, each representing a value of the matrix, from left to right to use.

Example:

mat3 myMat3 = mat3(1.0, 0.0, 0.0, // 第一列 
                   0.0, 1.0, 0.0, // 第二列
                   0.0, 1.0, 1.0); // 第三列

Fourth, the vectors and matrix elements

1. The components of the vector

Operators can use the dot .or array subscripts []are two ways to access components of the vector.

When using the dot operator, each component may use the vector coordinate X {, Y, Z, W} , the color coordinates {r, g, b, a } or {s, t, p, q } texture coordinates three kinds of compositions named access. A different naming convention for convenience only, but not a mixture of different cross-naming convention.

Example:

vec3 myVec3 = vec3(0.0, 1.0, 2.0);

vec3 temp = myVec3.xyz; // temp = {0.0, 1.0, 2.0}
temp = myVec3.xxx; // temp = {0.0, 0.0, 0.0}
temp = myVec3.bgr; // temp = {2.0, 1.0, 0.0}

When using the array index, the elements [0]corresponding to x, the elements [1]corresponding to y, and the like.

2. matrix components

Matrix can be seen by a number of vector components. For a matrix, single column array subscript can be used []to access, thus obtaining a vector of a matrix, and each vector can be accessed by way of access vectors.

Example:

mat4 myMat4 = mat4(1.0); // 4*4的单位矩阵

vec4 col0 = myMat4[0]; // 得到矩阵的第一列
float m1_1 = myMat4[1][1]; // 得到矩阵中[1][1]的元素
float m2_2 = myMat4[1].z; // 得到矩阵中[2][2]的元素

V. Constant

By adding a statement constqualifier may be declared as a constant variable, a constant read only, can not be modified. Constants must be initialized when they are declared.

Example:

const float pi = 3.14159;
const vec4 red = vec4(1.0, 0.0, 0.0, 0.0);
const mat4 identity = mat4(1.0);

Sixth, structure

Structure similar to the C language, the language may be colored polymeric variables into the structure.

Example:

struct fogStruct {
    vec4 color;
    float start;
    float end;
} fogVar;

fogVar = fogStruct(vec4(0.0, 1.0, 0.0, 0.0), // color
                   0.5, // start
                   2.0); // end
vec4 color = fogVar.color;
float start = fogVar.start;
float end = fogVar.end;

Seven array

Shading Language also supports an array, the array is also similar to the C language. Wherein the number of parameters of the constructor must be equal to the array size.

Example:

float a[4] = float[]{1.0, 2.0, 3.0, 4.0};
float b[4] = float[4]{1.0, 2.0, 3.0, 4.0};
vec2 c[2] = vec2[2](vec2(1.0), vec2(2.0));

Eight operators

OpenGL ES shading language operators:

Operator Type description Operator Type description
* Multiply ==,!=,<,>,<=,>= Comparison Operators
/ except && Logic and
% Modulo ^^ Logical XOR
+ plus || Logical or
- Less <<,>> Displacement
++ Increment &,^,| Bitwise AND, XOR, or
Decreasing ?: Ternary operator
= Assignment , sequence
+=,-=,*=,/= Arithmetic Assignment

Use as in the C language, it is noted that, due to the strict rules type, operator can only occur between the same basic type.

Further, addition ==and !=addition, comparison operators <( <=, >, , >=) for only a scalar. To compare vector, built-in functions may be used, component-wise compared.

IX function

C function declarations and similar language, and the function given previously in use, it must first provide a prototype declaration. Special qualifier shading language, whether the variable defined functions can modify the parameters.

Qualifier:

Qualifier description
in The default value, a parameter indicating passed by value function can not be modified
out Means no value of the variable passed to the function, will be modified when the function returns
inout By introducing a parameter indicating transmission will be changed when the function returns

Example:

// 计算基本漫射光线
vec4 diffuse(vec3 normal, vec3 light, vec4 baseColor) {
    return baseColor * dot(normal, light);
}

Note: shading language, the function is not recursive.

Ten, built-in functions

OpenGL ES Shading Language has many built-in functions, deal with a variety of computing tasks. In order to efficiently write shaders, you must be familiar with common built-in functions.

Example :( substantially reflective illumination Fragment shader fragment calculation)

float nDotL = dot(normal, light);
float rDotV = dot(viewDir, (2.0 * normal) * nDotL - light);
float specular = specularColor * pow(rDotV, specularPower);

Example using the dotcalculated dot product of two vectors, using the powpower of the scalar calculation. The number of functions built many of the limited space here will not be described in detail, we want to know can access relevant information.

Eleven, control flow statements

Control flow statements and the C language syntax coloring language is similar. However, the value of the test expression conditional statements must be a boolean value.

if-then-else Example of use:

if (color.a < 0.25) {
    color *= color.a;
} else {
    color = vec4(0.0);
}

Of course there are whileand do-whilecycling.

In OpenGL ES 2.0, there are very strict cycle using control rules, but those limitations gone in 3.0. This does not mean no effect on the performance of the cycle, the rule of thumb, you should attempt to limit the cross-flow diffusion control vertex / fragment or use of loop iterations.

XII uniform variable

Uniform variables in the global scope uniformqualifier statement. Namespace Uniform variable in the vertex shader and fragment shader are shared.

Example:

uniform mat4 viewProjMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

Uniform application is typically stored variable value by the read-only API passed shader, such as a matrix transformation, lighting, and color parameters.

XIII, unified variable block

Unified variable block is 3.0 of a new thing, it can be used for uniform buffer object variable . Use of uniform buffer object variable, unified buffer data can be shared among multiple programs, need only be set once. And between the unified buffer variable object switching time than single unified variable load more efficient.

Example of use:

#version es 300

uniform TransformBlock {
    mat4 matViewProj;
    mat3 marNormal;
    mat3 matTexGen;
};

layout(location = 0) in vec4 a_position;

void main() {
    gl_Position = matViewProj * a_position;
}

Layout unified block variable qualifier

Some optional qualifier may be used to specify the layout of the unified buffer object unified support variable block layout in memory.

1. All layout qualifier can be used to block the unified variable

Qualifier description
shared (default) Specify a plurality of shader programs or a plurality of memory blocks the same as the layout of the unified variable. Using this qualifier, row_major / column_major define different values ​​must be equal. Cover and packed std140
packed Specifies that the compiler can optimize the layout of unified memory variable block. Using this qualifier must query the offset position, and the variable block is not uniform shared vertices / and fragment shader program. Covering std140 and shared
std140 Specifies a uniform layout based on a variable block OpenGL ES 3.0 standard set of rules defined in the specification. Covering shared and packed
row_major In the memory matrix in row major order layout
column (default) Memory matrix column-major order layout order

2. Give all unified block of variables to set the default layout

In the global scope, you can add the following statement:

layout(packed, row_major) uniform;

3. The block is provided to a single unified variable layouts

layout(std140) uniform TransformBlock {
    mat4 matViewProj;
    layout(row_major) mat3 matNormal;
    mat3 matTexGen;
}

Fourteen, input and output vertex and fragment shader

使用 in 关键字表示输入,out 关键字表示输出。

1. 顶点着色器示例:

#version es 300

uniform mat4 u_matViewProj;
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_color;
out vec3 v_color;

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

顶点着色器中,输入变量通常存储位置、法线、纹理坐标和颜色这样的数据,数据由应用程序加载。

上例中我们在输入变量前加了 layout 限定符,用于指定顶点属性的索引、这个是可选的,如果没有指定,将由链接程序自动分配。

顶点着色器中,输出变量将被传递到片段着色器中。在片段着色器中,我们使用与之匹配的输入变量声明,例如 in vec3 v_color

2. 片段着色器示例:

#version es 300
precision mediump float;

in vec3 v_color; // input form vertex shader
layout(location = 0) out vec4 o_fragColor;

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

片段着色器中,输入变量是顶点着色器中的输出变量,需要保证类型和变量名一致。

片段着色器通常输出一个或多个颜色。通常我们只渲染到一个颜色缓冲区,这时布局限定符是可选的。当渲染到多个目标时(MRT),我们可以使用布局限定符指定每个输出前往的目标。

十五、插值限定符

上例中我们指定了顶点着色器的输出变量,即片段着色器的输入变量 v_color。我们可以给其添加插值限定符,指明其使用的插值方式。

插值限定符 描述
smooth 默认方式,平滑着色,顶点着色器的输出变量在图元中线性插值
flat 平面着色,将一个顶点视为驱动顶点(取决于图元类型),该顶点的值用于图元中所有片段
centroid 质心采样,使用多重采样渲染时,该限定符可用于强制插值发生在被渲染图元内部,否则图元边缘可能出现伪像

示例:

// 顶点着色器中
smooth out vec3 v_color;

// 片段着色器中
smooth in vec3 v_color;

十六、预处理器和指令

和 C 语言类似,不同点是宏不能定义为带有参数。

1. 条件测试宏

#define
#undef
#if
#ifdef
#ifndef
#else
#elif
#endif

2. 其余常见宏

__LINE__    // 当前行的行数
__FILE__    // 在 OpenGL ES 3.0 中始终为 0
__VERSION__ // 版本号,例如 300
GL_ES       // 在着色语言中始终为 1

#error      // 导致着色器编译出错,并在信息日志中放入对应消息
#pragma     // 为编译器指定特定于实现的指令
#extension  // 启用和设置扩展行为

十七、精度限定符

较低的精度效率更高,较高的精度效果更高。这种提升效率是以精度为代价的,不合适的精度限定符可能会导致伪像。

精度限定符种类:

  • lowp : 低精度
  • mediump : 中精度
  • highp : 高精度

注意:

在顶点着色器中,如果没有指定默认精度,则 int 和 float 默认精度都是 highp。

在片段着色器中,浮点值没有默认精度,必须由开发者声明。

十八、不变性

由于编译器可能进行指令的重新排序的优化,指令重排导致两个着色器之间的等价计算不能保证结果一致,而导致一些诸如“深度冲突”等问题。

使用 invariant 关键字给变量声明不变性,编译器会保证相同的输入和计算,在所有的脚本中结果一致,但是会导致性能下降。

示例:

#version es 300

uniform mat4 u_matViewProj;
layout(location = 0) in vec4 a_position;
invariant gl_Position;

void main() {
    gl_Position = u_matViewProj * a_position;
}

使用 #pargma 指定所有变量全都不变:

#pargma STDGL invariant(all)

不变性只在必要时才使用,它会限制编译器所做的优化,更不建议指定所有变量全都不变。

Guess you like

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