Naloga 2: C0 and C1
This commit is contained in:
6006
vaja_1/glm.js
Normal file
6006
vaja_1/glm.js
Normal file
File diff suppressed because it is too large
Load Diff
188
vaja_1/main.js
188
vaja_1/main.js
@@ -1,51 +1,33 @@
|
||||
import { mat4 } from './glm.js';
|
||||
|
||||
// Initialize WebGPU
|
||||
const adapter = await navigator.gpu.requestAdapter();
|
||||
const device = await adapter.requestDevice();
|
||||
const canvas = document.querySelector('canvas');
|
||||
const context = canvas.getContext('webgpu');
|
||||
|
||||
const format = 'rgba8unorm';
|
||||
const format = navigator.gpu.getPreferredCanvasFormat();
|
||||
context.configure({ device, format });
|
||||
|
||||
// Create shaders
|
||||
const code = await fetch('shader.wgsl').then((res) => res.text());
|
||||
const module = device.createShaderModule({ code });
|
||||
|
||||
// Create vertex buffer layouts
|
||||
/** @type {GPUVertexBufferLayout} */
|
||||
const vertexBufferLayout = {
|
||||
arrayStride: 32,
|
||||
attributes: [
|
||||
{
|
||||
offset: 0,
|
||||
format: 'float32x4',
|
||||
shaderLocation: 0,
|
||||
},
|
||||
{
|
||||
offset: 16,
|
||||
format: 'float32x4',
|
||||
shaderLocation: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Create render pipeline
|
||||
const pipeline = device.createRenderPipeline({
|
||||
vertex: {
|
||||
module,
|
||||
buffers: [vertexBufferLayout],
|
||||
},
|
||||
fragment: {
|
||||
module,
|
||||
targets: [{ format }],
|
||||
},
|
||||
layout: 'auto',
|
||||
// Create depth texture
|
||||
const depthTexture = device.createTexture({
|
||||
size: [canvas.width, canvas.height],
|
||||
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
||||
format: 'depth24plus',
|
||||
});
|
||||
|
||||
// Create vertex buffer
|
||||
// prettier-ignore
|
||||
const vertices = new Float32Array([
|
||||
0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1,
|
||||
1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1,
|
||||
// position // color
|
||||
-1, -1, -1, 1, 1, 0, 0, 1,
|
||||
1, -1, -1, 1, 0, 1, 0, 1,
|
||||
-1, 1, -1, 1, 0, 0, 1, 1,
|
||||
1, 1, -1, 1, 1, 1, 0, 1,
|
||||
|
||||
-1, 1, 1, 1, 1, 0, 0, 1,
|
||||
1, -1, 1, 1, 0, 1, 0, 1,
|
||||
-1, 1, 1, 1, 0, 0, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 1,
|
||||
]);
|
||||
|
||||
const vertexBuffer = device.createBuffer({
|
||||
@@ -55,7 +37,16 @@ const vertexBuffer = device.createBuffer({
|
||||
|
||||
device.queue.writeBuffer(vertexBuffer, 0, vertices);
|
||||
|
||||
const indices = new Uint32Array([0, 1, 2, 1, 2, 3]);
|
||||
// Create index buffer
|
||||
// prettier-ignore
|
||||
const indices = new Uint32Array([
|
||||
0, 1, 2, 1, 2, 3,
|
||||
0, 1, 3, 1, 4, 5,
|
||||
0, 4, 2, 4, 2, 5,
|
||||
1, 5, 3, 5, 3, 7,
|
||||
2, 3, 6, 3, 6, 7,
|
||||
4, 5, 6, 5, 6, 7,
|
||||
]);
|
||||
|
||||
const indexBuffer = device.createBuffer({
|
||||
size: indices.byteLength,
|
||||
@@ -64,27 +55,114 @@ const indexBuffer = device.createBuffer({
|
||||
|
||||
device.queue.writeBuffer(indexBuffer, 0, indices);
|
||||
|
||||
// Create command encoder
|
||||
const commandEncoder = device.createCommandEncoder();
|
||||
// Fetch and compile shaders
|
||||
const code = await fetch('shader.wgsl').then((response) => response.text());
|
||||
const module = device.createShaderModule({ code });
|
||||
|
||||
// Encode render pass
|
||||
const renderPass = commandEncoder.beginRenderPass({
|
||||
colorAttachments: [
|
||||
// Create the pipeline
|
||||
/** @type {GPUVertexBufferLayout} */
|
||||
const vertexBufferLayout = {
|
||||
arrayStride: 24,
|
||||
attributes: [
|
||||
{
|
||||
view: context.getCurrentTexture().createView(),
|
||||
loadOp: 'clear',
|
||||
clearValue: [1, 1, 1, 1],
|
||||
storeOp: 'store',
|
||||
shaderLocation: 0,
|
||||
offset: 0,
|
||||
format: 'float32x2',
|
||||
},
|
||||
{
|
||||
shaderLocation: 1,
|
||||
offset: 8,
|
||||
format: 'float32x4',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const pipeline = device.createRenderPipeline({
|
||||
vertex: {
|
||||
module,
|
||||
buffers: [vertexBufferLayout],
|
||||
},
|
||||
fragment: {
|
||||
module,
|
||||
targets: [{ format }],
|
||||
},
|
||||
depthStencil: {
|
||||
depthWriteEnabled: true,
|
||||
depthCompare: 'less',
|
||||
format: 'depth24plus',
|
||||
},
|
||||
layout: 'auto',
|
||||
});
|
||||
renderPass.setPipeline(pipeline);
|
||||
renderPass.setVertexBuffer(0, vertexBuffer);
|
||||
renderPass.setIndexBuffer(indexBuffer, 'uint32');
|
||||
renderPass.drawIndexed(indices.length);
|
||||
renderPass.end();
|
||||
|
||||
const commandBuffer = commandEncoder.finish();
|
||||
// Create uniform buffer
|
||||
const uniformBuffer = device.createBuffer({
|
||||
size: 4 * 4 * 4,
|
||||
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
||||
});
|
||||
|
||||
// Send commands to GPU
|
||||
device.queue.submit([commandBuffer]);
|
||||
// Create the bind group
|
||||
const bindGroup = device.createBindGroup({
|
||||
layout: pipeline.getBindGroupLayout(0),
|
||||
entries: [{ binding: 0, resource: { buffer: uniformBuffer } }],
|
||||
});
|
||||
|
||||
function update() {
|
||||
// Animate the square
|
||||
const time = performance.now() / 1000;
|
||||
|
||||
const modelMatrix = mat4
|
||||
.create()
|
||||
.rotateX(time * 0.7)
|
||||
.rotateY(time);
|
||||
const viewMatrix = mat4.create().translate([0, 0, 5]).invert();
|
||||
const projectionMatrix = mat4.create().perspectiveZO(1, 1, 0.01, 100);
|
||||
|
||||
const matrix = mat4
|
||||
.create()
|
||||
.multiply(projectionMatrix)
|
||||
.multiply(viewMatrix)
|
||||
.multiply(modelMatrix);
|
||||
|
||||
// const radius = 0.5;
|
||||
// const frequency = 0.5;
|
||||
// const x = radius * Math.cos(frequency * time * 2 * Math.PI);
|
||||
// const y = radius * Math.sin(frequency * time * 2 * Math.PI);
|
||||
|
||||
device.queue.writeBuffer(uniformBuffer, 0, matrix);
|
||||
}
|
||||
|
||||
function render() {
|
||||
// Render the square
|
||||
const commandEncoder = device.createCommandEncoder();
|
||||
const renderPass = commandEncoder.beginRenderPass({
|
||||
colorAttachments: [
|
||||
{
|
||||
view: context.getCurrentTexture().createView(),
|
||||
loadOp: 'clear',
|
||||
clearValue: [1, 1, 1, 1],
|
||||
storeOp: 'store',
|
||||
},
|
||||
],
|
||||
depthStencilAttachment: {
|
||||
view: depthTexture.createView(),
|
||||
depthLoadOp: 'clear',
|
||||
depthClearValue: 1,
|
||||
depthStoreOp: 'discard',
|
||||
},
|
||||
});
|
||||
renderPass.setPipeline(pipeline);
|
||||
renderPass.setVertexBuffer(0, vertexBuffer);
|
||||
renderPass.setIndexBuffer(indexBuffer, 'uint32');
|
||||
renderPass.setBindGroup(0, bindGroup);
|
||||
renderPass.drawIndexed(indices.length);
|
||||
renderPass.end();
|
||||
device.queue.submit([commandEncoder.finish()]);
|
||||
}
|
||||
|
||||
function frame() {
|
||||
update();
|
||||
render();
|
||||
requestAnimationFrame(frame);
|
||||
}
|
||||
|
||||
requestAnimationFrame(frame);
|
||||
|
||||
@@ -1,17 +1,38 @@
|
||||
struct VertexInput {
|
||||
@location(0) position: vec4f,
|
||||
@location(1) color: vec4f,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) position: vec4f,
|
||||
@location(0) color: vec4f,
|
||||
}
|
||||
|
||||
struct FragmentInput {
|
||||
@location(0) color: vec4f,
|
||||
}
|
||||
|
||||
struct FragmentOutput {
|
||||
@location(0) color: vec4f,
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<uniform> mtrx: mat4x4f;
|
||||
|
||||
@vertex
|
||||
fn vertex(@location(0) position: vec4f, @location(1) color: vec4f) -> VertexOutput {
|
||||
fn vertex(input: VertexInput) -> VertexOutput {
|
||||
var output: VertexOutput;
|
||||
output.position = position;
|
||||
output.color = color;
|
||||
|
||||
output.position = mtrx * input.position;
|
||||
output.color = input.color;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment(@location(0) color: vec4f) -> @location(0) vec4f {
|
||||
return color;
|
||||
fn fragment(input: FragmentInput) -> FragmentOutput {
|
||||
var output: FragmentOutput;
|
||||
|
||||
output.color = input.color;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user