Webgl and threejs

WebGL is a 3D drawing standard, which allows the combination of JavaScript and OpenGL ES 2.0. By adding a JavaScript binding of OpenGL ES 2.0, WebGL can provide hardware 3D accelerated rendering for HTML5 Canvas. This allows Web developers to display 3D scenes and models more smoothly in the browser with the help of the system graphics card, and to create complex navigation and data visualizations.

Threejs is an open source mainstream 3D drawing JS engine (Three means 3D). Threejs encapsulates WebGL, making it easier to create 3D applications. The framework has a lot of built-in tools, such as model loader, support obJ, FBX, and other general model formats. It also provides mouse controls such as zooming, zooming and so on.

While threejs is a quick way to create 3D applications, it doesn’t have much insight into the underlying WebGL code. Not to mention WebGL’s father, OpenGL.

Now I’m going to draw a rectangle using WebGL

The final result

Create a Canvas

<canvas id="box" width=300 height=300></canvas>
Copy the code

// Get the Canvas DOM object
const canvas = document.getElementById('box')

// Get the context to draw the WebGL, and then we can use the webGL object to create a 3D application
const webgl = canvas.getContext('webgl')
Copy the code
Prepare the coordinates of the rectangle to be drawn// v1--------v0
// | |
// | |
// | |
// v2--------v3
// The correction square consists of four points
let jsArrayData = new Float32Array([
  // x y z
  -0.5, +0.5.0.0.// v1
  +0.5, +0.5.0.0.// v0
  +0.5, -0.5.0.0.// v3
  -0.5, -0.5.0.0.// v2
])

// Form a square by drawing two triangles. The numbers in the array below represent the indexes in jsArrayData.
// 0 indicates -0.5, 2 indicates 0.0
// 0, 1, 2 means to draw a triangle with these three points
let indexDatas = [      
    0.1.2.0.2.3    
]
Copy the code

Bind square vertices and triangle vertex indexes to WebGL

// Create a vertex buffer
triangleBuffer = webgl.createBuffer()
// Specify the type of buffer
// webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
// // Allocating memory
// webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW)
webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
// Allocate memory
webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW)

// Create index buffer
indexBuffer = webgl.createBuffer()
// Specify the type of buffer
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer)
// Allocate memory
webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexDatas), webgl.STATIC_DRAW)
// Use a buffer to specify the vertex data to draw from
webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer)

Copy the code

Pass the vertex data to the shader

// Bind the v3PositionIndex variable to v3Position in the vertex shader
webgl.bindAttribLocation(programObject, v3PositionIndex, 'v3Position')
    
/ / enable v3PositionIndex
webgl.enableVertexAttribArray(v3PositionIndex)    
// 3 indicates that each vertex has three data points (x, y, z)
// 4 * 3 represents the number of bytes in memory used by all vertices, 4 represents the number of bytes used by a vertex, and 3 represents the number of bytes used by a vertex
// 0 indicates that data is fetched from the 0th element
webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false.4 * 3.0)

Copy the code

Bind vertex shaders and slice shaders

/ / create a shader
vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER)
fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER)

webgl.shaderSource(vertexShaderObject, ` attribute vec3 v3Position; Void main(void) {gl_Position = vec4(v3Position, 1.0); } `)

webgl.shaderSource(fragmentShaderObject, ` precision lowp float; Void main(void) {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `)

/ / compile a shader
webgl.compileShader(vertexShaderObject)
webgl.compileShader(fragmentShaderObject) 
Copy the code

Bind shaders and vertex data to WebGL

// Create an empty program
programObject = webgl.createProgram()    
// Bind vertex shaders and slice shaders
webgl.attachShader(programObject, vertexShaderObject)    
webgl.attachShader(programObject, fragmentShaderObject)    
// Bind the v3PositionIndex variable to v3Position in the vertex shader
webgl.bindAttribLocation(programObject, v3PositionIndex, 'v3Position')    
// Execute the connection, this program is no longer empty
webgl.linkProgram(programObject)    
// Use this program
webgl.useProgram(programObject)
Copy the code

Perform rendering

