Skip to content

Commit

Permalink
Merge pull request #2 from JediWattson/cleanup
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
JediWattson authored Jan 7, 2024
2 parents 7b31667 + 419c446 commit e80c46b
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 118 deletions.
88 changes: 52 additions & 36 deletions lib/buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,15 @@ import { mat4, vec3 } from "gl-matrix";
type CreateModelType = (pos: vec3, i: number) => mat4

export type MaterialBufferType = {
buffer: GPUBuffer,
bufferLayout: GPUVertexBufferLayout,
type: string,
buffer: GPUBuffer,
update: (createModel: CreateModelType) => void,
makeObjects: (count: number, isFloor?: boolean) => void,
getCount: () => number
}

export const meshBufferLayout: GPUVertexBufferLayout = {
arrayStride: 24,
attributes: [
{
shaderLocation: 0,
format: `float32x3`,
offset: 0
},
{
shaderLocation: 1,
format: `float32x3`,
offset: 12
}
]
}

const makeBuffer = (posByteCount: 2 | 3, colorByteCount: 2 | 3, verticesCoords: number[]) =>
(device: GPUDevice, objBuffer: GPUBuffer, offset: number = 0) => {
const makeBuffer = (verticesCoords: number[], type: string) =>
(device: GPUDevice, objBuffer: GPUBuffer, offset: number = 0): MaterialBufferType => {

const vertices = new Float32Array(verticesCoords);
const descriptor: GPUBufferDescriptor = {
Expand All @@ -45,14 +30,12 @@ const makeBuffer = (posByteCount: 2 | 3, colorByteCount: 2 | 3, verticesCoords:
if (isFloor) {
for (var x: number = -count; x <= count; x++) {
for (var y: number = -count; y <= count; y++) {
objects.push([x, y, -1]);
console.log([x, y, -1]);

objects.push([x, y, -1]);
}
}
} else {
for(let i = 0; i < count; i++) {
objects.push([2, i, 0]);
objects.push([2, i, -0.5]);
}
}
}
Expand All @@ -65,6 +48,7 @@ const makeBuffer = (posByteCount: 2 | 3, colorByteCount: 2 | 3, verticesCoords:
}

return {
type,
buffer,
getCount() {
return objects.length;
Expand All @@ -75,19 +59,51 @@ const makeBuffer = (posByteCount: 2 | 3, colorByteCount: 2 | 3, verticesCoords:
};

// each point contains 3 position values, 3 color values
export const makeTriangle = makeBuffer(3, 3, [
export const makeTriangle = makeBuffer([
0.0, 0.0, 0.5, 1.0, 0.0, 0.0,
0.0, -0.5, -0.5, 0.0, 1.0, 0.0,
0.0, 0.5, -0.5, 0.0, 0.0, 1.0
])
0.0, -0.5, -0.5, 0.0, 1.0, 0.0,
0.0, 0.5, -0.5, 0.0, 0.0, 1.0
], "TRI")

// each point contains 3 position values, 2 texture pos values
export const makeQuad = makeBuffer(3, 3, [
-0.5, 0.5, 0.0, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.0, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.0, 0.0, 1.0,
export const makeQuad = makeBuffer([
-0.5, 0.5, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.0, 1.0, 1.0,
0.5, -0.5, 0.0, 0.0, 1.0,

0.5, -0.5, 0.0, 0.0, 1.0,
0.5, 0.5, 0.0, 0.0, 0.0,
-0.5, 0.5, 0.0, 1.0, 0.0,
], "QUAD")

export const meshBufferLayout: GPUVertexBufferLayout = {
arrayStride: 24,
attributes: [
{
shaderLocation: 0,
format: `float32x3`,
offset: 0
},
{
shaderLocation: 1,
format: `float32x3`,
offset: 12
}
]
}

0.5, -0.5, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, 0.0, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.0, 0.0, 1.0, 0.0,
])
export const textureBufferLayout: GPUVertexBufferLayout = {
arrayStride: 20,
attributes: [
{
shaderLocation: 0,
format: `float32x3`,
offset: 0
},
{
shaderLocation: 1,
format: `float32x2`,
offset: 12
}
]
}
128 changes: 63 additions & 65 deletions lib/hooks/useRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,39 @@ import { KeyboardEvent, MouseEvent, useEffect, useRef } from "react";

import textureShader from '../shaders/texture.wgsl';
import meshShader from '../shaders/mesh.wgsl';

import { makeQuad, makeTriangle, meshBufferLayout } from "../buffer";
import { CameraType } from "../camera";
import makeMaterial from "../material";

import {
makeQuad,
makeTriangle,
meshBufferLayout,
textureBufferLayout
} from "../buffer";

import {
CanvasRefType,
PipelineType,
makeBindGroup,
makeCamera,
makeDepthStencil,
makePipeline,
updateFloor,
updateTriangles
} from "../utils";

const triangleCount = 40;
const floorCount = 10;

function startPipeline(
device: GPUDevice,
context: GPUCanvasContext,
pipeline: GPURenderPipeline,
objectBindGroup: GPUBindGroup,
pipelines: PipelineType[],
pipelines: PipelineType[]
): () => void {
const depthStencilAttachment = makeDepthStencil(device);

const triangleMaterial = pipelines[1].material;
updateTriangles(triangleMaterial);
updateFloor(pipelines[0].material);

let frameId: number;
function frame() {

updateTriangles(triangleMaterial);
const commandEncoder = device.createCommandEncoder();
const textureView = context.getCurrentTexture().createView();

Expand All @@ -49,17 +51,24 @@ function startPipeline(
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(pipeline);
passEncoder.setBindGroup(0, objectBindGroup);

let objectCount = 0
pipelines.forEach(({ bindGroup, material }, i) => {
passEncoder.setVertexBuffer(0, material.buffer);
// passEncoder.setBindGroup(1, bindGroup);
const currentCount = material.getCount();
passEncoder.draw( i === 0 ? 6 : 3, currentCount, 0, objectCount);
objectCount += currentCount
pipelines.forEach(({ bindGroups, pipeline, materials }) => {
passEncoder.setPipeline(pipeline);
bindGroups.forEach((bindGroup, i) => {
passEncoder.setBindGroup(i, bindGroup);
})
let objectCount = 0
materials.forEach((material, i) => {
if (material.type === "TRI") updateTriangles(material);

passEncoder.setVertexBuffer(0, material.buffer);
const currentCount = material.getCount();
const vertices = material.type === "QUAD" ? 6 : 3;
passEncoder.draw(vertices, currentCount, 0, objectCount);
objectCount += currentCount

})
})

passEncoder.end();

device.queue.submit([commandEncoder.finish()]);
Expand Down Expand Up @@ -93,59 +102,48 @@ function useRender(canvasRef: { current: CanvasRefType }) {

const cameraBuffer = makeCamera(device, camera)

const triangleCount = 4;
const floorCount = 1;
const objectBuffer = device.createBuffer({
size: 64 * 4 * (triangleCount + floorCount),
const meshBuffer = device.createBuffer({
size: 64 * triangleCount,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
})

const triangleMesh = makeTriangle(device, meshBuffer);
triangleMesh.makeObjects(triangleCount);
updateTriangles(triangleMesh);

const meshBindGroup = makeBindGroup(device, [cameraBuffer, meshBuffer]);
const pipeline = makePipeline(
device,
meshShader,
meshBufferLayout,
[meshBindGroup],
[triangleMesh]
);

const textureBuffer = device.createBuffer({
size: 64 * (1 + (floorCount*2))**2,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
})
const floorMesh = makeQuad(device, objectBuffer);

const floorMesh = makeQuad(device, textureBuffer);
floorMesh.makeObjects(floorCount, true);
updateFloor(floorMesh);

const floorTexture = await makeMaterial(device, 'floor.jpeg')
const textureBindGroup = makeBindGroup(device, [cameraBuffer, textureBuffer]);

const triangleMesh = makeTriangle(device, objectBuffer, floorMesh.getCount());
triangleMesh.makeObjects(triangleCount);

const objectBindGroup = makeBindGroup(device, [cameraBuffer, objectBuffer]);
const texturePipeline = makePipeline(
device,
textureShader,
textureBufferLayout,
[textureBindGroup, floorTexture],
[floorMesh]
);

const pipelineLayout = device.createPipelineLayout({
bindGroupLayouts: [objectBindGroup.bindGroupLayout]
})

const pipeline = device.createRenderPipeline({
layout: pipelineLayout,
depthStencil: {
format: "depth32float",
depthWriteEnabled: true,
depthCompare: "less-equal"
},
vertex: {
entryPoint: "vs_main",
module: device.createShaderModule({
code: meshShader
}),
buffers: [meshBufferLayout]
},
fragment: {
entryPoint: "fs_main",
module: device.createShaderModule({
code: meshShader
}),
targets: [{ format }]
},
primitive : {
topology : "triangle-list"
},
})

cleanup.current = startPipeline(
device,
context,
pipeline,
objectBindGroup.bindGroup,
[{ ...floorTexture, material: floorMesh }, { material: triangleMesh }]

[pipeline, texturePipeline]
);
}

Expand Down
5 changes: 2 additions & 3 deletions lib/material.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { BindGroupType } from "./utils";

export type MaterialType = {
bindGroup: GPUBindGroup,
bindGroupLayout: GPUBindGroupLayout,
texture: GPUTexture
}

export default async function makeMaterial(device: GPUDevice, url: string): Promise<MaterialType> {
export default async function makeMaterial(device: GPUDevice, url: string): Promise<MaterialType & BindGroupType> {
const response: Response = await fetch(url);
const blob: Blob = await response.blob();
const imageData: ImageBitmap = await createImageBitmap(blob);
Expand Down
7 changes: 4 additions & 3 deletions lib/shaders/mesh.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ struct TransformData {
view: mat4x4<f32>,
projection: mat4x4<f32>,
};
@binding(0) @group(0) var<uniform> transformUBO: TransformData;

struct ObjectData {
model: array<mat4x4<f32>>
}
@binding(1) @group(0) var<storage, read> objects: ObjectData;

struct Fragment {
@builtin(position) Position : vec4<f32>,
@location(0) Color : vec4<f32>
@location(0) Color : vec4<f32>,
}

@binding(0) @group(0) var<uniform> transformUBO: TransformData;
@binding(1) @group(0) var<storage, read> objects: ObjectData;

@vertex
fn vs_main(
@builtin(instance_index) ID: u32,
Expand Down
Loading

0 comments on commit e80c46b

Please sign in to comment.