preface

This article is the Opengles added on the basis of CamerA2, to achieve the filter or black and white gray effect, because Opengles need to set the SHAder of GLSL language, here a separate GLSL study note. Reading time 20 minutes +

Reference article Huguang Wu Wang CSDN

Refer to the article

1. About the GLSL

Shaders are used to render images in place of a programmable program with a fixed rendering pipeline. Shader replaces the traditional fixed rendering pipeline and can realize the related calculation in 3D graphics calculation. Due to its programmability, it can realize a variety of image effects without being limited by the fixed rendering pipeline of the graphics card. This greatly improves the image quality.

In Opengloes, shaders are divided into vertex shader and chip shader. We can understand that: the vertex shader is executed once for each vertex to determine the position of the vertex; The tile shader is performed once per tile (which can be interpreted as per pixel) to confirm the color of each tile (pixel) rendered.

2. Brief description of GLSL

OpenGLES ‘shader language, GLSL, is a high-level graphical programming language derived from the widely used C language. Different from the traditional C language, it provides more abundant native types for image processing, such as vectors, matrices and so on. OpenGLES contains the following features:

1.GLSL is a procedural language, which is different from the object-oriented Java.

2. It’s perfect for support vector and matrix operations. 3. It manages input and output types through qualifier operations. 4.GLSL provides a number of built-in functions to provide rich extensions.

3.1 Basic Types

type describe
void As in Java, empty type. As the return type of a function, it means that the function does not return a value.
bool The Boolean types rue and false can produce Boolean expressions.
int The integer type represents a signed integer containing at least 16 bits. Decimal, hexadecimal, octal
float floating-point
bvec2 /3 /4 A vector that has 2/3 of the Boolean components
ivec2 / 3 / 4 A vector that contains 2/3 of the integral components
Mat2 or mat2x2 Floating-point matrix type of 2×2
Mat3 or mat3x3 3×3 floating-point matrix type
Mat4 or mat4x4 4×4 floating point matrix
mat2x3 Floating-point matrices with 2 columns and 3 rows (OpenGL matrices are columns in master order) and there are many types: 2 by 4, 2 columns and 4 rows
sampler1D / 2D / 3D Handle used to reference the specified 1D /2D / 3D texture in the built-in texture function. Can only be used as a consistent variable or function argument
samplerCube Handle to the Cube Map texture
sampler1DShadow / sampler2DShadow 1d / 2D depth texture handle

Example code:

Float a = 1.0;

int b=1; bool c=true; Vec2 d = vec2 (1.0, 2.0); Vec3 e = vec3 (1.0, 2.0, 3.0) vec4 f = vec4 (vec3, 1.0); Vec4 g = vec4 (0.2); / / equivalent to vec (0.2, 0.2, 0.2, 0.2) mat2 I = mat2 (0.1, 0.5, 1.2, 2.4); Mat2 j = mat2 (0.8); // Equivalent to MAT2 (0.8,0.8,0.8,0.8,0.8)

3.2 the operator

The GLSL language has similar operators to the Java language. The following table (operators in descending order of priority)

The operator describe
(a) For expression combinations, function calls, constructs
[] Array indices, vector or matrix selectors
. Member selection of structures and vectors
++ — The increment and decrement operator for a prefix or suffix
+ -! Unary operator that indicates positive or negative logical non
* / The multiplication and division operator
+ – The binary operators represent addition and subtraction
<> <= >= == != Less than, greater than, less than or equal to, greater than or equal to, equal to, not equal to
&& ^ ^ Logic and, or, xor
? : Conditional judge
= += – = *= /= The assignment operator

3.3 structure

Structures can combine basic types and arrays to form user-defined types. While defining a structure, you can define an instance of the structure. Or I’ll define it later.

struct surface {float indexOfRefraction; vec3 color; float turbulence; } mySurface; surface secondeSurface;Copy the code

You can assign a value to a structure using =, or using ==,! = to determine whether two structures are equal

The two structures are equal only if every component of the structure is equal. Access the internal members of the structure. (same as in Java).

The structure contains at least one member. Arrays of fixed size can also be contained in a structure. GLSL structures do not support nested definitions. Only pre-declared constructs can be nested inside.


struct myStruct {

  vec3 points[3]; // Arrays of fixed size are legal
  surface surf;  // Yes, it has been defined before
  
  struct velocity {  // Invalid float speed;
    vec3 direction;
  } velo;

  subSurface sub; 
  // Illegal, no prior declaration;
  struct subSurface { 
   int id;
  };
};
Copy the code

3.4 an array

You can only use one-dimensional arrays in GLSL. The type of an array can be any primitive type or structure. The following array declarations are legal:


surface mySurfaces[];
vec4 lightPositions[8];
vec4 lightPos[] = lightPositions;const int numSurfaces = 5;
surface myFiveSurfaces[numSurfaces];float[5] values;
Copy the code

An array specifying the size of the display can be used as an argument to a function or as a return value, or as a member of a structure. Array types have a built-in length() function that returns the length of the array.