// Set the color of the repainted background
webgl.clearColor(0.0.0.0.0.0.1.0)
// Clear the background
webgl.clear(webgl.COLOR_BUFFER_BIT)    
// The index on both sides has a total of 6 data
webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_SHORT, 0)
Copy the code

The total code


<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>WebGL</title>
</head>

<body>

  <canvas id="box" style="border: 1px solid black;" width=300 height=300></canvas>

  <script>
    let vertexShaderObject = null
    let fragmentShaderObject = null
    let programObject = null
    let indexBuffer = null
    let v3PositionIndex = 0
    let uniformColor

    // 1 Create context
    const canvas = document.getElementById('box')
    const webgl = canvas.getContext('webgl')

    webgl.viewport(0.0, canvas.clientWidth, canvas.clientHeight)

    // 2 Create shader
    vertexShaderObject = webgl.createShader(webgl.VERTEX_SHADER)
    fragmentShaderObject = webgl.createShader(webgl.FRAGMENT_SHADER)

    webgl.shaderSource(vertexShaderObject, ` attribute vec3 v3Position; Void main(void) {gl_Position = vec4(v3Position, 1.0); } `)

    webgl.shaderSource(fragmentShaderObject, ` precision lowp float; Void main(void) {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `)

    // 3 Compile shader
    webgl.compileShader(vertexShaderObject)
    webgl.compileShader(fragmentShaderObject)

    if(! webgl.getShaderParameter(vertexShaderObject, webgl.COMPILE_STATUS)) {console.log('err---vertexShaderObject', webgl.getShaderInfoLog(vertexShaderObject))
    }

    if(! webgl.getShaderParameter(fragmentShaderObject, webgl.COMPILE_STATUS)) {console.log('err---fragmentShaderObject', webgl.getShaderInfoLog(fragmentShaderObject))
    }


    // Create an empty program
    programObject = webgl.createProgram()

    // Bind vertex shaders and slice shaders
    webgl.attachShader(programObject, vertexShaderObject)
    webgl.attachShader(programObject, fragmentShaderObject)

    // Bind the v3PositionIndex variable to v3Position in the vertex shader
    webgl.bindAttribLocation(programObject, v3PositionIndex, 'v3Position')

    // Execute the connection, this program is no longer empty
    webgl.linkProgram(programObject)

    // Use this program
    webgl.useProgram(programObject)


    // v1--------v0
    // | |
    // | |
    // | |
    // v2--------v3

    let jsArrayData = new Float32Array([
      // x y z
      -0.5, +0.5.0.0.// v1
      +0.5, +0.5.0.0.// v0
      +0.5, -0.5.0.0.// v3
      -0.5, -0.5.0.0.// v2
    ])

    let indexDatas = [
      0.1.2.0.2.3
    ]

    // Create a vertex buffer

    triangleBuffer = webgl.createBuffer()
    // Specify the type of buffer
    // webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
    // // Allocating memory
    // webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW)
    webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
    // Allocate memory
    webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(jsArrayData), webgl.STATIC_DRAW)



    // Create index buffer
    indexBuffer = webgl.createBuffer()
    // Specify the type of buffer
    webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer)
    // Allocate memory
    webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexDatas), webgl.STATIC_DRAW)
    // Use a buffer to specify the vertex data to draw from
    webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer)



    webgl.enableVertexAttribArray(v3PositionIndex)

    // Specifies the data to draw the vertex
    // v3PositionIndex binds the v3Position in the shader
    // 3 Each vertex consists of 3 bytes, and each vertex is offset by 3 bytes
    // 4*3 4 is the number of bytes in a float, and 6 means that each vertex has 6 data, which means that every 24 bytes to the next vertex
    // 0 is taken backwards from the 0th buffer
    webgl.vertexAttribPointer(v3PositionIndex, 3, webgl.FLOAT, false.4 * 3.0)

    // Set the color of the repainted background
    webgl.clearColor(0.0.0.0.0.0.1.0)
    // Perform the drawing
    webgl.clear(webgl.COLOR_BUFFER_BIT)

    // The index on both sides has a total of 6 data
    webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_SHORT, 0)

  </script>

</body>

</html>

Copy the code

Share my possession of TS tutorials, from zero to high order all series, click a link, 0 RMB for www.yidengxuetang.com/pub-page/in…