webgpu_快速入门2

发布时间 2023-06-04 12:47:29作者: 虎虎生威啊

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/9.片元的屏幕坐标/1.片元坐标/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
    <style>

    </style>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');


        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        // 一个矩形拆分为两个三角形表示,三角形其中两个顶点坐标是重合的
        // 注意一个面的多个三角形,正反面要保持一致,要么都是正面,要么都是反面,或者说沿着某个方向看过去,要么都是顺时装,要么都是逆时针
        const vertexArray = new Float32Array([
            // 三角形1三个顶点坐标的x、y、z值
            -0.3, -0.5, 0.0,//顶点1坐标
            0.3, -0.5, 0.0,//顶点2坐标
            0.3, 0.5, 0.0,//顶点3坐标
            // 三角形2三个顶点坐标的x、y、z值
            -0.3, -0.5, 0.0,//顶点4坐标 与顶点1重合
            0.3, 0.5, 0.0,//顶点5坐标 与顶点3重合
            -0.3, 0.5, 0.0,//顶点6坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(6);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/9.片元的屏幕坐标/1.片元坐标/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return vec4<f32>(pos,1.0);
}
`;

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main(@builtin(position) fragCoord : vec4<f32>) -> @location(0) vec4<f32> {
    var x = fragCoord.x;//片元屏幕坐标x
    var y = fragCoord.y;//片元屏幕坐标y
    // fragCoord.z;
    if(x < 250.0){
        // 片元x屏幕坐标小于250,片元设置为红色
        return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    }else{
        // 片元x屏幕坐标不小于250,片元设置为绿色
        return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    }

    // 左上角红色,其他区域绿色
    // if(x < 250.0 && y < 250.0){
    //     return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    // }else{
    //     return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    // }
}
`;

export { vertex, fragment };

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/9.片元的屏幕坐标/2.片元坐标渐变色/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        // 一个矩形拆分为两个三角形表示,三角形其中两个顶点坐标是重合的
        // 注意一个面的多个三角形,正反面要保持一致,要么都是正面,要么都是反面,或者说沿着某个方向看过去,要么都是顺时装,要么都是逆时针
        const vertexArray = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/9.片元的屏幕坐标/2.片元坐标渐变色/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main(@builtin(position) fragCoord : vec4<f32>) -> @location(0) vec4<f32> {
    var x = fragCoord.x;//片元屏幕坐标x
    var y = fragCoord.y;//片元屏幕坐标y
    // 渐变色
    var per: f32 = (x-250.0)/250.0;
    return vec4<f32>(per, 0.0, 1.0-per, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/循环动画.html

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

<head>
    <meta charset="UTF-8">
    <title>Three.js中文网:www.webgl3d.cn</title>
</head>

<body>
    <script>
        let i = 0;
        // 循环动画
        function render() {
            i += 1;
            console.log(i);
        }
        render();
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/requestAnimationFrame请求动画帧函数.html

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

<head>
    <meta charset="UTF-8">
    <title>Three.js中文网:www.webgl3d.cn</title>
</head>

<body>
    <script>
        // requestAnimationFrame实现周期性循环执行
        // requestAnimationFrame默认每秒钟执行60次,但不一定能做到,要看代码的性能
        let i = 0;
        function render() {
            i+=1;
            console.log('执行次数'+i);
            requestAnimationFrame(render);//请求再次执行函数render
        }
        render();
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/1.绕z旋转矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });

        //创建顶点数据(矩形)
        const vertexArray = new Float32Array([
            // 三角形1
            -0.3, -0.5, 0.0,
            0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            // 三角形2
            -0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            -0.3, 0.5, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });


        const modelMatrix = glMatrix.mat4.create();
        // 绕z旋转30度
        glMatrix.mat4.rotateZ(modelMatrix, modelMatrix, Math.PI/6);
        // 绕z旋转90度
        // glMatrix.mat4.rotateZ(modelMatrix, modelMatrix, Math.PI/2);

        // 在GPU显存上创建一个uniform数据缓冲区
        const modelMatrixBuffer = device.createBuffer({
            size: modelMatrix.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix);


        // 设置uniform数据的绑定组
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: modelMatrixBuffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(6);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/1.绕z旋转矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }


// @group(0) @binding(0) var<uniform> t:f32;

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/2.绕z旋转动画/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据(矩形)
        const vertexArray = new Float32Array([
            // 三角形1
            -0.3, -0.5, 0.0,
            0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            // 三角形2
            -0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            -0.3, 0.5, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });


        const modelMatrix = glMatrix.mat4.create();
        // 在GPU显存上创建一个uniform数据缓冲区
        const modelMatrixBuffer = device.createBuffer({
            size: modelMatrix.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix);


        // 设置uniform数据的绑定组
        const bindGroup = device.createBindGroup({
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            entries: [
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: modelMatrixBuffer }
                }
            ]
        });

        //渲染循环
        let angle = 0.0;//初始旋转角度
        function render() {
            angle += 0.05;//每次渲染角度增加
            const modelMatrix = glMatrix.mat4.create();
            // 每次渲染,生成新的旋转矩阵
            glMatrix.mat4.rotateZ(modelMatrix, modelMatrix, angle);
            //模型矩阵modelMatrix重新写入uniform数据的缓冲区中
            device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix)

            // 命令编码器
            const commandEncoder = device.createCommandEncoder();
            // 渲染通道
            const renderPass = commandEncoder.beginRenderPass({
                colorAttachments: [{
                    view: context.getCurrentTexture().createView(),
                    storeOp: 'store',

                    loadOp: 'clear',
                }]
            });
            renderPass.setPipeline(pipeline);
            // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
            renderPass.setVertexBuffer(0, vertexBuffer);
            // 把绑定组里面的uniform数据传递给着色器中uniform变量
            renderPass.setBindGroup(0, bindGroup);
            renderPass.draw(6);// 绘制顶点数据
            renderPass.end();
            const commandBuffer = commandEncoder.finish();
            device.queue.submit([commandBuffer]);

            requestAnimationFrame(render);
        }
        render()
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/7.WebGPU动画(uniform旋转矩阵)/2.绕z旋转动画/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }


