2024年全网最新最详细《WebGL教程》

2024年全网最新最详细《WebGL教程》

https://www.bilibili.com/video/BV1AS411A74T/

1 2

02-canvas的基础知识

https://bx2eq6ulg18.feishu.cn/docx/I4hTdO95qozPBOxauPlcbDfInVd

2.1 获取渲染上下文
HTMLCanvasElement.getContext()方法用于返回绘图上下文对象,绘图上下文对象是2D上下文还是3D上下文取决于传入的参数。
getContext('2d'):创建一个CanvasRenderingContext2D 二维的渲染上下文对象getContext('webgl'):创建一个 WebGLRenderingContext 三维的渲染上下文对象

css图片会拉伸 标签属性width不会

03-了解类型化数组

作用:常用在处理图像数据、音频数据、视频数据这些方向。对应的API有:WebGL、Canvas API、WebRTC、File

04-着色器基础语法

GLSL(OpenGL Shading Language)是一种用于编写图形着色器的编程语言。着色器是用于在图形处理单元
(GPU)上执行特定图形处理任务的程序。通俗讲,着色器是画点的工具,一个图形是由无数个点组成的,每个点都有其自己的颜色。

变量修饰符:
用于指定变量的作用域、生命周期和用途。不同的修饰符在顶点着色器和片段着色器中起到不同的作用。
attribute:用于顶点着色器,定义从顶点缓冲区传入的变量(仅在顶点着色器中使用)。
uniform:定义在整个渲染过程中保持不变的变量,常用于传递变换矩阵、光照参数等。
varying:用于在顶点着色器和片段着色器之间传递插值数据。
内罟变量:

05-webGL接口api

06-第一个WebGL程序

另类script 需要加;才行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        void main(){
            gl_PointSize=10.0;
            gl_Position=vec4(0.0,0.0,0.0,1.0);
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        // const vertexSource=`
        //     void main(){
        //         gl_PointSize=10.0;
        //         gl_Position=vec4(0.0,0.0,0.0,1.0)
        //     }
        // `
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);
        gl.drawArrays(gl.POINTS, 0, 1);
     </script>
</body>
</html>

