My OpenGL thematic learning directory, hope to learn with you exchange progress!
- OpenGL Learning (I) – Terminology understanding
- OpenGL learning (2) — Xcode build OpenGL environment
- OpenGL learning (three) – OpenGL base rendering
- OpenGL learning (4) – front & back culling and depth testing
- OpenGL Learning (5) – Cropping and Blending
- OpenGL Learning (6) – Base textures
- OpenGL Learning (7) — Summary of basic change Comprehensive Exercise practice
- OpenGL ES Learning (8)
- OpenGL learning (nine) — OpenGL ES preliminary exploration (next) GLKit
- OpenGL learning (10) – GLSL syntax introduction
- OpenGL learning (11) – using GLSL to load pictures
- OpenGL learning (12) — OpenGL ES texture flipping strategy comparison
A list,
GLSL (OpenGL Shading Language) is a Language for Shading programming in OpenGL, that is, short custom programs written by developers that they execute on the graphics card’s GPU instead of a fixed part of the rendering pipeline, Make different layers in the render pipeline programmable. GLSL uses C as its basic high-level coloring language, avoiding the complexity of using assembly language or hardware specification language.
Variable naming
GLSL variables are named in a similar way to C. They can be named using letters, numbers, and underscores (_), but cannot start with a number. Also note that variable names cannot be prefixed with gl_, which is a GLSL reserved prefix for GLSL internal variables.
Data types
1. Basic data types
type | describe |
---|---|
void | withCThe language of thevoidSimilarly, represents an empty type. As the return type of a function, indicating that the function does not return a value. |
bool | Boolean type.true 或 false, and expressions that can produce Booleans. |
int | Signed integer |
uint | Unsigned shaping |
float | floating-point |
2. Special Type — Texture sampling type
type | describe |
---|---|
sampler1D | Used to reference the specified in the built-in texture functionHandle to 1D texture. Can only be used as a consistent variable or function parameter |
sampler2D | 2d texture handle |
sampler3D | Handle to 3d texture |
samplerCube | Cube Map texture handle |
sampler1DShadow | One-dimensional depth texture handle |
sampler2DShadow | 2d depth texture handle |
3. Aggregate types (vector and matrix types)
(1) Vector type
type | describe |
---|---|
vec2,vec3,vec4 | 2-component, 3-component, and 4-component floating point vectors |
ivec2,ivec3,ivec4 | 2-component, 3-component, and 4-component integer vectors |
uvec2,uvec3,uvec4 | 2-component, 3-component, and 4-component unsigned integer vectors |
bvec2,vbec3,bvec4 | 2 -, 3 -, and 4-component Boolean vectors |
A, vector declaration — 4-component float vector
vec4 V1;
Copy the code
B, declare vectors and construct them
vec4 V2 = vec4(1.2.3.4);
Copy the code
C, vector operation
vec4 v;
vec4 vOldPos = vec4(1.2.3.4);
vec4 vOffset = vec4(1.2.3.4);
// Note: Next assume that all the variables involved in the operation are defined and assigned.
v = vOldPos + vOffset;
v = vNewPos;
v += vec4(10.10.10.10);
v = vOldPos * vOffset;
v *= 5;
Copy the code
D, vector element acquisition (component selection)
The individual components of a vector can be denoted by {x,y,z,w}, {r,g,b,a} or {s,t,p,q}. These different notations are used for vertex, color, texture coordinates. You should not mix these notations in your choice of ingredients. Where the p in {s,t,p,q} replaces the r-coordinate of the texture because it is duplicated with the color R. Here are some examples of usage: for example, there are vectors v1 and v2:
vec3 v1 = {0.5.0.35.0.7};
vec4 v2 = {0.1.0.2.0.3.0.4};
Copy the code
By {x, y, z, w}, {r, g, b, b} or {s, t, p, q} to remove the element values in the vector. Through the x, y, z, w:
v2.x = 3.0f;
v2.xy = vec2(3.0f,4.0f);
v2.xyz = vec3(3.0f,4.0f,5.0f);
Copy the code
Through the r, g, b, a:
v2.r = 3.0f;
v2.rgba = vec4(1.0f,1.0f,1.0f,1.0f);
Copy the code
Through the s, t, q, r:
v2.stqr = vec2(1.0f, 0.0f, 0.0f, 1.0f);
Copy the code
Examples of errors:
float myQ = v1.q;// Error, array access out of bounds, q represents the fourth element
float myRY = v1.ry; // invalid
Copy the code
Vectors also support operating on all components at once
v1.x = v2.x +5.0f;
v1.y = v2.y +4.0f;
v1.z = v2.z +3.0f;
v1.xyz = v2.xyz + vec3(5.0f,4.0f,3.0f);
Copy the code
(2) Matrix type
type | describe |
---|---|
Mat2 or mat2x2 | Floating-point matrix type for 2×2 |
Mat3 or mat3x3 | 3×3 floating point matrix type |
Mat4 or mat4x4 | 4×4 floating point matrix type |
mat2x3 | 2 column 3 row floating point matrix (OpenGL matrix is column primary order) |
mat2x4 | Floating point matrix with 2 columns and 4 rows |
mat3x2 | Floating point matrix with 3 columns and 2 rows |
mat3x4 | Floating point matrix with 3 columns and 4 rows |
mat4x2 | Floating point matrix with 4 columns and 2 rows |
mat4x3 | Floating point matrix with 4 columns and 3 rows |
Create matrix:
mat4 m1,m2,m3;
Copy the code
Construct element matrix:
mat4 m2 = mat4(1.0f,0.0f,0.0f,0.0f
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f);
Copy the code
or
mat4 m4 = mat4(1.0f);
Copy the code
4, arrays,
Only one dimensional arrays can be used in GLSL. The type of an array can be any primitive type or structure. The following array declarations are legal:
float floatArray[4];
vec4 vecArray[2];
float a[4] = float[] (1.0.2.0.3.0.4.0);
vec2 c[2] = vec2[2] (vec2(1.0.2.0),vec2(3.0.4.0));
Copy the code
The array type has a built-in length() function that returns the length of the array.
lightPositions.length(a)// Return the length of the array
Copy the code
5. Structure
Structs can combine primitive types and arrays to form user-defined types. While defining a structure, you can define an instance of a structure. Or we can define it later.
struct fogStruct {
vec4 color;
float start;
float end;
vec3 points[3]; // Arrays of fixed size are legal
} fogVar;
Copy the code
Structs can be assigned by =, or by using ==,! = to determine whether the two structures are equal.
fogVar = fogStruct(vec4(1.0.0.0.0.0.1.0),0.5.2.0);
vec4 color = fogVar.color;
float start = fogVar.start;
Copy the code
3. Modifiers
1. Variable store qualifiers
qualifiers | describe |
---|---|
(omitted by default) is a normal local variable, readable and writable, invisible and inaccessible to the outside world | |
const | A constant value must be initialized at declaration time. It is read-only and cannot be modified |
varying | The output of the vertex shader is mainly responsible invertex 和 fragmentPass variables between. Such as color or texture coordinates, as read-only input to the fragment shader. Must be a global variable declared by the global scope. It can be scalar, vector, matrix of floating-point type. Can’t be an array or structure. |
uniform | Consistent variable. The value of a consistent variable is constant during shader execution. withconstConstants differ in that this value is unknown at compile time and is initialized externally by the shader. Consistent variables are shared between vertex shaders and fragment shaders. It can only be declared globally. |
attribute | Represents read-only vertex data, used only in vertex shaders. The data comes from the current vertex state or vertex array. It must be declared globally, not inside a function. aattributeIt can be a scalar, vector, or matrix of floating-point type. Cannot be an array or structure |
centorid varying | In the absence of multiple sampling, andvaryingIt means the same thing. In the case of multiple sampling,centorid varyingEvaluate inside the rasterized graph rather than at a fixed location in the center of the fragment. |
invariant | (invariant) used to represent the output of the vertex shader and the input of any matching fragment shader. The values computed in different shaders must be consistent. All data flow and control flow, write oneinvariantThe variables are consistent. To ensure that the results are completely consistent, the compiler needs to discard potential optimizations that might lead to inconsistent values. Do not use this modifier unless necessary. Avoid in multi-pass renderingz-fightingIt might be used. |
2. Function parameter qualifiers
GLSL allows custom functions, but arguments are passed in as values by default (the in qualifier), meaning that any variable is copied as it is passed in. If you want to pass parameters by reference, you need to add the function parameter qualifier.
qualifiers | describe |
---|---|
in | Used in a function parameter to indicate that the parameter is input. Changing the value in a function can have no adverse effects on the called function. This is the default modifier for function arguments |
out | Used in arguments to a function to indicate that the parameter is an output parameter whose value will change. |
inout | Parameter used in a function to indicate that the parameter is either an input parameter or an output parameter. |
Parameters passed in Inout are similar to those passed by reference in other OOP languages. Parameters are read and written, and changes made to parameters within a function affect the parameters themselves. Eg:
vec4 getPosition(out vec4 p){
p = vec4(0..0..0..1.);
return v4;
}
void doubleSize(inout float size){
size= size * 3.0 ;
}
Copy the code
3. Operation in GLSL
⚠️ Note that there are no implicit conversions in GLSL, even in multidimensional vectors, and assignments such as the following are incorrect:
/ / ⚠ ️ errors
int a = 2.0;
vec4 v4=vec4(1.0.1.0.2.1.0);
Copy the code
Float (int); float (int);
Float to int requires a display conversion, and the following expressions are correct:
int a = int(2.0);
float a = float(2);
int a = int(2.0) *2 + 1;
float a = float(2) *6.0+2.3;
Copy the code
2, float and vec(vector), mat(matrix) operation:
- Component-by-component operations Vec, mat these types are composition of float, and when they operate with float, they operate separately with float on each component. This is called component-by-component operations. In GLSL, most operations involving VEC and MAT are component-by-component operations, but not all of them are. Exceptions are covered below. Component by component operations are linear, which means that veC and float are veC.
Int is unoperable with vec and mat, because each component in vec and mat is of type float and cannot be evaluated component by component with int.
Float: vec, mat: vec, mat: vec, mat
vec3 a = vec3(1.0.2.0.3.0);
mat3 m = mat3(1.0);
float s = 10.0;
vec3 b = s * a; / / vec3 (10.0, 20.0, 30.0)
vec3 c = a * s; / / vec3 (10.0, 20.0, 30.0)
mat3 m2 = s * m; / / = mat3 (10.0)
mat3 m3 = m * s; / / = mat3 (10.0)
Copy the code
3. Vec (vector) and VEC (vector) operations:
The operation between two vectors must first ensure that the order of the operands are the same, otherwise it cannot be calculated. For example: VEC3 * VEC2, VEC4 + VEC3, etc.
They are evaluated by the components of the two operands at the same position, and are essentially component-by-component. This may differ a little from the above, but vec and veC remain the same.
vec3 a = vec3(1.0.2.0.3.0);
vec3 b = vec3(0.1.0.2.0.3);
vec3 c = a + b; // = vec3(1.1, 2.2, 3.3);
vec3 d = a * b; // = vec3(0.1, 0.4, 0.9);
Copy the code
4. Vec (vector) and MAT (matrix):
The order of operands should be the same, and only multiplication operation exists between VEc and MAT. They are computed in the same way as matrix multiplication in linear algebra, not component by component.
vec2 v = vec2(10..20.);
mat2 m = mat2(1..2..3..4.);
vec2 w = m * v; // = vec2(1. * 10. + 3. * 20., 2. * 10. + 4. * 20.)
vec2 v = vec2(10..20.);
mat2 m = mat2(1..2..3..4.);
vec2 w = v * m; // = vec2(1. * 10. + 2. * 20., 3. * 10. + 4. * 20.)
Copy the code
5. Mat (matrix) and MAT (matrix):
⚠️ Ensure that the operands have the same order.
Among the operations of MAT and MAT, except that the multiplication is matrix multiplication in linear algebra, the other operations are still component-by-component operations. In short, only multiplication is special, and the rest are similar to VEC and VEC operations.
mat2 a = mat2(1..2..3..4.);
mat2 b = mat2(10..20..30..40.);
mat2 c = a * b; // mat2(1.*10.+3.*20.,2.*10.+4.*20.,1.* 30.+3.*40.,2.* 30.+4.*40.);
mat2 d = a+b;// mat2(1.+10.,2.+20.,3.+30.,4.+40);
Copy the code
4. Type conversion
GLSL can be explicitly converted via constructors as follows:
bool t= true;
bool f = false;
int a = int(t); // true converts to 1 or 1.0
int a1 = int(f);// false converts to 0 or 0.0
float b = float(t);
float b1 = float(f);
bool c = bool(0);// 0 or 0.0 is converted to false
bool c1 = bool(1);// Non-0 converts to true
bool d = bool(0.0);
bool d1 = bool(1.0);
Copy the code
Five, precision limitation
GLSL will generate a large number of floating point operations when rasterizing and coloring, which may not be able to withstand the current device, so GLSL provides three floating point precision, we can use the appropriate precision for different devices. Highp, mediump, lowp;
lowp float color;
varying mediump vec2 Coord;
lowp ivec2 foo(lowp mat3);
highp mat4 m;
Copy the code
We add the Precision Mediump float at the beginning of the fragment shader; The default precision is set so that all variables that do not have an explicit precision are treated with the default precision set.
Control statements
GLSL is syntactically very similar to C, with if else, for, while, do while, continue to jump into the next loop, and break to end the loop.
for (l = 0; l < numLights; l++) {
if(! lightExists[l]);continue;
color += light[l];
}
while (i < num) {
sum += color[i];
i++;
}
do {
color += light[lightNum];
lightNum--;
} while (lightNum > 0)
Copy the code
In addition to this, GLSL also adds a special control statement called discard, which immediately jumps out of the fragment shader without any statement down. No subsequent fragment coloring is performed and the fragment is not written to the frame buffer.
if (true)
discard;
Copy the code
⚠️ Note that there is no recursion in the GLSL function!
The above summary refers to and partly extracts the following articles, thanks very much to the following authors for sharing! :
1, the author eats the code rabbit nest “primary GLSL shader (A)”
3, the author eats the code rabbit nest “primary GLSL shader (2)”
4. GLSL language basics by jeffasd
Reprint please note the original source, shall not be used for commercial communication – any more