一个旋转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)

  // default state
  //  let aspect = size.width / size.height
 

    
    /*
     let position;
    position.x=0;
    position.y=0
    position.z= -5 
    
    let scale;
    scale.x=1
    scale.y=1
    scale.z=1 
    
    let rotation;
    rotation.x= 0
    rotation.y= 0
    rotation.z= 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() {
  
//=================================
/*   
   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>

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值