y轴 旋转矩形,颜色插值显示

<!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三个顶点坐标的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设置该缓冲区的用途(作为顶点缓冲区|可以写入顶点数据)

    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,

  });

        //引入gl-matrix.js库

 import * as glMatrix from './dist/esm/index.js';

  // 将顶点信息写入缓冲器

  device.queue.writeBuffer(vertexBuffer, 0, vertexArray);

    // ----------------------------------------------------------------

  // 创建一个单位矩阵

  const mat4Array = glMatrix.mat4.create();

  // 在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([1.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);

  // 创建渲染管线

  const pipeline = device.createRenderPipeline({

    layout: "auto",

    vertex: {

      //顶点相关配置

      buffers: [

        // 顶点所有的缓冲区模块设置

        {

          //其中一个顶点缓冲区设置

          arrayStride: 3 * 4, //一个顶点数据占用的字节长度,该缓冲区一个顶点包含xyz三个分量,每个数字是4字节浮点数,3*4字节长度

          attributes: [

            {

              // 顶点缓冲区属性

              shaderLocation: 0, //GPU显存上顶点缓冲区标记存储位置

              format: "float32x3", //格式:loat32x3表示一个顶点数据包含3个32位浮点数

              offset: 0, //arrayStride表示每组顶点数据间隔字节数,offset表示读取改组的偏差字节数,没特殊需要一般设置0

            },

          ],

        },

      ],

      module: device.createShaderModule({

        label: "triangle vertex",

        code: vertex,

      }),

      entryPoint: "main",

    },

    fragment: {

      module: device.createShaderModule({

        label: "fragment vertex",

        code: fragment,

      }),

      entryPoint: "main", //指定入口函数

      targets: [

        {

          format: format, //和WebGPU上下文配置的颜色格式保持一致

        },

      ],

    },

    primitive: {

      topology: "triangle-list", //绘制三角形

      // topology: "point-list", //绘制三角形

      // topology: "line-list", //绘制三角形

    },

  });

  // 设置uniform数据的绑定组

  const bindGroup = device.createBindGroup({

    layout: pipeline.getBindGroupLayout(0), //绑定组,标记为0

    // 一个组里面可以包含多个uniform数据

    entries: [

      //每个元素可以用来设置一个uniform数据

      {

        binding: 0, //标记组里面的uniform数据

        resource: { buffer: mat4Buffer },

      },

      {

        //binding的值对应@binding(1)的参数,保持一致,比如都是1

        binding: 1, //标记组里面的uniform数据

        resource: { buffer: colorBuffer },

      },

    ],

  });

  //渲染循环

  let angle = 0.0; //初始旋转角度

  function render() {

    angle += 0.01; //每次渲染角度增加

    const modelMatrix = glMatrix.mat4.create();

    glMatrix.mat4.translate(modelMatrix, modelMatrix,[0,0,0.5]);

    // 每次渲染,生成新的旋转矩阵

    glMatrix.mat4.rotateY(modelMatrix, modelMatrix, angle);

   

    //模型矩阵modelMatrix重新写入uniform数据的缓冲区中

    device.queue.writeBuffer(mat4Buffer, 0, modelMatrix);

    // 创建GPU命令编码器对象

    const commandEncoder = device.createCommandEncoder();

    const renderPass = commandEncoder.beginRenderPass({

      label: "our basic canvas renderPass",

      // 给渲染通道指定颜色缓冲区,配置指定的缓冲区

      colorAttachments: [

        {

          // 指向用于Canvas画布的纹理视图对象(Canvas对应的颜色缓冲区)

          // 该渲染通道renderPass输出的像素数据会存储到Canvas画布对应的颜色缓冲区(纹理视图对象)

          view: context.getCurrentTexture().createView(),

          storeOp: "store", //像素数据写入颜色缓冲区

          loadOp: "clear",

          clearValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 }, //背景颜色

        },

      ],

    });

    // 关联顶点缓冲区数据和渲染管线

    renderPass.setVertexBuffer(0, vertexBuffer);

    // 把绑定组里面的uniform数据传递给着色器中uniform变量

    // 参数1的0和.getBindGroupLayout(0)参数一致,都是0

    renderPass.setBindGroup(0, bindGroup);

    renderPass.setPipeline(pipeline);

    renderPass.draw(6); // call our vertex shader 3 times

    renderPass.end();

    // 命令缓冲器

    const commandBuffer = commandEncoder.finish();

    device.queue.submit([commandBuffer]);

    requestAnimationFrame(render);

  }

  render();

    </script>

</body>

</html>

---------------

// 顶点着色器代码
const vertex = /* wgsl */ `
//@group(0)的参数0对应webgpu代码.getBindGroupLayout(0)参数0
//@binding(0)的参数对应webgpu代码.binding的值,保持一致,比如都是0
@group(0) @binding(0) var<uniform> S:mat4x4<f32>;
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= S * vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
    out.vposition= (S * vec4<f32>(pos,1.0)).xyz;//缩放矩阵对顶点缩放变换
    return out;
}
`;
 
// 片元着色器代码
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) vposition:vec3<f32>) -> @location(0) vec4<f32> {
    
    var c=color;
    return vec4<f32>(vposition.z+c.x,c.y,c.z+1-vposition.z,1);
}
`;
 
export { vertex, fragment };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值