07-attribute动态传递点数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPos;
        attribute vec2 aPos1;
        void main(){
            gl_PointSize=10.0;
            vec2 newPos=aPos+aPos1;
            gl_Position=vec4(newPos,0.0,1.0);
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        // const vertexSource=`
        //     void main(){
        //         gl_PointSize=10.0;
        //         gl_Position=vec4(0.0,0.0,0.0,1.0)
        //     }
        // `
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        //动态传数据 坐标
        const posLocation=gl.getAttribLocation(program, 'aPos')
        const posLocation1=gl.getAttribLocation(program, 'aPos1')
        const offset=[0.5,0.5]
        const offset1=[-0.1,-0.2]
        gl.vertexAttrib2f(posLocation,...offset)
        gl.vertexAttrib2f(posLocation1,...offset1)

        gl.drawArrays(gl.POINTS, 0, 1);
     </script>
</body>
</html>

08-使用缓冲区数据绘制线段

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        void main(){
            gl_Position=vec4(aPosition,0.0,1.0);
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,-0.5,  //第一个点的x轴和y轴坐标
            0.5,0.5,    //第二个点的xy轴坐标
        ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        gl.drawArrays(gl.LINES, 0, 2);
     </script>
</body>
</html>

09-varying实现彩色线段

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        attribute vec4 aColor;
        varying vec4 vColor;
        void main(){
            gl_Position=vec4(aPosition,0.0,1.0);
            vColor=aColor;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision highp float;
        varying vec4 vColor;
        void main(){
            gl_FragColor=vColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,-0.5,  //第一个点的x轴和y轴坐标
            0.5,0.5,    //第二个点的xy轴坐标
        ])
        const colors=new Float32Array([
            0.0,0.0,0.0,1.0,
            1.0,0.0,0.0,0.0,
        ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        const colorBuffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)
        const colorLocation=gl.getAttribLocation(program, 'aColor')
        gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(colorLocation)

        gl.drawArrays(gl.LINES, 0, 2);
     </script>
</body>
</html>

10-如何使用单个buffer解析数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        attribute vec4 aColor;
        varying vec4 vColor;
        void main(){
            gl_Position=vec4(aPosition,0.0,1.0);
            vColor=aColor;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision highp float;
        varying vec4 vColor;
        void main(){
            gl_FragColor=vColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,-0.5, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标
            0.5,0.5, 1.0,0.0,0.0,0.0,    //第二个点的xy轴坐标
        ])
        // const colors=new Float32Array([
        //     0.0,0.0,0.0,1.0,
        //     1.0,0.0,0.0,0.0,
        // ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        // const colorBuffer=gl.createBuffer()
        // gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
        // gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)
        const colorLocation=gl.getAttribLocation(program, 'aColor')
        gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)
        gl.enableVertexAttribArray(colorLocation)

        gl.drawArrays(gl.LINES, 0, 2);
     </script>
</body>
</html>

11-绘制三角形案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        attribute vec4 aColor;
        varying vec4 vColor;
        void main(){
            gl_Position=vec4(aPosition,0.0,1.0);
            vColor=aColor;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision highp float;
        varying vec4 vColor;
        void main(){
            gl_FragColor=vColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,-0.5, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标 前2坐标 后4颜色
            0.5,-0.5, 1.0,0.0,0.0,0.0,    //第二个点的xy轴坐标
            0.0,0.5, 0.0,0.0,1.0,0.0,  //3 point
        ])
        // const colors=new Float32Array([
        //     0.0,0.0,0.0,1.0,
        //     1.0,0.0,0.0,0.0,
        // ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        // const colorBuffer=gl.createBuffer()
        // gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
        // gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)
        const colorLocation=gl.getAttribLocation(program, 'aColor')
        gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)
        gl.enableVertexAttribArray(colorLocation)

        gl.drawArrays(gl.TRIANGLES, 0, 3);
     </script>
</body>
</html>

12-图元绘制类型详解

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        attribute vec4 aColor;
        varying vec4 vColor;
        void main(){
            gl_Position=vec4(aPosition,0.0,1.0);
            gl_PointSize=10.0;
            vColor=aColor;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision highp float;
        varying vec4 vColor;
        void main(){
            gl_FragColor=vColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -1.0,1.0, 0.0,0.0,0.0,1.0, //第一个点的x轴和y轴坐标 前2坐标 后4颜色
            -0.5,-1.0, 1.0,0.0,0.0,0.0,    //第二个点的xy轴坐标
            -0.5,1.0, 0.0,0.0,1.0,0.0,  //3 point
            0.0,-1.0, 0.0,0.0,1.0,0.0,  //3 point
            0.0,1.0, 0.0,0.0,1.0,0.0,  //3 point
            0.5,-1.0, 0.0,0.0,1.0,0.0,  //3 point
        ])
        // const colors=new Float32Array([
        //     0.0,0.0,0.0,1.0,
        //     1.0,0.0,0.0,0.0,
        // ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        // const colorBuffer=gl.createBuffer()
        // gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
        // gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW)
        const colorLocation=gl.getAttribLocation(program, 'aColor')
        gl.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 6*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT)
        gl.enableVertexAttribArray(colorLocation)

        gl.drawArrays(gl.POINTS, 0, 6);
        gl.drawArrays(gl.LINE_LOOP, 0, 6);
        gl.drawArrays(gl.TRIANGLES, 0, 6);
     </script>
</body>
</html>

13-uniform传递矩阵变换数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        uniform vec2 uTranslate;
        void main(){
            vec2 newPos=uTranslate+aPosition;
            gl_Position=vec4(newPos,0.0,1.0);
            gl_PointSize=10.0;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,0.5,
            -0.5,-0.5,
            0.5,-0.5,
            0.5,0.5,
        ])

        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        const translationLocation=gl.getUniformLocation(program,'uTranslate')
        const translation=[0.2,0.2]
        gl.uniform2fv(translationLocation,translation)


        gl.drawArrays(gl.POINTS, 0, 4);
        gl.drawArrays(gl.LINE_LOOP, 0, 4);
     </script>
</body>
</html>

14-推导旋转矩阵

scale *

一行 矩阵 行向量