vec4 myColor, ambient, diffuse[6], specular[6];

myColor = ambient + diffuse[4] + specular[4];
Copy the code

3.5 modifier

The modifier describe
const Constant values must be initialized when declared. It is read-only and cannot be modified.
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 and not inside the function. An attribute can be a floating point scalar, vector, or matrix. It cannot be an array or a structure
uniform Consistent variable. The value of a consistent variable is constant during shader execution. Unlike const, this value is unknown at compile time and is initialized externally to the shader. The consistent variable is shared between the vertex shader and the fragment shader. It can also only be declared at global scope.
varying The output of the vertex shader. Color or texture coordinates, for example, are used as read-only input to the fragment shader. Must be a global variable declared at global scope. It can be a float scalar, a vector, a matrix. Can’t be an array or a structure.
centorid varying In the absence of multiple samples, it has the same meaning as VARYING. In the case of multiple sampling, Centorid VARYING evaluates inside the rasterized figure rather than at a fixed position in the center of the fragment.
invariant (invariant) is used to represent the output of the vertex shader and the input of any matching fragment shader. The values generated by the calculation must be consistent across different shaders. All data flows and control flows in which invariant variables are written are consistent. In order for the compiler to ensure that the results are completely consistent, it is necessary to discard potential optimizations that might result in inconsistent values. Do not use this modifier unless absolutely necessary. Avoid z-fighting when it may be used in multi-channel renders.
in Used in a function argument to indicate that the parameter is input. Changing the value in the function does not affect the called function. (equivalent to C passvalues), this is the default modifier for function arguments
out Used as an argument to a function to indicate that the parameter is an output parameter whose value is subject to change.
inout Parameter used in a function to indicate that the parameter is either an input or an output parameter.

3.6 Built-in Variables

Built-in variables can interact with fixed function functions. No declaration is required before use. The built-in variables available for vertex shaders are shown in the following table:

The name of the type describe
gl_Color vec4 Input property – Represents the primary color of the vertex
gl_SecondaryColor vec4 Input property – represents the auxiliary color of the vertex
gl_Normal vec3 Input property – Represents the normal value of the vertex
gl_Vertex vec4 Input property – Represents vertex positions in object space
gl_MultiTexCoordn vec4 Input Property – Represents the coordinates of the NTH texture of the vertex
gl_FogCoord float Input property – Represents the fog coordinates of the vertices
gl_Position vec4 Output property – The position of the transformed vertices for subsequent fixed clipping operations. All vertex shaders must write this value.
gl_ClipVertex vec4 Output coordinates for clipping the user clipping plane
gl_PointSize float The size of the point
gl_FrontColor vec4 Output of the main color of the facade
gl_BackColor vec4 Output of the main color on the back
gl_FrontSecondaryColor vec4 Output of the auxiliary color of the front
gl_BackSecondaryColor vec4 The secondary color output on the back
gl_TexCoord [] vec4 Output of the array of texture coordinates
gl_FogFragCoord float Output of fog coordinates

The built-in variables for the fragment shader are as follows:

The name of the type describe
gl_Color vec4 Interpolated read-only input that contains the main color
gl_SecondaryColor vec4 Interpolated read-only input with auxiliary colors
gl_TexCoord[] vec4 Interpolated read-only input that contains an array of texture coordinates
gl_FogFragCoord float Interpolated read-only input that contains fog coordinates
gl_FragCoord vec4 Read-only input, window x,y,z and 1/ W
gl_FrontFacing bool Read-only input, or true if it is part of the front pane of the window
gl_PointCoord vec2 The 2-d coordinates of the point Sprite range from (0.0, 0.0) to (1.0, 1.0), and are only used when the point element and the point Sprite are on.
gl_FragData[] vec4 An array of data outputs using glDrawBuffers. Cannot be used in combination with gl_FragColor.
gl_FragColor vec4 The color of the output is used for subsequent pixel operations
gl_FragDepth float The depth of the output is used for subsequent pixel operations, and if this value is not written, the depth value of the fixed function pipeline is used instead

3.7 Constructors

Constructors can be used to initialize variables that contain multiple members, including arrays and structures. Constructors can also be used in expressions. The calling method is as follows:


vec3 myNormal = vec3(1.0.1.0.1.0);
greenTint = myColor + vec3(0.0.1.0.0.0);
ivec4 myColor = ivec4(255);
Copy the code

You can also use a mixture of scalars and vectors, as long as you have enough elements to fill the vector.


vec4 color = vec4(1.0, vec2(0.0.1.0), 1.0);
vec3 v = vec3(1.0.10.0.1.0);
vec3 v1 = vec3(v);
vec2 fv = vec2(5.0.6.0);
Copy the code

For matrices, matrices in OpenGL are column oriented. If only one value is passed, the diagonal matrix is constructed and the remaining elements are zeros.

Mat3 m3 = mat3 (1.0);Copy the code

The constructed matrix:

1.0 0.0 0.0

0.0 1.0 0.0

0.0 0.0 1.0

