F   11/17      Volume Rendering

M   11/27      Atacama.bio Guest Lecture

F    12/01      WebGPU II

F   11/24      No class (Thanksgiving Recess)

W   11/29      Final Project Fast Forward (60 seconds each!)

M   11/20     Field Trip / Outside Lecture

W  11/22      glTF / WebGPU I

M   12/04     Final Project Presentations I

W   12/06     Final Project Presentations II

F   12/08     Skybox

M   12/11       Final Project Presentations III

W   12/13       Final Recap and Last Lecture!

F   12/22       Final Project Submission

40% of your grade

chance to pair your learned skills
with your creative ideas

can be done as a team or solo

the more impact, the better!

Final Project

Fast Forward 

Final Project

Presentation 

Code

Report

50%

30%

20%

5-min

5%

15%

40% of your grade!!!

Fast Forward (30-60 seconds)

Final Project Presentation

Final Submission

Wed 11/29

Mon 12/04

Fri 12/22

Wed 12/06

Mon 12/11

pre-recorded or live!

Slots will be assigned today!

~5 minutes

significant progress

keep it simple!

and interesting!

be loud, be proud!

in person!

Final Project Presentation

Mon 12/04

Wed 12/06

Mon 12/11

MEGA

QUIZ

Bonus only, counts as 4 quizzes!!

Soon on Blackboard!

glTF

Graphics Layer Transmission Format

google-chrome --enable-unsafe-webgpu --use-vulkan=true --test-type --enable-features=Vulkan

Assignment 6!

How do we start?

<!-- for linux: google-chrome --enable-unsafe-webgpu --use-vulkan=true --test-type --enable-features=Vulkan -->
<html>
<head>
    <title>WebGPU Hello Triangle</title>
    <style>
        html, body { width: 100%; height: 100%; padding: 0; margin: 0; }
        #c { width: 100%; height: 100%; }
    </style>
</head>
<body>
    <canvas id="c" width="600" height="600"></canvas>
    <script>
        async function initWebGPU() {

            // Ensure WebGPU is supported
            if (!navigator.gpu) {
                console.error("WebGPU is not supported. Please use a compatible browser.");
                return;
            }

            // Initialization
            const canvas = document.getElementById("c");
            const adapter = await navigator.gpu.requestAdapter();
            const device = await adapter.requestDevice();
            const context = canvas.getContext("webgpu");

            const format = navigator.gpu.getPreferredCanvasFormat();
            context.configure({
                device: device,
                format: format
            });

            // Shaders
            const shaderCode = `
                @vertex
                fn vs_main(

                  @builtin(vertex_index) VertexIndex : u32

                ) -> @builtin(position) vec4<f32> {

                  var pos = array<vec2<f32>, 3>(
                    vec2(0.0, 0.5),
                    vec2(-0.5, -0.5),
                    vec2(0.5, -0.5)
                  );

                  return vec4<f32>(pos[VertexIndex], 0.0, 1.0);

                }

                @fragment
                fn fs_main() -> @location(0) vec4<f32> {

                  return vec4(1.0, 0.0, 0.0, 1.0);

                }
            `;

            const shaderModule = device.createShaderModule({ code: shaderCode });

            // Pipeline Configuration
            const pipeline = device.createRenderPipeline({
                vertex: {
                    module: shaderModule,
                    entryPoint: "vs_main"
                },
                fragment: {
                    module: shaderModule,
                    entryPoint: "fs_main",
                    targets: [{
                        format: format
                    }]
                },
                primitive: {
                    topology: "triangle-list"
                },
                layout: "auto"
            });

            // Drawing
            const commandEncoder = device.createCommandEncoder();
            const textureView = context.getCurrentTexture().createView();
            const renderPassDescriptor = {
                colorAttachments: [{
                    view: textureView,
                    loadValue: { r: 0, g: 0, b: 0, a: 1 },
                    storeOp: 'store',
                    loadOp: 'clear'
                }]
            };

            const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
            passEncoder.setPipeline(pipeline);
            passEncoder.draw(3, 1, 0, 0);
            passEncoder.end();

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

        window.onload = initWebGPU;
    </script>
</body>
</html>

How do we start?

<html>
<head>
    <title>Babylon.js</title>
    <style>
        html, body { width: 100%; height: 100%; padding: 0; margin: 0; }
        #c { width: 100%; height: 100%; }
    </style>

    <script src="https://cdn.babylonjs.com/babylon.js"></script>

    <script>

        window.onload = async function() {

            var canvas = document.getElementById('c');

            var engine = new BABYLON.WebGPUEngine(canvas);
            await engine.initAsync();


            var scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0., 0., 0.);



            var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, 10), scene);
            camera.setTarget(BABYLON.Vector3.Zero());
            camera.attachControl(canvas, false);

            var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(1, 1, 0));



            var customMesh = new BABYLON.Mesh("custom");
            customMesh.color = new BABYLON.Color3(1., 0., 0.);

            // Set the vertices for the triangle
            var positions = [
                0, 1, 0,  // vertex 0: position (x, y, z)
                1, 0, 0,  // vertex 1
                -1, 0, 0  // vertex 2
            ];

            // Set the indices for the triangle
            var indices = [0, 1, 2];

            var colors = [1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1];

            // Create a vertexData object
            var vertexData = new BABYLON.VertexData();
            vertexData.positions = positions;
            vertexData.indices = indices;
            vertexData.colors = colors;
            vertexData.applyToMesh(customMesh);



            engine.runRenderLoop(function () {
                scene.render();
            });



            // Watch for browser/canvas resize events
            window.addEventListener("resize", function () {
                engine.resize();
            });


        };
    </script>

