primers
JavaScript WebGL base confusion after some optimization, then try to draw common two-dimensional faces.
Geometry in WebGL is ultimately made up of triangles, which is more appropriate to cut in.
-
My GitHub
Draw a triangle
Here is an example, based on drawing a line the main changes are:
-
The vertices
-
Drawing primitives
The vertices
A triangle has three vertices. In the basic puzzle point, I know that the coordinate system is the right hand coordinate system. I am used to describing the sequence of vertices from the center of the graph as the origin, from the first quadrant to the fourth quadrant.
let vertices = [
0.5.0.5.0.0.// First quadrant
-0.5.0.5.0.0.// Second quadrant
-0.5, -0.5.0.0.// Third quadrant
]; / / triangle
Copy the code
Drawing primitives
So this time, using a face, the drawing mode in drawArrays is changed to Gl.Triangles. Take a look at some patterns of primitives.
-
Gl. POINTS: Draws a series of POINTS.
-
Gl.lines: Draws a series of separate line segments, with two points as endpoints and no connection between the segments. For example, if you have vertices A, B, C, D, E, and F, you get three line segments.
- Gl.line_strip: Draws a series of line segments with the top point connecting the next.
- Gl.line_loop: Draws a series of line segments, the top point connecting to the next point, and the last point connecting to the first point.
- TRIANGLES: Using a series of TRIANGLES, using three points as vertices. For example, if there are six vertices A, B, C, D, E, and F, two triangles will be drawn: ABC and DEF.
- Gl. TRIANGLE_STRIP: Used to draw triangles with shared sides. Starting with the second triangle, read one vertex at a time, and form a triangle using the previous two trailing vertices, and so on. For example, if there are six vertices A, B, C, D, E, F, four triangles will be drawn: ABC and BCD and CDE and DEF.
- Gl. TRIANGLE_FAN: Draw triangles with shared edges. Starting with the second triangle, read one vertex at a time, and form a triangle using the first vertex and the last vertex before it, and so on. For example, if there are six vertices A, B, C, D, E, F, four triangles will be drawn: ABC and ACD and ADE and AEF.
Implementation process
Here is a visualization of the execution process of drawing triangles, combined with a look to help deepen understanding.
Hd processing
In the example above, there is obvious blur and jagging on an HD screen, but it is a little different from dealing with blur in a 2D context. The main difference is that WebGL requires viewPort methods to specify mapping transformations from standard devices to window coordinates. Details can be found in this article.
This is the HD example.
function WebGLHD(w = 300, h = 150) {
const ratio = window.devicePixelRatio || 1;
const canvas = document.createElement("canvas");
const context = canvas.getContext("webgl");
// Handle hd screen blur
canvas.width = w * ratio; // Actual render pixels
canvas.height = h * ratio; // Actual render pixels
canvas.style.width = `${w}px`; // Control the display size
canvas.style.height = `${h}px`; // Control the display size
context.viewport(0.0, context.canvas.width, context.canvas.height);
}
Copy the code
Draw a rectangle
As mentioned above, geometry in WebGL is ultimately composed of triangles, which need to be decomposed into multiple triangles when drawing polygons.
Here is an example where a rectangle can be divided into two triangles:
let vertices = [
0.5.0.5.0.0,
-0.5.0.5.0.0,
-0.5, -0.5.0.0.// The first triangle
-0.5, -0.5.0.0.0.5, -0.5.0.0.0.5.0.5.0.0.// The second triangle
]; / / rectangle
Copy the code
If one edge is found to be common, the buffer object can be indexed to reduce redundant data.
Index buffer object
The full name of an Index Buffer Object is Index Buffer Object (IBO), which uses indexes to reuse existing data.
Based on the square example above, the main changes are as follows:
-
data
-
The buffer
-
draw
data
Only four vertex positions are needed, and the public data is indexed instead.
const vertices = [
0.5.0.5.0.0.// first vertex
-0.5.0.5.0.0.// second vertex
-0.5, -0.5.0.0.// the third vertex
0.5, -0.5.0.0.// the fourth vertex
]; / / rectangle
Copy the code
The index data is related to the primitive drawing mode indicated above.
Using the TRIANGLES mode of Gl. TRIANGLES are independent, with the following indexed data:
const indexData = [
0.1.2.// The index of vertex 1, 2, and 3 in the corresponding vertex position data
0.2.3.// The index of vertex 1, 3, and 4 in the corresponding vertex position data
]
Copy the code
Construct a triangle using the two vertices at the end of the previous triangle when drawing mode is GL. TRIANGLE_STRIP:
const indexData = [
1.0.2.3 // Select * from index 1, 0, 2 to draw the first triangle, and then select * from index 0, 2, 3 to draw the second triangle
]
Copy the code
When drawing in gl.TRIANGLE_FAN, construct a triangle using the first vertex and the vertex at the end of the previous triangle, plus the newly read vertex:
const indexData = [
0.1.2.3 // Select * from index 0, 1, 2 to draw the first triangle, and then select * from index 0, 2, 3 to draw the second triangle
]
Copy the code
The buffer
The indexed data needs to be buffered to the corresponding variables before it can be used.
/** * buffer index data *@param {*} Gl WebGL context *@param {*} Data Index data */
function setIndexBuffers(gl, data) {
// Create a blank buffer object
const buffer = gl.createBuffer();
// Bind the target
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
// WebGL does not support using JavaScript primitive array types directly
const dataFormat = new Uint16Array(data);
// Initialize the data store
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, dataFormat, gl.STATIC_DRAW);
}
Copy the code
draw
The index buffer object is used and drawElements method is needed instead of drawArrays. This method takes a type parameter, which refers to the type of the index buffer data, with the following values:
-
gl.UNSIGNED_BYTE
-
gl.UNSIGNED_SHORT
The previous buffered-index data type is converted to Uint16Array, where gl.unsigned_short should be used.
The three methods are as follows:
-
TRIANGLE_STRIP sample
-
TRIANGLE_FAN sample
The resources
-
WebGL lessons
-
Hello, triangle
-
WebGL 1.0 official index card
Recently, I saw a work “Deli Lili’s Fantasy Paris”, in which the costumes of the characters are gorgeous and distinctive, and the scene architecture is exquisite.
The story expresses a positive attitude, but most of the people you meet in the plot are either rich or wealthy, which is a bit magical.