www.xbdev.net
xbdev - software development
Saturday June 13, 2026
Home | Contact | Support | WebGPU Graphics and Compute ... | WebGPU.. Games, Tutorials, Demos, Projects, and Code.....
     
 

WebGPU..

Games, Tutorials, Demos, Projects, and Code.....

 


Camera Mouse Control


Using the keyboard to control the camera location.


Single triangle provides a point of references for our camera - as we move around we see the triangle moving.
Single triangle provides a point of references for our camera - as we move around we see the triangle moving.


Functions Used: setVertexBuffer(), setIndexBuffer(), drawIndexed(), createBuffer(), getMappedRange(), getContext(), requestAdapter(), getPreferredCanvasFormat(), createCommandEncoder(), beginRenderPass(), setPipeline(), draw(), end(), submit(), getCurrentTexture(), createView(), createShaderModule()

The cameras `eye`, `at` and `direction` are stored - we then check for key events using the `onkeydown`. Then we can update the camera dynamically on the fly. The camera displacement step is set as a fixed size.

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

let counter     = 0.0;
let frameNumber = 0;
let fpsTime     = performance.now();


let cameraAt  = [ 0, 0, 0 ];
let cameraDir = [ 0, 0, 1 ];
let cameraEye = [ cameraAt[0]-cameraDir[0], 
                  cameraAt[1]-cameraDir[1],  
                  cameraAt[2]-cameraDir[2] ];


function frame() 
{
  var startTime = performance.now();

  // setup a transform for triangle 
  const t = { p:{x:0,y:0,z:0}, r:{x:0,y:0.0,z:0.0}, s:{x:1.0, y:1.0,z:1.0} };

  let modelMatrix = buildMatrix(t.p, t.r, t.s);
  // update the local matrix for each triangle draw differently
  device.queue.writeBuffer(mvpUniformBuffer,      0,      modelMatrix);

  // Rotate the camera around the origin in the circle
  mat4.lookAt(viewMatrix, cameraEye,  cameraAt, [0, 1, 0]);
  device.queue.writeBuffer(mvpUniformBuffer,      64,     viewMatrix);

  // simple counter
  counter += 0.001;

  const k = 0;
  const renderPassDescription = {
    colorAttachments: [{
      view: context.getCurrentTexture().createView(),
      loadOp: (k==0 ? "clear":"load"), 
      clearValue: [0, 0.5, 0.5, 1], // clear screen to color
      storeOp: 'store'
    }],
    depthStencilAttachment: {
      view: depthTexture.createView(),
      depthLoadOp: (k==0 ? "clear":"load"), 
      depthClearValue: 1,
      depthStoreOp: "store",
    }
  };

  renderPassDescription.colorAttachments[0].view = context.getCurrentTexture().createView();
  const commandEncoder = device.createCommandEncoder();
  const renderPass = commandEncoder.beginRenderPass(renderPassDescription);

  renderPass.setBindGroup(0, uniformBindGroup);
  renderPass.setPipeline(pipeline);
  renderPass.setVertexBuffer(0, positionBuffer);
  renderPass.setVertexBuffer(1, colorBuffer);
  renderPass.setIndexBuffer(indexBuffer, 'uint16');
  renderPass.drawIndexed(3,1);
  renderPass.end();
  device.queue.submit([commandEncoder.finish()]);

  // animate - keep updating
  requestAnimationFrame(frame);
  
  // --------- Timing Information -------------------------
  frameNumber++;
  var endTime = performance.now();

  var updateFPS = 1000.0 / ( endTime - fpsTime);
  var maxFPS    = 1000.0 / ( endTime - startTime);
  
      
  fpsTime = endTime;
  
  
  divInfo.innerHTML = `
  Cursor Keys to Move Forward/Backward Left/Right<br>
  Frame Number: ${frameNumber}<br>
  Current FPS: ${updateFPS.toFixed(1)},<br>
  Max FPS: ${maxFPS.toFixed(2)}
  `;
} 


onkeydown = function( e )
{
  let dt = 0.2;
  
  switch (event.key) 
  {
    case "ArrowLeft":
    {
        cameraAt[0] += dt;
    }
    break;
    
    case "ArrowRight":
    {
       cameraAt[0] -= dt;
    }  
    break;
      
    case "ArrowUp":
    {
       cameraAt[2] += dt;
    }
    break;
    
    case "ArrowDown":
    {
       cameraAt[2] -= dt;
    }
    break;
  }// end switch(..)
  
  cameraEye = [ cameraAt[0]-cameraDir[0], 
                cameraAt[1]-cameraDir[1],  
                cameraAt[2]-cameraDir[2] ];

}// end onkeydown(..)

frame();


console.log('ready...');



Resources and Links


• WebGPU Example Link [LINK]









































WebGPU by Example: Fractals, Image Effects, Ray-Tracing, Procedural Geometry, 2D/3D, Particles, Simulations WebGPU Compute graphics and animations using the webgpu api 12 week course kenwright learn webgpu api kenwright programming compute and graphics applications with html5 and webgpu api kenwright real-time 3d graphics with webgpu kenwright webgpu api develompent a quick start guide kenwright webgpu by example 2022 kenwright webgpu gems kenwright webgpu interactive compute and graphics visualization cookbook kenwright wgsl webgpu shading language cookbook kenwright wgsl webgpugems shading language cookbook kenwright



 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2026 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.