WebGL can draw three basic shapes: points, lines, and triangles. All other shapes are assembled from these three basic shapes.
The following examples use the GLSL knowledge.
Shader code
- Gl_Position: built-in variable to set vertex coordinates.
- Gl_PointSize: Built-in variable used to set vertex size.
- Gl_FragColor: Built-in variable used to set pixel color.
- Gl_FragCoord: Built-in variable, slice coordinate, unit pixel
- Precision: Precision setting qualifier. After precision is set with this qualifier, the precision will be used for all subsequent data types unless set separately.
- Vec2:2-dimensional vector.
- Vec4: a 4-dimensional vector.
- Vector operations
- Vec2 (x, y) * 2.0 = vec(x * 2.0, y * 2.0).
- Vec2 * vec2: vec2(x1, y1) * vec2(x2, y2) = vec2(x1 * x2, y1 * y2).
- Attribute: Declare vertex – related data in a vertex shader.
- Uniform: Declare non-vertex data (such as light position data, direction data, matrix data) in shaders.
- Distance: Computes the distance between vertices.
- Discard: Discard a slice.
GLSL language in JS program – how to connect shader program
- CreateShader: Creates a shader object
- ShaderSource: provides shaderSource code
- CompileShader: Compiles shader objects
- CreateProgram: Create shader program
- AttachShader: Binds the shader object
- LinkProgram: link shader program
- UseProgram: Enables the shader program
How do YOU pass data to shaders in JS
- GetAttribLocation: Finds the shader
attribute
Variable address. - GetUniformLocation: Finds the shader
uniform
Variable address. - VertexAttrib2f:
attribute
The variable passes two floating point numbers. - Uniform4f:
uniform
The variable passes four floating point numbers.
Graphing function
- DrawArrays (type,start,count): Draw with the specified primitives.
type
There are mainly the following types.start
Specifies the point from which to draw.count
Specifies how many points will be used to draw.- Gl. POINTS: Draws a series of POINTS.
- Gl.line_strip: Draws a line. That is, draw a series of line segments with the top point connecting the next.
- Gl.line_loop: Draws a coil. That is, draw a series of line segments, with the top point joining the next, and the last point joining the first point.
- Gl.lines: Draws a series of individual line segments. Every two points serve as endpoints, and line segments are not connected.
- Gl. TRIANGLE_STRIP: Draw a triangle strip.
- Gl. TRIANGLE_FAN: Draw a triangle fan.
- TRIANGLES: Using a series of TRIANGLES. Every three points are the vertices.
1. Draw square point graph
<canvas id="canvas" width="500" height="500"></canvas>
Copy the code
Here is the shader language. It is usually written as a single js code. Of course, it can also be written as a string in JS code. The center of the square is 0.5,0.5, the upper left corner is the origin of the coordinates, and the lower right corner is 1.0,1.0,
- Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
// The position of the vertex
gl_Position = vec4(0.0.0.0.0.0.1.0);
// The pixel size of the vertex
gl_PointSize = 40.0;
}
</script>
Copy the code
- Chip shader
<script type="shader-source" id="fragmentShader">
// The data type is low precision floating point
precision lowp float;
void main(){
// Sets the color of the chip shader
gl_FragColor = vec4(1.0.0.0.0.0.1.0);
}
</script>
Copy the code
javascript
Code section
/ / get the canvas
let canvas = document.getElementById('canvas');
// Get the drawing context
let gl = canvas.getContext('webgl');
// Create a shader program
initShader(gl);
// Set the clear color to black.
gl.clearColor(0.0.0.1.0);
/ / clear screen
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw a point.
gl.drawArrays(gl.POINTS, 0.1);
// Declare the initialization shader function
function initShader(gl){
// Create a fixed-point shader
const vertexShaderSource = document.querySelector('#vertexShader').innerText;
// Create a slice shader
const fragmentShaderSource = document.querySelector('#fragmentShader').innerText;
// Create a vertex shader object
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
// Create a slice shader object
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
// Introduce vertex, slice shader source code
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
// Build vertex and slice shaders
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
// Create program object program
const program = gl.createProgram();
// Attach vertex shaders and slice shaders to program
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
/ / link to the program
gl.linkProgram(program);
/ / using the program
gl.useProgram(program);
// Return program object
return program;
}
Copy the code
2. Draw circular point graph
The dots are drawn using two built-in functions distance and discard. Distance is used to calculate the distance between two vertex coordinates. The discard function is used to discard unwanted slices.
- Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
// The position of the vertex
gl_Position = vec4(0.0.0.0.0.0.1.0);
// The pixel size of the vertex
gl_PointSize = 40.0;
}
</script>
Copy the code
- Chip shader
<script type="shader-source" id="fragmentShader">
// The data type is low precision floating point
precision lowp float;
void main(){
//gl_PointCoord is a built-in variable that indicates that the maximum value of gl_PointCoord is (1.0,1.0)
//gl_FragColor is also a built-in variable that represents the color value of the pixel corresponding to the vertex coordinates
// Calculate the distance between the vertex coordinates and the specified point (0.5,0.5),
float r = distance(gl_PointCoord, vec2(0.5.0.5));
// Set the chip according to the distance
if(r < 0.5) {// The radius of the square area is less than 0.5 from the geometric center, and the pixel color is set to red
gl_FragColor = vec4(1.0.0.0.0.0.1.0);
}else {
// Drop the segment clipping if the radius of the square area is greater than or equal to 0.5 from the geometric center:
discard;
}
}
</script>
Copy the code
javascript
Code section
This part of the code is the same as drawing the square point graph.
Here is a comparison of images cropped to a circle using gl_pointCoord and an uncropped square.
3. Dynamically draw points
Add points dynamically by user’s click.
- Vertex shader
<script type="shader-source" id="vertexShader">
// Float is set to medium precision
precision mediump float;
// Accept the coordinates (X, Y) of the point passed by JavaScript.
attribute vec2 a_Position;
// Accept the canvas size.
attribute vec2 a_Screen_Size;
void main(){
// Convert the canvas coordinate value to the range of [-1.0, 1.0].
vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
// Canvas's Y coordinate is opposite to the device coordinate.
position = position * vec2(1.0, -1.0);
// Final vertex coordinates.
gl_Position = vec4(position, 0.0.1.0);
// The size of the dot.
gl_PointSize = 10.0;
}
</script>
Copy the code
- Chip shader
<script type="shader-source" id="fragmentShader">
// Float is set to medium precision
precision mediump float;
// a global variable to receive colors from JavaScript.
uniform vec4 u_Color;
void main(){
// Process the colors to the GLSL range [0, 1].
vec4 color = u_Color / vec4(255.255.255.1);
gl_FragColor = color;
}
</script>
Copy the code
javascript
Code section
/ / get the canvas
let canvas = document.getElementById('canvas');
// Get the drawing context
let gl = canvas.getContext('webgl');
// Create a shader program
let program = initShader(gl);
// Gets the position of the variable a_Position in the vertex shader.
let a_Position = gl.getAttribLocation(program, 'a_Position');
// Gets the position of the variable a_Screen_Size in the vertex shader.
let a_Screen_Size = gl.getAttribLocation(program, 'a_Screen_Size');
// Get the position of the variable u_Color in the slice shader.
let u_Color = gl.getUniformLocation(program, 'u_Color');
// Pass the canvas size information to the vertex shader's a_Screen_Size.
gl.vertexAttrib2f(a_Screen_Size, canvas.width, canvas.height);
// Declare the initialization shader function
function initShader(gl){
// Create a fixed-point shader
const vertexShaderSource = document.querySelector('#vertexShader').innerText;
// Create a slice shader
const fragmentShaderSource = document.querySelector('#fragmentShader').innerText;
// Create a vertex shader object
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
// Create a slice shader object
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
// Introduce vertex, slice shader source code
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
// Build vertex and slice shaders
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
// Create program object program
const program = gl.createProgram();
// Attach vertex shaders and slice shaders to program
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
/ / link to the program
gl.linkProgram(program);
/ / using the program
gl.useProgram(program);
// Return program object
return program;
}
// The container that stores the vertex information of the area
let points = [];
canvas.addEventListener('click'.e= > {
let x = e.pageX;
let y = e.pageY;
let color = randomColor();
// Store the coordinates and colors of the new point.
points.push({ x: x, y: y, color: color })
render(gl);
})
// Draw the function
function render(gl) {
// Clear the screen
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < points.length; i++) {
let color = points[i].color;
// Pass color information to the slice shader
gl.uniform4f(u_Color, color.r, color.g, color.b, color.a);
Pass coordinate information to the vertex shader.
gl.vertexAttrib2f(a_Position, points[i].x, points[i].y);
// Draw points.
gl.drawArrays(gl.POINTS, 0.1); }}var random = Math.random;
function randomColor() {
return {
r: random() * 255.g: random() * 255.b: random() * 255.a: random() * 1
};
}
// Set the screen clear color to black.
gl.clearColor(0.0.0.1.0);
/ / to draw
render(gl);
Copy the code
4, gradient
- Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
gl_Position = vec4(0.0.0.0.0.0.1.0);
gl_PointSize = 100.0;
}
</script>
Copy the code
- Chip shader
<script type="shader-source" id="fragmentShader">
void main(){
// Set the pixel value of the slice according to the x coordinate of the slice
// The element is gradually changed along the x direction
gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0.0.0.0.0.1.0);
}
</script>
Copy the code
javascript
Code section This section of code is the same as the code used to draw the square point graph.
5. Color partitioning
- Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
gl_Position = vec4(0.0.0.0.0.0.1.0);
gl_PointSize = 200.0;
}
</script>
Copy the code
- Chip shader
<script type="shader-source" id="fragmentShader">
void main(){
// Set the pixel value of the slice according to the x coordinate of the slice
if(gl_FragCoord.x < 200.0) {// Defaults to the original canvas color
}
else if (gl_FragCoord.x < 250.0) {
// canvas set the pixel value between [0,300) on the canvas
gl_FragColor = vec4(1.0.0.0.0.0.1.0);
} else if (gl_FragCoord.x <= 300.0) {
// canvas Pixel values between (300,400) are set to green
gl_FragColor = vec4(0.0.1.0.0.0.1.0);
} else {
// Canvas Pixel values between (400,500) are set to blue
gl_FragColor = vec4(0.0.0.0.1.0.1.0);
}
}
</script>
Copy the code
javascript
Code section This section of code is the same as the code used to draw the square point graph.
reference
WebGL Zero Basic Tutorial (Guo Longbang); Introduction to WebGL and practice