三角形 cos sin tan 等知识换算

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec2 aPosition;
        void main(){
            float radian=radians(45.0);
            float sin=sin(radian);
            float cos=cos(radian);
            mat4 roatate=mat4(
                cos,-sin,0,0,
                sin,cos,0,0,
                0,0,1,0,
                0,0,0,1
            );
            gl_Position=roatate * vec4(aPosition,0.0,1.0);
            gl_PointSize=10.0;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,0.5,
            -0.5,-0.5,
            0.5,-0.5,
            0.5,0.5,
        ])

        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)



        gl.drawArrays(gl.POINTS, 0, 4);
        gl.drawArrays(gl.LINE_LOOP, 0, 4);
     </script>
</body>
</html>

15-绘制线框立方体

也有旋转公式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        void main(){
            float radian=radians(10.0);
            float sin=sin(radian);
            float cos=cos(radian);
            mat4 mx=mat4(
                1,0,0,0,
                0,cos,-sin,0,
                0,sin,cos,0,
                0,0,0,1
            );
            mat4 my=mat4(
                cos,0,-sin,0,
                0,1,0,0,
                sin,0,cos,0,
                0,0,0,1
            );
            gl_Position= mx * my * aPosition;
            gl_PointSize=10.0;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            0.5,0.5,0.5,
            -0.5,0.5,0.5,
            -0.5,-0.5,0.5,
            0.5,-0.5,0.5,

            0.5,0.5,-0.5,
            -0.5,0.5,-0.5,
            -0.5,-0.5,-0.5,
            0.5,-0.5,-0.5,

            0.5,0.5,0.5,
            0.5,0.5,-0.5,

            -0.5,0.5,0.5,
            -0.5,0.5,-0.5,

            -0.5,-0.5,0.5,   
            -0.5,-0.5,-0.5,      
            
            0.5,-0.5,0.5,
            0.5,-0.5,-0.5,
        ])

        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)



        gl.drawArrays(gl.POINTS, 0, 4);
        gl.drawArrays(gl.LINE_LOOP, 0, 4);
        gl.drawArrays(gl.POINTS, 4, 4);
        gl.drawArrays(gl.LINE_LOOP, 4, 4);
        gl.drawArrays(gl.LINES, 8, 8);
     </script>
</body>
</html>

16-顶点索引绘制立方体

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        void main(){
            float radian=radians(10.0);
            float sin=sin(radian);
            float cos=cos(radian);
            mat4 mx=mat4(
                1,0,0,0,
                0,cos,-sin,0,
                0,sin,cos,0,
                0,0,0,1
            );
            mat4 my=mat4(
                cos,0,-sin,0,
                0,1,0,0,
                sin,0,cos,0,
                0,0,0,1
            );
            gl_Position= mx * my * aPosition;
            gl_PointSize=10.0;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        uniform vec4 uColor;
        void main(){
            gl_FragColor=uColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            //前面
            -0.5,-0.5,0.5,
            0.5,-0.5,0.5,
            0.5,0.5,0.5,
            -0.5,0.5,0.5,
            //后面
            -0.5,-0.5,-0.5,
            -0.5,0.5,-0.5,
            0.5,0.5,-0.5,
            0.5,-0.5,-0.5,
            //上面
            -0.5,0.5,-0.5,
            -0.5,0.5,0.5,
            0.5,0.5,0.5,
            0.5,0.5,-0.5,
            //下面
            -0.5,-0.5,-0.5,
            0.5,-0.5,-0.5,
            0.5,-0.5,0.5,
            -0.5,-0.5,0.5,
            //右边
            0.5,-0.5,-0.5,   
            0.5,0.5,-0.5,      
            0.5,0.5,0.5,
            0.5,-0.5,0.5,
            //左边
            -0.5,-0.5,-0.5,   
            -0.5,-0.5,0.5,      
            -0.5,0.5,0.5,
            -0.5,0.5,-0.5,
        ])

        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const indices=new Uint16Array([
            0,1,2, 0,2,3,
            4,5,6, 4,6,7,
            8,9,10, 8,10,11,
            12,13,14, 12,14,15,
            16,17,18, 16,18,19,
            20,21,22, 20,22,23
        ])
        const indexBuffer=gl.createBuffer()
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        // gl.drawElements(gl.TRIANGLES,indices.length,gl.UNSIGNED_SHORT,0)

        const faceColors=[
            [1.0,0.0,0.0,1.0],//前面
            [0.0,1.0,0.0,1.0],
            [1.0,0.0,1.0,1.0],
            [0.0,0.0,0.0,1.0],
            [1.0,0.0,1.0,1.0],
            [1.0,0.0,0.0,1.0],
        ];
        const colorLocation=gl.getUniformLocation(program,'uColor')
        for(let i=0;i<6;i++){
            gl.uniform4fv(colorLocation,faceColors[i])
            gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,i*6*Uint16Array.BYTES_PER_ELEMENT)
        }
     </script>
