Skip to content

Commit

Permalink
object render updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dylanebert committed Dec 10, 2023
1 parent 52721f4 commit 9382952
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 56 deletions.
52 changes: 50 additions & 2 deletions src/renderers/WebGLRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ShaderPass } from "./webgl/passes/ShaderPass";
import { FadeInPass } from "./webgl/passes/FadeInPass";
import { RenderTexture } from "./webgl/utils/RenderTexture";
import { Camera } from "../cameras/Camera";
import { ObjectAddedEvent, ObjectChangedEvent } from "../events/Events";
import { Splat } from "../splats/Splat";

export class WebGLRenderer {
private _domElement: HTMLCanvasElement;
Expand Down Expand Up @@ -202,22 +204,42 @@ export class WebGLRenderer {
initialized = true;
};

const handleObjectAdded = () => {
const handleObjectAdded = (event: Event) => {
const e = event as ObjectAddedEvent;

if (e.object instanceof Splat) {
e.object.addEventListener("changed", handleObjectChanged);
}

if (initialized) {
this.dispose();
}

initWebGL();
};

const handleObjectRemoved = () => {
const handleObjectRemoved = (event: Event) => {
const e = event as ObjectAddedEvent;

if (e.object instanceof Splat) {
e.object.removeEventListener("changed", handleObjectChanged);
}

if (initialized) {
this.dispose();
}

initWebGL();
};

const handleObjectChanged = (event: Event) => {
const e = event as ObjectChangedEvent;

if (e.object instanceof Splat) {
renderTexture.markDirty(e.object);
}
};

this.render = (scene: Scene) => {
if (scene !== activeScene) {
if (initialized) {
Expand All @@ -228,6 +250,11 @@ export class WebGLRenderer {
if (activeScene) {
activeScene.removeEventListener("objectAdded", handleObjectAdded);
activeScene.removeEventListener("objectRemoved", handleObjectRemoved);
for (const object of activeScene.objects) {
if (object instanceof Splat) {
object.removeEventListener("objectChanged", handleObjectChanged);
}
}
}
activeScene = scene;
activeCamera = scene.findObjectOfType(Camera) as Camera;
Expand All @@ -238,6 +265,11 @@ export class WebGLRenderer {
activeCamera.update();
activeScene.addEventListener("objectAdded", handleObjectAdded);
activeScene.addEventListener("objectRemoved", handleObjectRemoved);
for (const object of activeScene.objects) {
if (object instanceof Splat) {
object.addEventListener("objectChanged", handleObjectChanged);
}
}
}

initWebGL();
Expand All @@ -246,6 +278,22 @@ export class WebGLRenderer {
activeCamera.update();
worker.postMessage({ viewProj: activeCamera.data.viewProj });

if (renderTexture.dirty) {
renderTexture.rebuild();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA32UI,
renderTexture.width,
renderTexture.height,
0,
gl.RGBA_INTEGER,
gl.UNSIGNED_INT,
renderTexture.buffer,
);
}

if (renderTexture.vertexCount > 0) {
for (const shaderPass of shaderPasses) {
shaderPass.render();
Expand Down
127 changes: 73 additions & 54 deletions src/renderers/webgl/utils/RenderTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class RenderTexture {
private _height: number;
private _positions: Float32Array;
private _vertexCount: number;
private _dirty: Set<Splat> = new Set<Splat>();

markDirty: (splat: Splat) => void;
rebuild: () => void;

constructor(scene: Scene) {
const _floatView: Float32Array = new Float32Array(1);
Expand Down Expand Up @@ -49,9 +53,12 @@ class RenderTexture {
};

let vertexCount = 0;
const offsets = new Map<Splat, number>();
for (const object of scene.objects) {
if (object instanceof Splat) {
offsets.set(object, vertexCount);
vertexCount += object.data.vertexCount;
this._dirty.add(object);
}
}

Expand All @@ -64,62 +71,70 @@ class RenderTexture {
const data_f = new Float32Array(this._buffer.buffer);
const data_c = new Uint8Array(this._buffer.buffer);

let offset = 0;
for (const object of scene.objects) {
if (object instanceof Splat) {
const splat = object.data;
const positions = splat.positions;
const rotations = splat.rotations;
const scales = splat.scales;
const colors = splat.colors;
for (let i = 0; i < object.data.vertexCount; i++) {
const index = offset + i;

data_f[8 * index + 0] = positions[3 * i + 0];
data_f[8 * index + 1] = positions[3 * i + 1];
data_f[8 * index + 2] = positions[3 * i + 2];

this.positions[3 * index + 0] = positions[3 * i + 0];
this.positions[3 * index + 1] = positions[3 * i + 1];
this.positions[3 * index + 2] = positions[3 * i + 2];

data_c[4 * (8 * index + 7) + 0] = colors[4 * i + 0];
data_c[4 * (8 * index + 7) + 1] = colors[4 * i + 1];
data_c[4 * (8 * index + 7) + 2] = colors[4 * i + 2];
data_c[4 * (8 * index + 7) + 3] = colors[4 * i + 3];

const rot = Matrix3.RotationFromQuaternion(
new Quaternion(
rotations[4 * i + 1],
rotations[4 * i + 2],
rotations[4 * i + 3],
-rotations[4 * i + 0],
),
);

const scale = Matrix3.Diagonal(
new Vector3(scales[3 * i + 0], scales[3 * i + 1], scales[3 * i + 2]),
);

const M = scale.multiply(rot).buffer;

const sigma = [
M[0] * M[0] + M[3] * M[3] + M[6] * M[6],
M[0] * M[1] + M[3] * M[4] + M[6] * M[7],
M[0] * M[2] + M[3] * M[5] + M[6] * M[8],
M[1] * M[1] + M[4] * M[4] + M[7] * M[7],
M[1] * M[2] + M[4] * M[5] + M[7] * M[8],
M[2] * M[2] + M[5] * M[5] + M[8] * M[8],
];

this.buffer[8 * index + 4] = packHalf2x16(4 * sigma[0], 4 * sigma[1]);
this.buffer[8 * index + 5] = packHalf2x16(4 * sigma[2], 4 * sigma[3]);
this.buffer[8 * index + 6] = packHalf2x16(4 * sigma[4], 4 * sigma[5]);
}
const build = (splat: Splat) => {
const data = splat.data;
const positions = data.positions;
const rotations = data.rotations;
const scales = data.scales;
const colors = data.colors;
for (let i = 0; i < splat.data.vertexCount; i++) {
const offset = offsets.get(splat) as number;
const index = offset + i;

data_f[8 * index + 0] = positions[3 * i + 0];
data_f[8 * index + 1] = positions[3 * i + 1];
data_f[8 * index + 2] = positions[3 * i + 2];

this.positions[3 * index + 0] = positions[3 * i + 0];
this.positions[3 * index + 1] = positions[3 * i + 1];
this.positions[3 * index + 2] = positions[3 * i + 2];

data_c[4 * (8 * index + 7) + 0] = colors[4 * i + 0];
data_c[4 * (8 * index + 7) + 1] = colors[4 * i + 1];
data_c[4 * (8 * index + 7) + 2] = colors[4 * i + 2];
data_c[4 * (8 * index + 7) + 3] = colors[4 * i + 3];

const rot = Matrix3.RotationFromQuaternion(
new Quaternion(
rotations[4 * i + 1],
rotations[4 * i + 2],
rotations[4 * i + 3],
-rotations[4 * i + 0],
),
);

const scale = Matrix3.Diagonal(new Vector3(scales[3 * i + 0], scales[3 * i + 1], scales[3 * i + 2]));

const M = scale.multiply(rot).buffer;

const sigma = [
M[0] * M[0] + M[3] * M[3] + M[6] * M[6],
M[0] * M[1] + M[3] * M[4] + M[6] * M[7],
M[0] * M[2] + M[3] * M[5] + M[6] * M[8],
M[1] * M[1] + M[4] * M[4] + M[7] * M[7],
M[1] * M[2] + M[4] * M[5] + M[7] * M[8],
M[2] * M[2] + M[5] * M[5] + M[8] * M[8],
];

this.buffer[8 * index + 4] = packHalf2x16(4 * sigma[0], 4 * sigma[1]);
this.buffer[8 * index + 5] = packHalf2x16(4 * sigma[2], 4 * sigma[3]);
this.buffer[8 * index + 6] = packHalf2x16(4 * sigma[4], 4 * sigma[5]);
}
};

this.markDirty = (splat: Splat) => {
this._dirty.add(splat);
};

offset += splat.vertexCount;
this.rebuild = () => {
for (const splat of this._dirty) {
build(splat);
}
}

this._dirty.clear();
};

this.rebuild();
}

get buffer() {
Expand All @@ -141,6 +156,10 @@ class RenderTexture {
get vertexCount() {
return this._vertexCount;
}

get dirty() {
return this._dirty.size > 0;
}
}

export { RenderTexture };

0 comments on commit 9382952

Please sign in to comment.