一个旋转cube,用了lookat,注释了其他的多余方法

<!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>てst</title>

</head>

<body>

  <!-- canvas:用来展示WebGPU渲染的结果 -->

  <canvas id="webgpu" width="500" height="500"></canvas>

  <script type="module">

    //chrome setting:

    //"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="D:\angular\webgpu\n" --disable-site-isolation-trials

    //

    //1,增加一个uniform buffer object(简称为ubo),

    //用于传输“model矩阵 乘以 view矩阵 乘以 projection矩阵”的结果矩阵(简称为mvp矩阵),并在每帧被更新

    //2.设置顶点

    //3.开启面剔除

    //4.开启深度测试

    // 配置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 cubeVertexArray2 = new Float32Array([

      // float4 position, float4 color, float2 uv,

      1, -1, 1, 1, 1, 0, 1, 1, 1, 1,

      -1, -1, 1, 1, 0, 0, 1, 1, 0, 1,

      -1, -1, -1, 1, 0, 0, 0, 1, 0, 0,

      1, -1, -1, 1, 1, 0, 0, 1, 1, 0,

      1, -1, 1, 1, 1, 0, 1, 1, 1, 1,

      -1, -1, -1, 1, 0, 0, 0, 1, 0, 0,

      1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

      1, -1, 1, 1, 1, 0, 1, 1, 0, 1,

      1, -1, -1, 1, 1, 0, 0, 1, 0, 0,

      1, 1, -1, 1, 1, 1, 0, 1, 1, 0,

      1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

      1, -1, -1, 1, 1, 0, 0, 1, 0, 0,

      -1, 1, 1, 1, 0, 1, 1, 1, 1, 1,

      1, 1, 1, 1, 1, 1, 1, 1, 0, 1,

      1, 1, -1, 1, 1, 1, 0, 1, 0, 0,

      -1, 1, -1, 1, 0, 1, 0, 1, 1, 0,

      -1, 1, 1, 1, 0, 1, 1, 1, 1, 1,

      1, 1, -1, 1, 1, 1, 0, 1, 0, 0,

      -1, -1, 1, 1, 0, 0, 1, 1, 1, 1,

      -1, 1, 1, 1, 0, 1, 1, 1, 0, 1,

      -1, 1, -1, 1, 0, 1, 0, 1, 0, 0,

      -1, -1, -1, 1, 0, 0, 0, 1, 1, 0,

      -1, -1, 1, 1, 0, 0, 1, 1, 1, 1,

      -1, 1, -1, 1, 0, 1, 0, 1, 0, 0,

      1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

      -1, 1, 1, 1, 0, 1, 1, 1, 0, 1,

      -1, -1, 1, 1, 0, 0, 1, 1, 0, 0,

      -1, -1, 1, 1, 0, 0, 1, 1, 0, 0,

      1, -1, 1, 1, 1, 0, 1, 1, 1, 0,

      1, 1, 1, 1, 1, 1, 1, 1, 1, 1,

      1, -1, -1, 1, 1, 0, 0, 1, 1, 1,

      -1, -1, -1, 1, 0, 0, 0, 1, 0, 1,

      -1, 1, -1, 1, 0, 1, 0, 1, 0, 0,

      1, 1, -1, 1, 1, 1, 0, 1, 1, 0,

      1, -1, -1, 1, 1, 0, 0, 1, 1, 1,

      -1, 1, -1, 1, 0, 1, 0, 1, 0, 0,

    ]);

    //-------设置顶点--------------------------

    //引入gl-matrix.js库

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

    // 定点缓冲区

    const vertexBuffer = device.createBuffer({

      size: cubeVertexArray2.byteLength, //顶点数据的字节长度

      //usage设置该缓冲区的用途(作为顶点缓冲区|可以写入顶点数据)

      usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,

    });

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

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


 

    //------------wsgl代码-------------------  

    const module = device.createShaderModule({

      label: 'triangle shaders with uniforms',

      code: `

struct Uniforms {

  modelViewProjectionMatrix : mat4x4f//这里不能用分号

};

@group(0) @binding(0) var<uniform> uniforms : Uniforms;

struct VertexOutput {

  @builtin(position) Position : vec4f,

  @location(0) fragUV : vec2f,

  @location(1) fragPosition: vec4f

};

@vertex

fn vs(@location(0) position : vec4f,@location(1) uv : vec2f) -> VertexOutput {

  var output : VertexOutput;

  output.Position =  uniforms.modelViewProjectionMatrix * position;

  output.fragUV = uv;

  output.fragPosition = 0.5 * (position + vec4f(1.0, 1.0, 1.0, 1.0));

  return output;

}

@fragment

fn fs(@location(0) fragUV: vec2<f32>,@location(1) fragPosition: vec4<f32>) -> @location(0) vec4<f32> {

  return fragPosition;

}

`,

    });

    let cubePositionOffset = 0;

    let cubeUVOffset = 4 * 8;

    let cubeVertexSize = 4 * 10;

    const pipeline = device.createRenderPipeline({

      layout: "auto",

      vertex: {

        module: module,

        entryPoint: 'vs',

        buffers: [ // 为顶点着色器配置Buffer

          {

            arrayStride: cubeVertexSize,

            attributes: [

              {

                // position

                shaderLocation: 0,

                offset: cubePositionOffset,

                format: 'float32x4',

              },

              {

                // uv

                shaderLocation: 1,

                offset: cubeUVOffset,

                format: 'float32x2',

              },

            ],

          },

        ],

      },

      fragment: {

        module: module,

        entryPoint: 'fs',

        targets: [

          {

            format: format,

          },

        ],

      },

      primitive: {

        topology: 'triangle-list',

        // Backface culling since the cube is solid piece of geometry.

        // Faces pointing away from the camera will be occluded by faces

        // pointing toward the camera.

        //3.开启背面面剔除

        cullMode: 'back',

      },

      //multisample: {

      //  count: 4

      //},

      // Enable depth testing so that the fragment closest to the camera

      // is rendered in front.

      //4.开启深度测试

      depthStencil: {

        depthWriteEnabled: true,

        depthCompare: 'less',

        format: 'depth24plus',

      },

    });


 

    const uniformBufferSize = 4 * 16; // 4x4 matrix

    const uniformBuffer = device.createBuffer({

      size: uniformBufferSize,

      usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,

    });

    const uniformBindGroup = device.createBindGroup({

      layout: pipeline.getBindGroupLayout(0),

      entries: [

        {

          binding: 0,

          resource: {

            buffer: uniformBuffer,

          },

        },

      ],

    });

    const depthTexture = device.createTexture({

      size: {

        width: canvas.width,

        height: canvas.height,

      },

      format: "depth24plus",

      //sampleCount: 4,

      usage: GPUTextureUsage.RENDER_ATTACHMENT

    });

    const renderPassDescriptor = {

      colorAttachments: [

        {

          // view: context.getCurrentTexture().createView(), // Assigned later

          loadOp: 'clear',

          loadValue: { r: 0.5, g: 0.5, b: 0.5, a: 1.0 },

          storeOp: 'store',

        },

      ],

      depthStencilAttachment: {

        view: depthTexture.createView(),

        depthStoreOp: 'store',

        depthClearValue: 1.0,

        depthLoadOp: "clear",

        depthLoadValue: 1.0,

        // depthStoreOp: 'store',

        // stencilLoadValue: 0,

        //stencilStoreOp: 'store',

      },

    };

    //固定相机,透视投影

    const aspect = Math.abs(canvas.width / canvas.height);

    //let projectionMatrix = glMatrix.mat4.create();

    //glMatrix.mat4.perspective(projectionMatrix, (2 * Math.PI) / 5, aspect, 1, 100.0);

    /*

    //计算mvp矩阵

    function getTransformationMatrix() {

      //顺序:平移--》旋转--》缩放

      let viewMatrix = glMatrix.mat4.create();

      glMatrix.mat4.translate(viewMatrix, viewMatrix, glMatrix.vec3.fromValues(0, 0, -5));

      let now = Date.now() / 1000;

      glMatrix.mat4.rotate(viewMatrix, viewMatrix, 1, glMatrix.vec3.fromValues(Math.sin(now), Math.cos(now), 0));

      let modelViewProjectionMatrix = glMatrix.mat4.create();

      //顺序:透视投影 x 旋转矩阵

      glMatrix.mat4.multiply(modelViewProjectionMatrix, projectionMatrix, viewMatrix);

      return modelViewProjectionMatrix;

    }

    */

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

    //==============================

    // return mvp matrix from given aspect, position, rotation, scale

    /*

    function getMvpMatrix(

        aspect: number,

        position: {x:number, y:number, z:number},

        rotation: {x:number, y:number, z:number},

        scale: {x:number, y:number, z:number}

    ){

    */

    const center = glMatrix.vec3.fromValues(0, 0, 0)

    const up = glMatrix.vec3.fromValues(0, 1, 0)

    function getMvpMatrix(

      aspect,

      position,

      rotation,

      scale

    ) {

      // get modelView Matrix

      const modelViewMatrix = getModelViewMatrix(position, rotation, scale)

      // get projection Matrix

      const projectionMatrix = getProjectionMatrix(aspect, 60 / 180 * Math.PI, 0.1, 100.0, { x: 0, y: 0, z: 0 })


 

      // get mvp matrix

      const mvpMatrix = glMatrix.mat4.create()

      glMatrix.mat4.multiply(mvpMatrix, projectionMatrix, modelViewMatrix)

      // return matrix as Float32Array

      return mvpMatrix;// as Float32Array

    }

    // return modelView matrix from given position, rotation, scale

    /*

    function getModelViewMatrix(

        position = {x:0, y:0, z:0},

        rotation = {x:0, y:0, z:0},

        scale = {x:1, y:1, z:1}

    ){

    */

    function getModelViewMatrix(

      position,

      rotation,

      scale

    ) {

      // get modelView Matrix

      const modelViewMatrix = glMatrix.mat4.create()

      // translate position

      glMatrix.mat4.translate(modelViewMatrix, modelViewMatrix, glMatrix.vec3.fromValues(position.x, position.y, position.z))

      // rotate

      glMatrix.mat4.rotateX(modelViewMatrix, modelViewMatrix, rotation.x)

      glMatrix.mat4.rotateY(modelViewMatrix, modelViewMatrix, rotation.y)

      glMatrix.mat4.rotateZ(modelViewMatrix, modelViewMatrix, rotation.z)

      // scale

      glMatrix.mat4.scale(modelViewMatrix, modelViewMatrix, glMatrix.vec3.fromValues(scale.x, scale.y, scale.z))

      // return matrix as Float32Array

      return modelViewMatrix;//as Float32Array

    }


 

    /*

    function getProjectionMatrix(

        aspect: number,

        fov:number = 60 / 180 * Math.PI,

        near:number = 0.1,

        far:number = 100.0,

        position = {x:0, y:0, z:0}

    ){  

    */

    function getProjectionMatrix(

      aspect,

      fov,

      near,

      far,

      position

    ) {

      // create cameraview

      const cameraView = glMatrix.mat4.create()

      const eye = glMatrix.vec3.fromValues(position.x, position.y, position.z)

      glMatrix.mat4.translate(cameraView, cameraView, eye)

      glMatrix.mat4.lookAt(cameraView, eye, center, up)

      // get a perspective Matrix

      const projectionMatrix = glMatrix.mat4.create()

      glMatrix.mat4.perspective(projectionMatrix, fov, aspect, near, far)

      glMatrix.mat4.multiply(projectionMatrix, projectionMatrix, cameraView)

      // return matrix as Float32Array

      return projectionMatrix;// as Float32Array

    }


 

    //==============================

    function frame() {

      //=================================

      /*   旧的方法,也是可以的,计算投影的时候,没用lookat

         const transformationMatrix = getTransformationMatrix();

          device.queue.writeBuffer(

            uniformBuffer,

            0,

            transformationMatrix.buffer,

            transformationMatrix.byteOffset,

            transformationMatrix.byteLength

          );

      */

      let position = { x: 0, y: 0, z: -5 }

      let scale = { x: 1, y: 1, z: 1 }

      //  let rotation = { x: 0, y: 2, z: 3 }


 

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

      // let viewMatrix = glMatrix.mat4.create();

      // glMatrix.mat4.translate(viewMatrix, viewMatrix, glMatrix.vec3.fromValues(0, 0, -5));

      let now = Date.now() / 1000;

      // glMatrix.mat4.rotate(viewMatrix, viewMatrix, 1, glMatrix.vec3.fromValues(Math.sin(now), Math.cos(now), 0));

      let rotation = { x: Math.sin(now), y: Math.cos(now), z: 0 };

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

      const mvpMatrix = getMvpMatrix(aspect, position, rotation, scale)

      /*    device.queue.writeBuffer(

                  pipelineObj.mvpBuffer,

                  0,

                  mvpMatrix.buffer

              );

          */

      device.queue.writeBuffer(

        uniformBuffer,

        0,

        mvpMatrix.buffer,

        mvpMatrix.byteOffset,

        mvpMatrix.byteLength

      );

      //=============================

      //必须在这里设置texture,否则保存

      renderPassDescriptor.colorAttachments[0].view = context

        .getCurrentTexture()

        .createView();

      const commandEncoder = device.createCommandEncoder();

      const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);

      passEncoder.setPipeline(pipeline);

      passEncoder.setBindGroup(0, uniformBindGroup);

      passEncoder.setVertexBuffer(0, vertexBuffer);

      passEncoder.draw(36, 1, 0, 0);

      passEncoder.end();

      device.queue.submit([commandEncoder.finish()]);

      requestAnimationFrame(frame);

    };

    frame();

  </script>

</body>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值