</body>
</html>

17-实现webgl动画

requestAnimationFrmae(callback)
每秒钟60次

20 = 360
Π = 180
弧度 = 角度*(n/180)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        uniform mat4 u_x_matrix;
        uniform mat4 u_y_matrix;
        void main(){
            gl_Position= u_x_matrix * u_y_matrix * aPosition;
            gl_PointSize=10.0;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        uniform vec4 uColor;
        void main(){
            gl_FragColor=uColor;
        }
     </script>
     <script>
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            //前面
            -0.5,-0.5,0.5,
            0.5,-0.5,0.5,
            0.5,0.5,0.5,
            -0.5,0.5,0.5,
            //后面
            -0.5,-0.5,-0.5,
            -0.5,0.5,-0.5,
            0.5,0.5,-0.5,
            0.5,-0.5,-0.5,
            //上面
            -0.5,0.5,-0.5,
            -0.5,0.5,0.5,
            0.5,0.5,0.5,
            0.5,0.5,-0.5,
            //下面
            -0.5,-0.5,-0.5,
            0.5,-0.5,-0.5,
            0.5,-0.5,0.5,
            -0.5,-0.5,0.5,
            //右边
            0.5,-0.5,-0.5,   
            0.5,0.5,-0.5,      
            0.5,0.5,0.5,
            0.5,-0.5,0.5,
            //左边
            -0.5,-0.5,-0.5,   
            -0.5,-0.5,0.5,      
            -0.5,0.5,0.5,
            -0.5,0.5,-0.5,
        ])

        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const indices=new Uint16Array([
            0,1,2, 0,2,3,
            4,5,6, 4,6,7,
            8,9,10, 8,10,11,
            12,13,14, 12,14,15,
            16,17,18, 16,18,19,
            20,21,22, 20,22,23
        ])
        const indexBuffer=gl.createBuffer()
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 3, gl.FLOAT, false, 3*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        // gl.drawElements(gl.TRIANGLES,indices.length,gl.UNSIGNED_SHORT,0)

        const faceColors=[
            [1.0,0.0,1.0,1.0],//前面
            [0.0,1.0,0.0,1.0],
            [1.0,0.0,1.0,1.0],
            [0.0,1.0,1.0,1.0],
            [1.0,0.0,1.0,1.0],
            [1.0,1.0,0.0,1.0],
        ];
        const colorLocation=gl.getUniformLocation(program,'uColor')
        gl.enable(gl.DEPTH_TEST)

        const u_x_matrix=gl.getUniformLocation(program,'u_x_matrix')
        const u_y_matrix=gl.getUniformLocation(program,'u_y_matrix')
        let deg=30
        function render(){
            deg+=0.1
            const cosB=Math.cos(deg*Math.PI/180)
            const sinB=Math.sin(deg*Math.PI/180)
            gl.uniformMatrix4fv(u_x_matrix,false,new Float32Array([
                1,0,0,0,
                0,cosB,-sinB,0,
                0,sinB,cosB,0,
                0,0,0,1
            ]))
            gl.uniformMatrix4fv(u_y_matrix,false,new Float32Array([
                cosB,0,-sinB,0,
                0,1,0,0,
                sinB,0,cosB,0,
                0,0,0,1
            ]))
            for(let i=0;i<6;i++){
                gl.uniform4fv(colorLocation,faceColors[i])
                gl.drawElements(gl.TRIANGLES,6,gl.UNSIGNED_SHORT,i*6*Uint16Array.BYTES_PER_ELEMENT)
            }
            window.requestAnimationFrame(render)
        }
        window.requestAnimationFrame(render)
     </script>
</body>
</html>

18-glmatrix矩阵库的使用

gl-matrix矩阵库

