“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

This is the beginning of the interpretation of the source code of Three.js. In this series of articles, the author tries to use the most vivid metaphor and the most appropriate illustration to make readers learn to draw a fantastic 3D world with WebGL.

WebGLRenderer

WebGLRenderer is a class that Three. Js encapsulates the WebGL rendering pipeline, that is, how WebGL renders a 3D interface. The file structure of the code is as follows:

Two conclusions can be drawn from the figure above:

  • Shaders are used to store shader code.
  • The WebGL folder is used to store JS control code.

Webgl renders a 3D world with JS control code and shader code.

An example of the js control code is as follows:

var program = gl.createProgram();
// Add a pre-existing shader
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
Copy the code

Example shader code is as follows:

export const vertex = /* glsl */` varying vec2 vUv; uniform mat3 uvTransform; void main() { vUv = ( uvTransform * vec3( uv, 1 ) ).xy; Gl_Position = vec4(position.xy, 1.0, 1.0); } `;

export const fragment = /* glsl */` uniform sampler2D t2D; varying vec2 vUv; void main() { vec4 texColor = texture2D( t2D, vUv ); gl_FragColor = mapTexelToLinear( texColor ); #include 
      
        #include 
       
         };
       
      Copy the code

For starters, it doesn’t matter if the js control code and shader code above are a little strange. In this source code series, I will try to use the most vivid metaphor to help you understand the technical principles of WebGL and the philosophy of Three.js.

What is WebGLProgram?

Those of you who already know what WebGLProgram is can skip this section and go straight to the source code analysis.

WebGLProgram is part of the WebGL API and consists of two WebGLShaders, a vertex shader and a slice shader (both are written in GLSL).

There are several steps in the process of using a shader program, including telling the GPU to use the shader program, binding the appropriate data buffer, configuring the options, and finally drawing the image to the screen.

If the 3D world is created by a painter, WebGLProgram is just like the brush in the painter’s hand. The Web RenderingContext is the painter’s hand, and the GPU is the painter’s brain.

The painter (GPU) has the data of how to draw the 3D world, and manipulates the brush (WebGLProgram) to draw the 3D world by hand (WebGLRenderingContext). The brush can be dipped in different colors and adjusted to different thicknesses to draw the 3D world.

WebGLRenderContext provides four methods to manipulate WebGLProgram.

  1. CreateProgram, create a shader program.
  2. LinkProgram binds the shader program to the rendering context.
  3. IsProgram is a program object.
  4. DeleteProgram, frees the shader’s memory.

Once the painter has configured his brush, he can begin to work by using his hands to invoke the different functions of the brush.

Webgl itself provides the class WebGLProgram, and three.js further encapsulates WebGLProgram. The following code is the encapsulation of WebGLProgram by three.js. Readers can first understand by themselves, or directly jump to the source code interpretation interface:

function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {}
Copy the code

three.jsIn theWebGLProgramThe arguments

  1. Renderer,WebGLRenderer instance.
  2. CacheKey, a cacheKey, presumably for performance optimization.
  3. Parameters are used to create programs such as vertex data, shader data.
  4. BindingStates, binding state, the current program has drawn what interface required data state.

renderer

const gl = renderer.getContext();
Copy the code

The function of the renderer here is to get the render context instance of this renderer.

cacheKey

No action is currently found in the constructor.

parameters

Contains vertex shader code and slice shader code, as well as the specific content configuration of shader code to generate shader code.

Specific content configuration is too much, we pick out a few to explain.

Version information for WebGL

const customExtensions = parameters.isWebGL2 ? ' ' : generateExtensions( parameters );
Copy the code

Webgl2 uses OpenGL ES 3.0 and WebGL uses OpenGL ES 2.0.

OpenGL ES 3.0 ‘introduces more new features.

  1. Optimize performance
  2. Unified texture format ETC.
  3. Support for more powerful features such as rendering multiple textures.

Shader language version information

The shader language, like the JS language, is constantly iterating versions.

	let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : ' ';
Copy the code

For example, if you want to use version 300 of the GLSL language, you can declare this at the beginning of the shader code:

#version 300 es
Copy the code

If you want to check the version of GLSL supported by your browser, you can do the following:

gl.getParameter(gl.SHADING_LANGUAGE_VERSION);
Copy the code

Define the role of

parameters.instancing ? '#define USE_INSTANCING' : ' ',
#define USE_INSTANCING
'#ifdef USE_INSTANCING'.'attribute mat4 instanceMatrix; '.Copy the code

From the above code, you can see that the code configuration parameter is used to dynamically generate the shader code snippet.

Shader code configuration parameters are a detailed description of the syntax of the GLSL shader language. By understanding the meaning of each parameter, you will be able to delve into more details of the GLSL language and graphics.

bindingStates

Instance of WebGLBindingStates. WebGLBindingStates is a class wrapped in three.js.

The WebGLProgram constructor returns the value

	this.usedTimes = 1;
	this.program = program;
	this.vertexShader = glVertexShader;
	this.fragmentShader = glFragmentShader;

	return this;
Copy the code

Mount the shader program object and the vertex shader and slice shader objects that the shader program object contains.

After looking at the encapsulation of WebGLProgram by three.js, I would like to say that the API documentation originally came out like this.

More details readers can go to read the source of WebGLProgram, thank you for your reading!