Mat2 Matrix1 = MAT2 (1.0, 0.0, 0.0, 1.0); Mat2 Matrix2 = MAT2 (Vec2 (1.0, 0.0), Vec2 (0.0, 1.0)); Mat2 matrix3 = mat2 (1.0); Mat2 matrix4 = mat2 (mat4 (2.0)); // It's going to take the 2x2 matrix in the top left corner of the 4x4 matrix.Copy the code

Constructors can be used for conversions of scalar data types. GLSL does not support implicit or explicit conversions, which can only be done through constructors. The int to float value is the same. When float is converted to int, the fractional part is discarded. Int or float is converted to bool, 0 and 0.0 to false, and the remaining values to true. Bool is converted to int or float, false to 0 and 0.0, and true to 1 and 1.0.

Float f = 1.7; int I = int(f); // I = 1Copy the code

To initialize an array, you can pass values in the constructor to initialize each corresponding value in the array.

Ivec2 position [3] = ivec2 [3] ((0, 0), (1, 1), (2, 2)); Ivec2 pos2[3] = ivec2[]((3,3), (2,1), (3,1));Copy the code

Constructors can also initialize structures. The order and type should correspond one to one.

struct surface {  
  int  index;
  vec3 color;  
  float rotate;
};

surface mySurface = surface(3, vec3(red, green, blue), 0.5);
Copy the code

3.8 the control flow

The process control in GLSL is basically the same as in Java, mainly include:

  1. If (){}else{} else{} if(){}else{}
  2. While () {} and do {} while ()
  3. for(;;) {}
  4. Break and continue

3.9 the function

There must be a main function in each shader. The void argument in main is optional, but is required when the return value is void.

Functions in GLSL must be defined and declared globally. You cannot declare or define a function in a function definition. The function must have a return type and the arguments are optional. Modifiers for arguments (in, out, inout, const, etc.) are optional

void main(void)
{
 ...
}
Copy the code

3.9.1 Common Functions

  1. Radians (x) : Angle radians
  2. Degrees (x) : The degree of rotation in radians
  3. Sin (x) : Sine function, passed in radians. The same goes for cosine cosine, tangent tangent, asin arc sine, acos arc cosine, an an arc tangent
  4. Pow (x, y) : xyxy
  5. Exp (x) : exex
  6. X2x exp2 (x) : 2
  7. The log (x) : logexlogex
  8. Log2 (x) : log2xlog2x
  9. SQRT (x) : x – x -)
  10. Inversesqr (x) : 1 x – 1 x -)
  11. Abs (x) : take the absolute value of x
  12. Sign (x) : x>0 returns 1.0, x<0 returns -1.0, otherwise 0.0 is returned
  13. Ceil (x) : returns an integer greater than or equal to x
  14. Floor (x) : returns an integer less than or equal to x
  15. Fract (x) : returns the value of x-floor(x)
  16. Mod (x,y) : mod(x,y) : mod(x,y)
  17. Min (x,y) : gets the smaller part of xy
  18. Max (x,y) : Get the larger of xy
  19. Mix (x,y,a) : Returns x∗(1−a)+y∗ax∗(1−a)+y∗a
  20. Step (x,a) : x< a returns 0.0, otherwise returns 1.0
  21. Smoothstep (x,y,a) : a < x returns 0.0,a >y returns 1.0, otherwise returns smooth Hermite interpolation between 0.0 and 1.0.
  22. DFdx (p) : the partial derivative of P in the x direction
  23. DFdy (p) : the partial derivative of P in the y direction
  24. Fwidth (p) : absolute sum of the partial derivatives of P in the x and y directions

3.9.2 Geometric functions

  1. Length (x) : Calculates the length of vector x
  2. Distance (x,y) : Returns the distance between the vector xy
  3. Dot (x,y) : Returns the dot product of the vector xy
  4. Cross (x,y) : returns the difference product of the vector xy
  5. Normalize (x) : Returns a vector of length 1 in the same direction as the x vector

3.9.3 Matrix functions

  1. MatrixCompMult (x,y) : Multiplies matrices
  2. LessThan (x, y) : returns the vector y each component performs x < y results, similar greaterThan, equal, notEqual
  3. LessThanEqual (x,y) : returns the result of x<= y for each component of the vector xy. Similarly, greaterThanEqual
  4. Any (bvec x) : true if one element of x is true
  5. All (bvec x) : x returns true if all elements are true, false otherwise
  6. Not (bvec x) : All components of X perform logical non-operations

3.9.4 Texture sampling function

Texture sampling functions include texture2D, texture2DProj, texture2DLod, texture2DProjLod, textureCube, textureCubeLod, texture3D, texture3DProj, and Texture3 DLod, texture3DProjLod, etc.

  1. Texture means texture sampling, 2D means 2D texture sampling and 3D means 3D texture sampling
  2. The Lod suffix applies only to vertex shader samples
  3. Proj means that the texture coordinate ST will be divided by q

Afterword.

The knowledge points of this article are mostly referred to the original article in the head, and more are recorded and summarized here.