glmatrix.net/docs/

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .canvas{
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
        attribute vec4 aPosition;
        unifrom mat4 mTranslate;
        void main(){
            gl_Position=mTranslate*aPosition;
        }
     </script>
    <!-- 片段着色器 -->
     <script id="fragment-shader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor=vec4(1.0,0.0,0.0,1.0);
        }
     </script>
     <script type="module">
        import {mat4} from 'gl-matrix';
        const canvas=document.querySelector('.canvas')
        const gl=canvas.getContext("webgl")
        //创建顶点着色器和片元着色器
        const vertexShader=gl.createShader(gl.VERTEX_SHADER)
        const fragmentShader=gl.createShader(gl.FRAGMENT_SHADER)
        //获取着色器源码
        const vertexSource=document.getElementById('vertex-shader').innerText
        const fragmentSource=document.getElementById('fragment-shader').innerText
        //绑定着色器源码
        gl.shaderSource(vertexShader, vertexSource)
        gl.shaderSource(fragmentShader, fragmentSource)
        //编译着色器源码
        gl.compileShader(vertexShader)
        gl.compileShader(fragmentShader)
        //创建程序对象
        const program=gl.createProgram()
        gl.attachShader(program, vertexShader)
        gl.attachShader(program, fragmentShader)
        gl.linkProgram(program)
        gl.useProgram(program);

        const vertices=new Float32Array([
            -0.5,-0.5,0.5,  //第一个点的x轴和y轴坐标
            -0.5,0,0.5    //第二个点的xy轴坐标
        ])
        const buffer=gl.createBuffer()
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

        const posLocation=gl.getAttribLocation(program, 'aPosition')
        gl.vertexAttribPointer(posLocation, 2, gl.FLOAT, false, 2*Float32Array.BYTES_PER_ELEMENT, 0)
        gl.enableVertexAttribArray(posLocation)

        const uniformTranslate=gl.getUniformLocation(program,'mTranslate')
        const matrix=mat4.create()
        mat4.translate(matrix,matrix,[0.5,0.5,0])

        gl.uniformMatrix4fv(uniformTranslate,false,matrix)

        gl.drawArrays(gl.TRIANGLES, 0, 3);
     </script>
</body>
</html>

19-矩阵方法的使用

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .canvas {
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <canvas class="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
      attribute vec4 aPosition;
      uniform mat4 mTranslate;
      void main(){
          gl_Position=mTranslate * aPosition;
      }
    </script>
    <!-- 片段着色器 -->
    <script id="fragment-shader" type="x-shader/x-fragment">
      void main(){
          gl_FragColor=vec4(1.0,0.0,0.0,1.0);
      }
    </script>
    <script type="module">
      import { mat4 } from "gl-matrix";
      const canvas = document.querySelector(".canvas");
      const gl = canvas.getContext("webgl");
      //创建顶点着色器和片元着色器
      const vertexShader = gl.createShader(gl.VERTEX_SHADER);
      const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      //获取着色器源码
      const vertexSource = document.getElementById("vertex-shader").innerText;
      const fragmentSource =
        document.getElementById("fragment-shader").innerText;
      //绑定着色器源码
      gl.shaderSource(vertexShader, vertexSource);
      gl.shaderSource(fragmentShader, fragmentSource);
      //编译着色器源码
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);
      //创建程序对象
      const program = gl.createProgram();
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      gl.linkProgram(program);
      gl.useProgram(program);

      const vertices = new Float32Array([
        -0.5,
        -0.5,
        0.5, //第一个点的x轴和y轴坐标
        -0.5,
        0.0,
        0.5, //第二个点的xy轴坐标
      ]);
      const buffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      const posLocation = gl.getAttribLocation(program, "aPosition");
      gl.vertexAttribPointer(
        posLocation,
        2,
        gl.FLOAT,
        false,
        2 * Float32Array.BYTES_PER_ELEMENT,
        0
      );
      gl.enableVertexAttribArray(posLocation);

      const uniformTranslate = gl.getUniformLocation(program, "mTranslate");
      const matrix = mat4.create();
    //   mat4.translate(matrix, matrix, [0.5, 0.5, 0]);
      mat4.scale(matrix, matrix, [0.5, 0.5, 0]);

      gl.uniformMatrix4fv(uniformTranslate, false, matrix);

      gl.drawArrays(gl.TRIANGLES, 0, 3);
    </script>
  </body>
</html>

posted @   KooTeam  阅读(261)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
点击右上角即可分享
微信分享提示