沿着zz轴旋转

<!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> {
  // return vec4<f32>(color,1.0);
 // var c=color;
  return vec4<f32>(vposition.z,1,1-vposition.z,1);
}
`;
 
export { vertex, fragment };

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值