2.3 Shaders

Shader

The shader is written in a C-like language called GLSL. GLSL is tailored for graphics calculations, and it contains some useful features for vector and matrix operations.

Always declare the version at the beginning of the shader, followed by input and output variables, uniform and main functions. The entry point of each shader is the main function, in this function we process all the input variables and output the results to the output variables.

A typical shader written in GLSL has the following structure.

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

int main()
{
  // 处理输入并进行一些图形操作
  ...
  // 输出处理过的结果到输出变量
  out_variable_name = weird_stuff_we_processed;
}

When it comes to vertex shaders, each input variable is also called a vertex attribute. There is an upper limit on the vertex attributes we can declare, which is determined by the hardware.

type of data

Basic type

GLSL contains most basic default data type, and other C language: int, float, double, uintand bool.

GLSL also has two container types, which will be used a lot in this tutorial, namely Vector and Matrix

vector

The vector in GLSL is a container that can contain 1, 2, 3, and 4 components. The type of the component can be one of the previous default basic types.

Types of meaning
vecn nA default vector containing float components
bvecn nA vector containing bool components
ivecn nA vector containing int components
uvecn nA vector containing an unsigned int component
dvecn nA vector containing a double component

Four components of a vector may be used .x, .y, .zand .wto obtain.

Vectors also allow a flexible way of component selection, called reassembly.

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

You can use a vector as a parameter to pass to different vector constructors to reduce the number of parameters.

vec2 vect = vec2(0.5, 0.7);
vec4 result = vec4(vect, 0.0, 0.0);
vec4 otherResult = vec4(result.xyz, 1.0);

input Output

Each shader communicates and transmits data with each other through input and output. Use inand outto identify input and output variables . Each shader uses these two keywords to set the input and output. As long as an output variable matches the input of the next shader stage, it will be passed on.

The vertex shader can receive input directly from the vertex data. In order to define how vertex data should be managed, we use locationto specify input variables to configure vertex attributes on the CPU.

The fragment shader needs a vec4color output variable.

So, if we intend to send data from one shader to another, we must declare an output in the sender shader and a similar input in the receiver shader. When the type and name are the same, OpenGL will link the two variables together, and data can be sent between them.

Uniform

Uniform is a way to send data from an application in the CPU to a shader in the GPU, but uniform and vertex attributes are somewhat different.

Uniform is global (Global). Global means that the uniform variable must be unique in each shader program object, and it can be accessed by any shader of the shader program at any stage.

No matter what you set the uniform value to, the uniform will keep their data until they are reset or updated.

Querying the uniform address does not require you to have used the shader program before, but you must use the program before updating a uniform, because it sets the uniform in the currently active shader program.

Guess you like

Origin blog.csdn.net/NelsonCheung/article/details/109398342