// @group(0) @binding(0) var<uniform> t:f32;

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/2.gl-matrix生成平移矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        const mat4Array = glMatrix.mat4.create();
        //生成平移变换矩阵
        glMatrix.mat4.translate(mat4Array, mat4Array, [-1, -1, 0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer = device.createBuffer({
            size: mat4Array.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer, 0, mat4Array);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/2.gl-matrix生成平移矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
// uniform关键字辅助var声明一个4x4矩阵变量
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(0)的参数对应webgpu代码.binding的值,保持一致,比如都是0
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }


/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/4.模型矩阵(先缩放、后平移)/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        const modelMatrix = glMatrix.mat4.create();
        //后发生平移变换,先乘
        glMatrix.mat4.translate(modelMatrix, modelMatrix, [-1, -1, 0]);
        //先发生缩放变换,后乘
        glMatrix.mat4.scale(modelMatrix, modelMatrix, [0.5, 0.5, 1]);

        // 在GPU显存上创建一个uniform数据缓冲区
        const modelMatrixBuffer = device.createBuffer({
            size: modelMatrix.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    binding: 0,
                    resource: { buffer: modelMatrixBuffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/4.模型矩阵(先缩放、后平移)/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }


/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/3.模型矩阵(先平移、后缩放)/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        const modelMatrix = glMatrix.mat4.create();
        //后发生缩放变换,先乘
        glMatrix.mat4.scale(modelMatrix, modelMatrix, [0.5, 0.5, 1]);
        //先发生平移变换,后乘
        glMatrix.mat4.translate(modelMatrix, modelMatrix, [-1, -1, 0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const modelMatrixBuffer = device.createBuffer({
            size: modelMatrix.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: modelMatrixBuffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/3.模型矩阵(先平移、后缩放)/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/1.gl-matrix生成缩放矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        const mat4Array = glMatrix.mat4.create();
        //缩放变换
        glMatrix.mat4.scale(mat4Array, mat4Array, [0.5, 0.5, 1]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer = device.createBuffer({
            size: mat4Array.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer, 0, mat4Array);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/6.gl-matrix生成顶点着色器的矩阵/1.gl-matrix生成缩放矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
// uniform关键字辅助var声明一个4x4矩阵变量
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(0)的参数对应webgpu代码.binding的值,保持一致,比如都是0
@group(0) @binding(0) var<uniform> S:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return S * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }



/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/8.绕y轴旋转动画/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 引入gl-matrix库
        import * as glMatrix from '../gl-matrix/index.js'
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据(矩形)
        const vertexArray = new Float32Array([
            // 三角形1
            -0.3, -0.5, 0.0,
            0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            // 三角形2
            -0.3, -0.5, 0.0,
            0.3, 0.5, 0.0,
            -0.3, 0.5, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });


        // const modelMatrix = glMatrix.mat4.create();
        // // 在GPU显存上创建一个uniform数据缓冲区
        // const modelMatrixBuffer = device.createBuffer({
        //     size: modelMatrix.byteLength,
        //     usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        // });
        
        const modelMatrixBuffer = device.createBuffer({
            size: 16*4,//旋转矩阵16个元素,每个元素占4个字节
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });

        // 设置uniform数据的绑定组
        const bindGroup = device.createBindGroup({
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            entries: [
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: modelMatrixBuffer }
                }
            ]
        });

        //渲染循环
        let angle = 0.0;
        function render() {
            angle += 0.05;
            const modelMatrix = glMatrix.mat4.create();
            // 每次操作(旋转后,再平移)
            glMatrix.mat4.translate(modelMatrix, modelMatrix,[0,0,0.5]);//后平移,不平移矩形平面会被剪裁掉一半
            glMatrix.mat4.rotateY(modelMatrix, modelMatrix,angle);//先旋转
            device.queue.writeBuffer(modelMatrixBuffer, 0, modelMatrix)

            // 命令编码器
            const commandEncoder = device.createCommandEncoder();
            // 渲染通道
            const renderPass = commandEncoder.beginRenderPass({
                colorAttachments: [{
                    view: context.getCurrentTexture().createView(),
                    storeOp: 'store',
                    
                    loadOp: 'clear',
                }]
            });
            renderPass.setPipeline(pipeline);
            // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
            renderPass.setVertexBuffer(0, vertexBuffer);
            // 把绑定组里面的uniform数据传递给着色器中uniform变量
            renderPass.setBindGroup(0, bindGroup);
            renderPass.draw(6);// 绘制顶点数据
            renderPass.end();
            const commandBuffer = commandEncoder.finish();
            device.queue.submit([commandBuffer]);

            requestAnimationFrame(render);
        }
        render()
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/8.绕y轴旋转动画/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> modelMatrix:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return modelMatrix * vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }


// @group(0) @binding(0) var<uniform> t:f32;

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/11.WebGPU顶点数据插值计算/2.顶点数据插值计算/index.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            0.0, 0.0, 0.0,
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/11.WebGPU顶点数据插值计算/2.顶点数据插值计算/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
struct Out{
    @builtin(position) position:vec4<f32>,
    // 位置变量vPosition表示顶点位置坐标插值后的坐标
    // 通过location标记改变量,location的参数可以是0、1、2等
    // vPosition用来表示每个片元的xyz坐标
    @location(0) vPosition:vec3<f32>,
}

@vertex
fn main(@location(0) pos: vec3<f32>) -> Out {
    var out:Out;//通过结构体声明一个变量
    out.position = vec4<f32>(pos,1.0);
    out.vPosition = pos;//插值计算,生成的每个片元对应的xyz坐标
    return out;
}
`;

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
// main参数通过@location(0)声明一个变量,和顶点着色器中vPosition变量关联起来
fn main(@location(0) vPosition:vec3<f32>) -> @location(0) vec4<f32> {
    // 根据x坐标设置片元颜色
    if(vPosition.x<0.5){
        return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    }else{
        return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    }
}
`;

export { vertex, fragment };

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/11.WebGPU顶点数据插值计算/1.顶点着色器返回值:结构体/index.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            0.0, 0.0, 0.0,
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/11.WebGPU顶点数据插值计算/1.顶点着色器返回值:结构体/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
struct Out{
    @builtin(position) position:vec4<f32>,
}
@vertex
fn main(@location(0) pos: vec3<f32>) -> Out {
    var out:Out;
    out.position = vec4<f32>(pos,1.0);
    return out;
}
`


// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/10.片元深度值、深度缓冲区/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        // 一个矩形拆分为两个三角形表示,三角形其中两个顶点坐标是重合的
        // 注意一个面的多个三角形,正反面要保持一致,要么都是正面,要么都是反面,或者说沿着某个方向看过去,要么都是顺时装,要么都是逆时针
        const vertexArray = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/10.片元深度值、深度缓冲区/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return vec4<f32>(pos,1.0);
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main(@builtin(position) fragCoord : vec4<f32>) -> @location(0) vec4<f32> {
    //片元深度值
    var z = fragCoord.z;
    // if(z < 0.5){
    //     // 片元深度值小于0.5,片元设置为红色
    //     return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    // }else{
    //     // 片元深度值不小于250,片元设置为绿色
    //     return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    // }
    // 可视化片元深度
    // return vec4<f32>(z, 1.0, 0.0, 1.0);
    return vec4<f32>(z,0.0,  1.0-z, 1.0);
}
`

export {
    vertex,
    fragment
}

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/演示/index.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/演示/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
struct Out{
    @builtin(position) position:vec4<f32>,
    @location(0) vPosition:vec3<f32>
}
@vertex
fn main(@location(0) pos: vec3<f32>) -> Out{
    var out:Out;
    out.position = vec4<f32>(pos,1.0);
    out.vPosition = pos;////插值计算,生成的每个片元对应的xyz坐标
    return out;
}
`


// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main(@location(0) vPosition:vec3<f32>) -> @location(0) vec4<f32> {
    // if(vPosition.y<0.5){
    //     return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    // }else{
    //     return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    // }
    return vec4<f32>(vPosition.x, 0.0, 1.0-vPosition.x, 1.0);
    
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/3.gl-matrix数学计算库/5.对顶点变换验证.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>

    <script type="module">
        import * as glMatrix from './gl-matrix-master/dist/esm/index.js'

        // 顶点先平移、后缩放
        const modelMatrix = glMatrix.mat4.create();
        //modelMatrix乘一个缩放矩阵(x方向缩放10倍) 
        glMatrix.mat4.scale(modelMatrix, modelMatrix, [10, 1, 1]);//后缩放
        //modelMatrix乘一个平移矩阵(沿着x平移2)
        glMatrix.mat4.translate(modelMatrix, modelMatrix, [2, 0, 0]);//先平移
        console.log('modelMatrix', modelMatrix);

        const p1 = glMatrix.vec3.fromValues(2, 0, 0);//表示一个顶点的坐标
        const p2 = glMatrix.vec3.create();//默认(0,0,0)
        console.log('p2',p2);
        // //p1矩阵变换,变换后结果存储在p2
        glMatrix.vec3.transformMat4(p2, p1, modelMatrix);
        console.log('p2', p2);//Float32Array(3) [40, 0, 0]
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/3.gl-matrix数学计算库/4.简化写法生成模型矩阵.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>

    <script type="module">
        import * as glMatrix from './gl-matrix-master/dist/esm/index.js'

        // 顶点先平移、后缩放
        // 沿着x平移2
        // x方向缩放10倍
        const modelMatrix = glMatrix.mat4.create();
        //后发生缩放变换,先乘
        glMatrix.mat4.scale(modelMatrix, modelMatrix, [10, 1, 1]);
        //先发生平移变换,后乘
        glMatrix.mat4.translate(modelMatrix, modelMatrix, [2, 0, 0]);
        console.log('modelMatrix', modelMatrix);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/3.gl-matrix数学计算库/1.直角表示4x4矩阵.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>

    <script type="module">
        // 引入全部API
        import * as glMatrix from './gl-matrix-master/dist/esm/index.js'
        console.log('glMatrix.mat4', glMatrix.mat4);



        // 创建一个平移矩阵(沿着x、y、z轴分别平移1、2、3)
        //1   0   0    1
        //0   1   0    2
        //0   0   1    3
        //0   0   0    1
        //把矩阵按照列依次写入作为参数
        const mat4T = glMatrix.mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1);

        //创建一个缩放矩阵(x、y、z分别缩放1、2、3) 
        //1   0   0    0
        //0   2   0    0
        //0   0   3    0
        //0   0   0    1
        //把矩阵按照列依次写入作为参数
        const mat4S = glMatrix.mat4.fromValues(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1);

        // 创建的矩阵其实就是用JavaScript的类型化数组表示的
        console.log('mat4T', mat4T);
        console.log('mat4S', mat4S);


    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/3.gl-matrix数学计算库/2.代码生成平移、缩放、旋转矩阵.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>

    <script type="module">
        import * as glMatrix from './gl-matrix-master/dist/esm/index.js'
        console.log('glMatrix', glMatrix);

        // glMatrix.mat4.create()创建的是单位矩阵(乘法运算不会旋转、缩放、平移改变坐标)
        const mat4 = glMatrix.mat4.create();//单位矩阵
        console.log('mat4',mat4);

        // 创建一个平移矩阵(沿着x平移2)
        const mat4T = glMatrix.mat4.create();
        glMatrix.mat4.translate(mat4T,mat4,[2,0,0]);
        // // 创建一个缩放矩阵(x缩放10) 
        const mat4S = glMatrix.mat4.create();
        glMatrix.mat4.scale(mat4S,mat4,[10,1,1]);

        console.log('mat4T',mat4T);
        console.log('mat4S',mat4S);


        // 生成一个旋转矩阵(绕z轴旋转45度) 
        const mat4X = glMatrix.mat4.create();
        glMatrix.mat4.rotateX(mat4X,mat4,Math.PI/4);
        console.log('mat4X',mat4X);

        // 生成一个旋转矩阵(绕z轴旋转45度) 
        const mat4Y = glMatrix.mat4.create();
        glMatrix.mat4.rotateY(mat4Y,mat4,Math.PI/4);
        console.log('mat4Y',mat4Y);

        // 生成一个旋转矩阵(绕z轴旋转45度) 
        const mat4Z = glMatrix.mat4.create();
        glMatrix.mat4.rotateZ(mat4Z,mat4,Math.PI/4);
        console.log('mat4Z',mat4Z);




    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/3.gl-matrix数学计算库/3.矩阵乘法运算.html

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

<head>
    <meta charset="UTF-8">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>

    <script type="module">
        import * as glMatrix from './gl-matrix-master/dist/esm/index.js'


        const mat4 = glMatrix.mat4.create();//单位矩阵

        // 创建一个平移矩阵(沿着x平移2)
        const mat4T = glMatrix.mat4.create();
        glMatrix.mat4.translate(mat4T,mat4,[2,0,0]);
        // 创建一个缩放矩阵(x缩放10) 
        const mat4S = glMatrix.mat4.create();
        glMatrix.mat4.scale(mat4S,mat4,[10,1,1]);


        // 矩阵乘法运算.multiply()
        const modelMatrix = glMatrix.mat4.create();//模型矩阵
        glMatrix.mat4.multiply(modelMatrix,modelMatrix,mat4S);//后缩放
        glMatrix.mat4.multiply(modelMatrix,modelMatrix,mat4T);//先平移
        console.log('modelMatrix',modelMatrix);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/3.先平移、后缩放/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/3.先平移、后缩放/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 创建一个平移矩阵(沿着x、y轴分别平移-1、-1)
    var T:mat4x4<f32> = mat4x4<f32>(1.0,0.0,0.0,0.0,  0.0,1.0,0.0,0.0,  0.0,0.0,1.0,0.0,  -1.0,-1.0,0.0,1.0);
    // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
    var S = mat4x4<f32>(0.5,0.0,0.0,0.0,  0.0,0.5,0.0,0.0,  0.0,0.0,1.0,0.0,  0.0,0.0,0.0,1.0);
    return S * T * vec4<f32>(pos,1.0);// 先平移、后缩放(矩阵顺序从右往左)
    // return T * S * vec4<f32>(pos,1.0);// 先缩放、后平移(矩阵顺序从右往左)
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export {
    vertex,
    fragment
}

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/2.平移矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/2.平移矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 创建一个平移矩阵(沿着x、y轴分别平移-1、-1)
    //1   0   0    -1
    //0   1   0    -1
    //0   0   1    0
    //0   0   0    1
    // 矩阵元素一列一列输入mat4x4<f32>()
    var T:mat4x4<f32> = mat4x4<f32>(1.0,0.0,0.0,0.0,  0.0,1.0,0.0,0.0,  0.0,0.0,1.0,0.0,  -1.0,-1.0,0.0,1.0);
    return T * vec4<f32>(pos,1.0);//平移矩阵对顶点平移变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export {
    vertex,
    fragment
}

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/4.先缩放、后平移/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/4.先缩放、后平移/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 创建一个平移矩阵(沿着x、y轴分别平移-1、-1)
    var T:mat4x4<f32> = mat4x4<f32>(1.0,0.0,0.0,0.0,  0.0,1.0,0.0,0.0,  0.0,0.0,1.0,0.0,  -1.0,-1.0,0.0,1.0);
    // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
    var S = mat4x4<f32>(0.5,0.0,0.0,0.0,  0.0,0.5,0.0,0.0,  0.0,0.0,1.0,0.0,  0.0,0.0,0.0,1.0);
    // return S * T * vec4<f32>(pos,1.0);// 先平移、后缩放(矩阵顺序从右往左)
    return T * S * vec4<f32>(pos,1.0);// 先缩放、后平移(矩阵顺序从右往左)
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export {
    vertex,
    fragment
}

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/1.缩放矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });

        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/4.顶点着色器矩阵变换/1.缩放矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
    //0.5  0    0    0
    //0    0.5  0    0
    //0    0    1    0
    //0    0    0    1
    // 矩阵元素一列一列输入mat4x4<f32>()
    var S = mat4x4<f32>(0.5,0.0,0.0,0.0,  0.0,0.5,0.0,0.0,  0.0,0.0,1.0,0.0,  0.0,0.0,0.0,1.0);
    return S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/2.uniform传递一个浮点数/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据(传递一个浮点数)
        const t = 0.5;//一个浮点数,表示三角形x和y两个方向的缩放倍数
        const tArray = new Float32Array([t]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const tBuffer = device.createBuffer({
            size: tArray.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        //tArray里面矩阵数据写入uniform缓冲区tBuffer
        device.queue.writeBuffer(tBuffer, 0, tArray);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: tBuffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup( 0, bindGroup );
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/2.uniform传递一个浮点数/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
@group(0) @binding(0) var<uniform> t:f32;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 创建一个缩放矩阵(沿着x、y分别缩放t倍)
    //t    0    0    0
    //0    t    0    0
    //0    0    1    0
    //0    0    0    1
    // 矩阵元素一列一列输入mat4x4<f32>()
    var S = mat4x4<f32>(t,0.0,0.0,0.0,  0.0,t,0.0,0.0,  0.0,0.0,1.0,0.0,  0.0,0.0,0.0,1.0);
    return S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/3.给片元着色器传递uniform数据/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形

            }
        });

        // 传递着色器对应uniform数据
        // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
        //0.5  0    0    0
        //0    0.5  0    0
        //0    0    1    0
        //0    0    0    1
        // 矩阵元素一列一列输入作为类型化数组的参数
        const mat4Array = new Float32Array([0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer = device.createBuffer({
            size: mat4Array.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer, 0, mat4Array);

        // 给片元着色器传递一个颜色数据
        const colorArray = new Float32Array([0.0,1.0,0.0]);//绿色
        // 在GPU显存上创建一个uniform数据缓冲区
        const colorBuffer = device.createBuffer({
            size: colorArray.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // colorArray里面颜色数据写入uniform缓冲区colorBuffer
        device.queue.writeBuffer(colorBuffer, 0, colorArray);


        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer }
                },
                {
                    //binding的值对应@binding(1)的参数,保持一致,比如都是1
                    binding: 1,//标记组里面的uniform数据
                    resource: { buffer: colorBuffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup(0, bindGroup);
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/3.给片元着色器传递uniform数据/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
// uniform关键字辅助var声明一个4x4矩阵变量
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(0)的参数对应webgpu代码.binding的值,保持一致,比如都是0
@group(0) @binding(0) var<uniform> S:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
// uniform关键字辅助var声明一个三维向量变量color表示片元颜色
//@binding(1)的参数对应webgpu代码.binding的值,保持一致,比如都是1
@group(0) @binding(1) var<uniform> color:vec3<f32>;
@fragment
fn main() -> @location(0) vec4<f32> {
    // return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    return vec4<f32>(color, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/1.uniform传递缩放矩阵/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
        //0.5  0    0    0
        //0    0.5  0    0
        //0    0    1    0
        //0    0    0    1
        // 矩阵元素一列一列输入作为类型化数组的参数
        const mat4Array = new Float32Array([0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer = device.createBuffer({
            size: mat4Array.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer, 0, mat4Array);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup( 0, bindGroup );
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/1.uniform传递缩放矩阵/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
// uniform关键字辅助var声明一个4x4矩阵变量
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(0)的参数对应webgpu代码.binding的值,保持一致,比如都是0
@group(0) @binding(0) var<uniform> S:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/4.传递两个uniform数据(两个矩阵)/index.html

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Threejs中文网:http://www.webgl3d.cn/</title>
</head>

<body>
    <!-- canvas:用来展示WebGPU渲染的结果 -->
    <canvas id="webgpu" width="500" height="500"></canvas>
    <script type="module">
        // 顶点着色器、片元着色器代码
        import { vertex, fragment } from './shader.js'

        // 配置WebGPU上下文
        const adapter = await navigator.gpu.requestAdapter();
        const device = await adapter.requestDevice();
        const canvas = document.getElementById('webgpu');
        const context = canvas.getContext('webgpu');
        const format = navigator.gpu.getPreferredCanvasFormat();
        context.configure({
            device: device,
            format: format,
        });


        //创建顶点数据
        const vertexArray = new Float32Array([
            // 三角形三个顶点坐标的x、y、z值
            0.0, 0.0, 0.0,//顶点1坐标
            1.0, 0.0, 0.0,//顶点2坐标
            0.0, 1.0, 0.0,//顶点3坐标
        ]);
        const vertexBuffer = device.createBuffer({// 创建顶点数据的缓冲区
            size: vertexArray.byteLength,
            usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
        });
        device.queue.writeBuffer(vertexBuffer, 0, vertexArray);// 顶点数据写入缓冲区


        // 渲染管线
        const pipeline = device.createRenderPipeline({
            layout: 'auto',
            vertex: {//顶点相关配置
                module: device.createShaderModule({ code: vertex }),
                entryPoint: "main",
                buffers: [//顶点缓冲区相关设置
                    {
                        arrayStride: 3 * 4,
                        attributes: [{
                            shaderLocation: 0,//顶点缓冲区存储位置标记
                            format: "float32x3",
                            offset: 0
                        }]
                    }
                ]
            },
            fragment: {//片元相关配置
                module: device.createShaderModule({ code: fragment }),
                entryPoint: "main",
                targets: [{
                    format: format
                }]
            },
            primitive: {
                topology: "triangle-list",//绘制三角形
                
            }
        });

        // 传递着色器对应uniform数据
        // 创建一个缩放矩阵(沿着x、y分别缩放0.5倍)
        //0.5  0    0    0
        //0    0.5  0    0
        //0    0    1    0
        //0    0    0    1
        // 矩阵元素一列一列输入作为类型化数组的参数
        const mat4Array = new Float32Array([0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer = device.createBuffer({
            size: mat4Array.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer, 0, mat4Array);

        // 平移矩阵
        const mat4Array2 = new Float32Array([1.0,0.0,0.0,0.0,  0.0,1.0,0.0,0.0,  0.0,0.0,1.0,0.0,  -1.0,-1.0,0.0,1.0]);
        // 在GPU显存上创建一个uniform数据缓冲区
        const mat4Buffer2 = device.createBuffer({
            size: mat4Array2.byteLength,
            usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
        });
        // mat4Array里面矩阵数据写入uniform缓冲区mat4Buffer
        device.queue.writeBuffer(mat4Buffer2, 0, mat4Array2);

        // 设置uniform数据的绑定组
        // 学习createBindGroup的参数,可以类比渲染管线中shaderLocation学习
        const bindGroup = device.createBindGroup({
            // .getBindGroupLayout(0)参数0对应shader中@group(0)代码的参数0
            layout: pipeline.getBindGroupLayout(0),//绑定组,标记为0
            // 一个组里面可以包含多个uniform数据
            entries: [//每个元素可以用来设置一个uniform数据
                {
                    //binding的值对应@binding(0)的参数,保持一致,比如都是0
                    binding: 0,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer }
                },
                {
                    //binding的值对应@binding(1)的参数,保持一致,比如都是1
                    binding: 1,//标记组里面的uniform数据
                    resource: { buffer: mat4Buffer2 }
                }
            ]
        });

        // 命令编码器
        const commandEncoder = device.createCommandEncoder();
        // 渲染通道
        const renderPass = commandEncoder.beginRenderPass({
            colorAttachments: [{
                view: context.getCurrentTexture().createView(),
                storeOp: 'store',
                
                loadOp: 'clear',
            }]
        });
        renderPass.setPipeline(pipeline);
        // 顶点缓冲区数据和渲染管线shaderLocation: 0表示存储位置关联起来
        renderPass.setVertexBuffer(0, vertexBuffer);
        // 把绑定组里面的uniform数据传递给着色器中uniform变量
        renderPass.setBindGroup( 0, bindGroup );
        renderPass.draw(3);// 绘制顶点数据
        renderPass.end();
        const commandBuffer = commandEncoder.finish();
        device.queue.submit([commandBuffer]);
    </script>
</body>

</html>

/Users/song/Downloads/WebGPU视频教程/2. 3D几何变换数学基础/5.传递uniform数据/4.传递两个uniform数据(两个矩阵)/shader.js

// 顶点着色器代码
const vertex = /* wgsl */ `
// uniform关键字辅助var声明一个4x4矩阵变量
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(1)的参数对应webgpu代码.binding的值,保持一致,比如都是1
@group(0) @binding(0) var<uniform> S:mat4x4<f32>;
@group(0) @binding(1) var<uniform> T:mat4x4<f32>;
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    // 先缩放、后平移
    return T * S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
`

// 片元着色器代码
const fragment = /* wgsl */ `
@fragment
fn main() -> @location(0) vec4<f32> {
    return vec4<f32>(1.0, 0.0, 0.0, 1.0);
}
`

export { vertex, fragment }

参考

  1. threejs中文档,郭老师博客