2d,正交投影,mat3.project 的使用

<!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>
  translationx:<input type="range" min="0" max="500" step="0.1" name="translationx" value="230.2" /><br>
  translationy:<input type="range" min="0" max="500" step="0.1" name="translationy" value="230.2" /><br>
  rotationx:<input type="range" min="0" max="360" step="0.1" name="rotationx" value="0" /><br>
  rotationy:<input type="range" min="0" max="360" step="0.1" name="rotationy" value="0" /><br>
  rotationz:<input type="range" min="0" max="360" step="0.1" name="rotationz" value="0" /><br>
  scalex:<input type="range" min="-5" max="5" step="0.1" name="scalex" value="1.1" /><br>
  scaley:<input type="range" min="-5" max="5" step="0.1" name="scaley" value="1.1" /><br>

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

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

    function createTranVertices() {
   const vertexData = new Float32Array([
    // 左栏
    0, 0, 0,
    30, 0, 0,
    0, 150, 0,
    30, 150, 0,
 
    // 顶部梯级
    30, 0, 0,
    100, 0, 0,
    30, 30, 0,
    100, 30, 0,
 
    // 中间梯级
    30, 60, 0,
    70, 60, 0,
    30, 90, 0,
    70, 90, 0,
  ]);
 
  const indexData = new Uint32Array([
    0,  1,  2,    2,  1,  3,  // 左栏
    4,  5,  6,    6,  5,  7,  // 顶部运行
    8,  9, 10,   10,  9, 11,  // 中间运行
  ]);
 
  return {
    vertexData,
    indexData,
    numVertices: indexData.length,
  };
    }

    async function main() {
      const adapter = await navigator.gpu?.requestAdapter();
      const device = await adapter?.requestDevice();
      if (!device) {
        fail('need a browser that supports WebGPU');
        return;
      }

      // Get a WebGPU context from the canvas and configure it
      const canvas = document.querySelector('canvas');
      const context = canvas.getContext('webgpu');
      const presentationFormat = navigator.gpu.getPreferredCanvasFormat();

      context.configure({
        device,
        format: presentationFormat,
        alphaMode: 'premultiplied',
      });

      const module = device.createShaderModule({
        code: `
       struct Uniforms {
          color: vec4f,
          matrix: mat4x4f,
        };

        struct Vertex {
          @location(0) position: vec4f,
        };

        struct VSOutput {
          @builtin(position) position: vec4f,
        };

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

        @vertex fn vs(vert: Vertex) -> VSOutput {
          var vsOut: VSOutput;

           vsOut.position = uni.matrix * vert.position;
  return vsOut;
        }

        @fragment fn fs(vsOut: VSOutput) -> @location(0) vec4f {
          return uni.color;
        }
    `
      });

      const pipeline = device.createRenderPipeline({
        label: 'just 2d position',
        layout: 'auto',
        vertex: {
          module,
          entryPoint: 'vs',
          buffers: [
            {
              arrayStride: (3) * 4, // (2) floats, 4 bytes each
              attributes: [
                { shaderLocation: 0, offset: 0, format: 'float32x3' },  // position
              ],
            },
          ],
        },
        fragment: {
          module,
          entryPoint: 'fs',
          targets: [{ format: presentationFormat }],
        },
      });

      // color, resolution, padding, matrix
      const uniformBufferSize = (4  + 16) * 4;
      const uniformBuffer = device.createBuffer({
        label: 'uniforms',
        size: uniformBufferSize,
        usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
      });

      const uniformValues = new Float32Array(uniformBufferSize / 4);

      // offsets to the various uniform values in float32 indices
      const kColorOffset = 0;
       
      const kMatrixOffset = 4;

      const colorValue = uniformValues.subarray(kColorOffset, kColorOffset + 4);
      const matrixValue = uniformValues.subarray(kMatrixOffset, kMatrixOffset + 16);

      // The color will not change so let's set it once at init time
      colorValue.set([Math.random(), Math.random(), Math.random(), 1]);

      
      const { vertexData, indexData, numVertices } = createTranVertices();
      const vertexBuffer = device.createBuffer({
        label: 'vertex buffer vertices',
        size: vertexData.byteLength,
        usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
      });
      device.queue.writeBuffer(vertexBuffer, 0, vertexData);

const indexBuffer = device.createBuffer({
    label: 'index buffer',
    size: indexData.byteLength,
    usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
  });
  device.queue.writeBuffer(indexBuffer, 0, indexData);
  
      const bindGroup = device.createBindGroup({
        label: 'bind group for object',
        layout: pipeline.getBindGroupLayout(0),
        entries: [
          { binding: 0, resource: { buffer: uniformBuffer } },
        ],
      });

      const renderPassDescriptor = {
        label: 'our basic canvas renderPass',
        colorAttachments: [
          {
            // view: <- to be filled out when we render
            loadOp: 'clear',
            storeOp: 'store',
          },
        ],
      };

      function render() {

        // Get the current texture from the canvas context and
        // set it as the texture to render to.
        renderPassDescriptor.colorAttachments[0].view =
          context.getCurrentTexture().createView();

        const encoder = device.createCommandEncoder();
        const pass = encoder.beginRenderPass(renderPassDescriptor);
        pass.setPipeline(pipeline);
        pass.setVertexBuffer(0, vertexBuffer);
pass.setIndexBuffer(indexBuffer, 'uint32');
        let translationx = document
          .querySelector('input[name="translationx"]')
          .value;
        let translationy = document
          .querySelector('input[name="translationy"]')
          .value;
        let rotationx = document
          .querySelector('input[name="rotationx"]')
          .value;
        rotationx = rotationx * Math.PI / 180;
        
        let rotationy = document
          .querySelector('input[name="rotationy"]')
          .value;
        rotationy = rotationy * Math.PI / 180;
        
        let rotationz = document
          .querySelector('input[name="rotationz"]')
          .value;
        rotationz = rotationz * Math.PI / 180;

        let scalex = document
          .querySelector('input[name="scalex"]')
          .value;
        let scaley = document
          .querySelector('input[name="scaley"]')
          .value;

        let translationMatrix = glMatrix.mat4.create();
        glMatrix.mat4.translate(translationMatrix, translationMatrix, glMatrix.vec3    .fromValues(translationx, translationy,1));

        let rotationMatrix = glMatrix.mat4.create();
       // glMatrix.mat4.rotate(rotationMatrix, rotationMatrix, 1, glMatrix.vec3.fromValues(Math.sin(rotation), Math.cos(rotation), 0));
        //glMatrix.mat4.rotate(rotationMatrix, rotationMatrix, rotation);

        glMatrix.mat4.rotateX(rotationMatrix, rotationMatrix, rotationx);
        glMatrix.mat4.rotateY(rotationMatrix, rotationMatrix, rotationy);
        glMatrix.mat4.rotateZ(rotationMatrix, rotationMatrix, rotationz);

        let scaleMatrix = glMatrix.mat4.create();
        glMatrix.mat4.scale(scaleMatrix, scaleMatrix, [scalex, scaley, 1]);

        // make a matrix that will move the origin of the 'F' to its center.
        // const moveOriginMatrix = mat3.translation([-50, -75]);
        let moveOriginMatrix = glMatrix.mat4.create();
        //glMatrix.mat4.translate(moveOriginMatrix, moveOriginMatrix, glMatrix.vec2.fromValues(-50, -70));

//-------------
 //固定相机,正交投影
 //  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);
  // glMatrix.mat4.projection(projectionMatrix,400,canvas.clientWidth, canvas.clientHeight);
   glMatrix.mat4.ortho(projectionMatrix,0,canvas.clientWidth, 0,canvas.clientHeight,400,-400);
   
   /*
   mat4.ortho(
        0,                   // 左边
        canvas.clientWidth,  // 正确的
        canvas.clientHeight, // 底部
        0,                   // 顶部
        400,                 // 靠近
        -400,                // 远的
        matrixValue,         // 夏令时
    ); 
    */
//-------------
        let matrix = glMatrix.mat4.create();
        //glMatrix.mat4.multiply(matrix, translationMatrix, rotationMatrix);
        glMatrix.mat4.multiply(matrix,projectionMatrix, translationMatrix);
        glMatrix.mat4.multiply(matrix, matrix, rotationMatrix);
        glMatrix.mat4.multiply(matrix, matrix, scaleMatrix);

        // matrix = mat3.multiply(matrix, moveOriginMatrix);
        glMatrix.mat4.multiply(matrix, matrix, moveOriginMatrix);

/*
        console.log('matrix:' + matrix);
        console.log('matrix0-3:' + matrix.slice(0, 3));
        console.log('matrixValue:' + matrixValue);
*/
        // Set the uniform values in our JavaScript side Float32Array
       // resolutionValue.set([canvas.width, canvas.height]);
        
     /*
        matrixValue.set([
          ...matrix.slice(0, 3), 0,
          ...matrix.slice(3, 6), 0,
          ...matrix.slice(6, 9), 0,
        ]);
*/
 //console.log(matrix) 
  matrixValue.set(matrix);

        // upload the uniform values to the uniform buffer
        device.queue.writeBuffer(uniformBuffer, 0, uniformValues);

        pass.setBindGroup(0, bindGroup);
        // pass.drawIndexed(numVertices);
        //pass.draw(3);
        pass.drawIndexed(numVertices);
        pass.end();

        const commandBuffer = encoder.finish();
        device.queue.submit([commandBuffer]);
      }

      //-----------------
      document
        .querySelector('input[name="translationx"]')
        .addEventListener("input", (e) => {
          render();
        });

      document
        .querySelector('input[name="translationy"]')
        .addEventListener("input", (e) => {
          render();
        });
      document
        .querySelector('input[name="rotationx"]')
        .addEventListener("input", (e) => {
          render();
        });
        document
        .querySelector('input[name="rotationy"]')
        .addEventListener("input", (e) => {
          render();
        });
        document
        .querySelector('input[name="rotationz"]')
        .addEventListener("input", (e) => {
          render();
        });
      document
        .querySelector('input[name="scalex"]')
        .addEventListener("input", (e) => {
          render();
        });
      document
        .querySelector('input[name="scaley"]')
        .addEventListener("input", (e) => {
          render();
        });

      const observer = new ResizeObserver(entries => {
        for (const entry of entries) {
          const canvas = entry.target;
          const width = entry.contentBoxSize[0].inlineSize;
          const height = entry.contentBoxSize[0].blockSize;
          canvas.width = Math.max(1, Math.min(width, device.limits.maxTextureDimension2D));
          canvas.height = Math.max(1, Math.min(height, device.limits.maxTextureDimension2D));
          // re-render
          render();
        }
      });
      observer.observe(canvas);
    }

    function fail(msg) {
      alert(msg);
    }

    main();
  </script>
</body>

</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值