</head>

<body>
    <canvas id="c"></canvas>
</body>
</html>

How do we start?

<html>
<head>
    <title>Taichi.js</title>
    <style>
        html, body { width: 100%; height: 100%; padding: 0; margin: 0; }
        #c { width: 100%; height: 100%; }
    </style>

    <script src="https://unpkg.com/taichi.js/dist/taichi.umd.js"></script>

    <script>

        window.onload = async function() {

          await ti.init();

          let htmlCanvas = document.getElementById('c');
          htmlCanvas.width = 720;
          htmlCanvas.height = 360;

          let VBO = ti.field(ti.types.vector(ti.f32, 3), 3);
          let IBO = ti.field(ti.i32, 3);

          let aspectRatio = htmlCanvas.width / htmlCanvas.height;
          let target = ti.canvasTexture(htmlCanvas);
          let depth = ti.depthTexture([htmlCanvas.width, htmlCanvas.height]);

          ti.addToKernelScope({ VBO, target, IBO, aspectRatio, depth });

          await VBO.fromArray([
            [-1, 0, 0],
            [1, 0, 0],
            [0, 1, 0]
          ]);
          await IBO.fromArray([
            0, 1, 2
          ]);

          let render = ti.kernel(() => {
            
            let center = [0., 0., 0.];
            let eye = [0, 0, 3];
            let view = ti.lookAt(eye, center, [0.0, 1.0, 0.0]);
            let proj = ti.perspective(70.0, aspectRatio, 0.1, 100);
            let mvp = proj.matmul(view);

            ti.clearColor(target, [0., 0., 0., 1]);
            ti.useDepth(depth);

            for (let v of ti.inputVertices(VBO, IBO)) {
              let pos = mvp.matmul([v.x, v.y, v.z, 1.0]);
              ti.outputPosition(pos);
              ti.outputVertex(v);
            }
            for (let f of ti.inputFragments()) {
              ti.outputColor(target, [1.,0.,0.,1.]);
            }
          });

          async function frame() {

            render();
            requestAnimationFrame(frame);
          }
          requestAnimationFrame(frame);
        };


    </script>

</head>

<body>
    <canvas id="c"></canvas>
</body>
</html>

Quiz 13 due tonight!