Skip to content

Commit

Permalink
WebGPURenderer: Support BatchMesh (#871)
Browse files Browse the repository at this point in the history
* Update

* Add examples

* Updates

* Update patch

* Delete examples
  • Loading branch information
Methuselah96 authored Mar 23, 2024
1 parent ccaac26 commit a73ee28
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 4 deletions.
125 changes: 125 additions & 0 deletions examples-testing/changes.patch
Original file line number Diff line number Diff line change
Expand Up @@ -14192,6 +14192,131 @@ index fbbabfc..a1a82bd 100644
}
}

diff --git a/examples-testing/examples/webgpu_mesh_batch.ts b/examples-testing/examples/webgpu_mesh_batch.ts
index 028192e..48fb520 100644
--- a/examples-testing/examples/webgpu_mesh_batch.ts
+++ b/examples-testing/examples/webgpu_mesh_batch.ts
@@ -4,15 +4,15 @@ import Stats from 'stats-gl';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-import { radixSort } from 'three/addons/utils/SortUtils.js';
+import { RadixSortOptions, radixSort } from 'three/addons/utils/SortUtils.js';
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
import { MeshNormalNodeMaterial } from 'three/nodes';

-let camera, scene, renderer;
-let controls, stats;
+let camera: THREE.PerspectiveCamera, scene: THREE.Scene, renderer: WebGPURenderer;
+let controls: OrbitControls, stats: Stats;
let gui;
-let geometries, mesh, material;
-const ids = [];
+let geometries: THREE.BufferGeometry[], mesh: THREE.BatchedMesh, material: MeshNormalNodeMaterial;
+const ids: number[] = [];

const matrix = new THREE.Matrix4();

@@ -42,7 +42,7 @@ init();

//

-function randomizeMatrix(matrix) {
+function randomizeMatrix(matrix: THREE.Matrix4) {
position.x = Math.random() * 40 - 20;
position.y = Math.random() * 40 - 20;
position.z = Math.random() * 40 - 20;
@@ -58,7 +58,7 @@ function randomizeMatrix(matrix) {
return matrix.compose(position, quaternion, scale);
}

-function randomizeRotationSpeed(rotation) {
+function randomizeRotationSpeed(rotation: THREE.Euler) {
rotation.x = Math.random() * 0.01;
rotation.y = Math.random() * 0.01;
rotation.z = Math.random() * 0.01;
@@ -83,7 +83,7 @@ function createMaterial() {

function cleanup() {
if (mesh) {
- mesh.parent.remove(mesh);
+ mesh.parent!.remove(mesh);

if (mesh.dispose) {
mesh.dispose();
@@ -133,7 +133,7 @@ function init(forceWebGL = false) {
document.body.removeChild(renderer.domElement);
}

- document.getElementById('backend').innerText = 'Active Backend: ' + (forceWebGL ? 'WebGL' : 'WebGPU');
+ document.getElementById('backend')!.innerText = 'Active Backend: ' + (forceWebGL ? 'WebGL' : 'WebGPU');
// camera

const aspect = window.innerWidth / window.innerHeight;
@@ -184,7 +184,7 @@ function init(forceWebGL = false) {
// gui

gui = new GUI();
- gui.add(api, 'webgpu', true).onChange(() => {
+ gui.add(api, 'webgpu').onChange(() => {
init(!api.webgpu);
});
gui.add(api, 'count', 1, MAX_GEOMETRY_COUNT).step(1).onChange(initMesh);
@@ -211,18 +211,13 @@ function init(forceWebGL = false) {
window.addEventListener('resize', onWindowResize);

function onWindowResize() {
- renderer.setSize(window.innerWidth, window.innerHeight);
-
- const aspect = window.innerWidth / window.innerHeight;
-
- camera.aspect = aspect;
-
- const frustumHeight = camera.top - camera.bottom;
-
- camera.left = (-frustumHeight * aspect) / 2;
- camera.right = (frustumHeight * aspect) / 2;
+ const width = window.innerWidth;
+ const height = window.innerHeight;

+ camera.aspect = width / height;
camera.updateProjectionMatrix();
+
+ renderer.setSize(width, height);
}

async function animate() {
@@ -257,18 +252,26 @@ function init(forceWebGL = false) {

//

-function sortFunction(list, camera) {
+type BatchedMeshWithOptions = THREE.BatchedMesh & {
+ _options?: RadixSortOptions<{ start: number; count: number; z: number }>;
+};
+
+function sortFunction(
+ this: THREE.BatchedMesh,
+ list: { start: number; count: number; z: number }[],
+ camera: THREE.Camera,
+) {
// initialize options
- this._options = this._options || {
+ (this as BatchedMeshWithOptions)._options = (this as BatchedMeshWithOptions)._options || {
get: el => el.z,
aux: new Array(this.maxGeometryCount),
};

- const options = this._options;
+ const options = (this as BatchedMeshWithOptions)._options!;
options.reversed = this.material.transparent;

// convert depth to unsigned 32 bit range
- const factor = (2 ** 32 - 1) / camera.far; // UINT32_MAX / max_depth
+ const factor = (2 ** 32 - 1) / (camera as THREE.PerspectiveCamera).far; // UINT32_MAX / max_depth
for (let i = 0, l = list.length; i < l; i++) {
list[i].z *= factor;
}
diff --git a/examples-testing/examples/webgpu_morphtargets.ts b/examples-testing/examples/webgpu_morphtargets.ts
index 751d39f..f54fb93 100644
--- a/examples-testing/examples/webgpu_morphtargets.ts
Expand Down
3 changes: 3 additions & 0 deletions examples-testing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@
"@types/three": "file:../types/three",
"prettier": "^3.2.5",
"typescript": "latest"
},
"devDependencies": {
"stats-gl": "2.2.7"
}
}
14 changes: 11 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions types/three/examples/jsm/nodes/Nodes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export * from "./shadernode/ShaderNode.js";

// accessors
export { parallaxDirection, parallaxUV, TBNViewMatrix } from "./accessors/AccessorsUtils.js";
export { batch, default as BatchNode } from "./accessors/BatchNode.js";
export {
bitangentGeometry,
bitangentLocal,
Expand Down
14 changes: 14 additions & 0 deletions types/three/examples/jsm/nodes/accessors/BatchNode.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { BatchedMesh } from "three";
import Node from "../core/Node.js";
import { ShaderNodeObject } from "../shadernode/ShaderNode.js";

export default class BatchNode extends Node {
batchMesh: BatchedMesh;

instanceColorNode: Node | null;
batchingIdNode: Node | null;

constructor(batchMesh: BatchedMesh);
}

export const batch: (batchMesh: BatchedMesh) => ShaderNodeObject<BatchNode>;
1 change: 1 addition & 0 deletions types/three/examples/jsm/nodes/materials/Materials.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { default as LineBasicNodeMaterial } from "./LineBasicNodeMaterial.js";
export { default as MeshBasicNodeMaterial } from "./MeshBasicNodeMaterial.js";
export { default as MeshNormalNodeMaterial } from "./MeshNormalNodeMaterial.js";
export { default as MeshPhongNodeMaterial } from "./MeshPhongNodeMaterial.js";
export { default as MeshPhysicalNodeMaterial } from "./MeshPhysicalNodeMaterial.js";
export { default as MeshSSSPhysicalNodeMaterial } from "./MeshSSSNodeMaterial.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MeshNormalMaterialParameters, NormalMapTypes, Texture, Vector2 } from "three";
import NodeMaterial, { NodeMaterialParameters } from "./NodeMaterial.js";

export interface MeshBasicNodeMaterialParameters extends NodeMaterialParameters, MeshNormalMaterialParameters {
}

export default class MeshNormalNodeMaterial extends NodeMaterial {
readonly isMeshNormalNodeMaterial: true;

// Properties from MeshNormalMaterial
readonly isMeshNormalMaterial: true;
bumpMap: Texture | null;
bumpScale: number;
normalMap: Texture | null;
normalMapType: NormalMapTypes;
normalScale: Vector2;
displacementMap: Texture | null;
displacementScale: number;
displacementBias: number;
flatShading: boolean;

constructor(parameters?: MeshBasicNodeMaterialParameters);
}
3 changes: 3 additions & 0 deletions types/three/examples/jsm/nodes/materials/NodeMaterial.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
LineBasicMaterial,
Material,
MeshBasicMaterial,
MeshNormalMaterial,
MeshPhongMaterial,
MeshPhysicalMaterial,
MeshStandardMaterial,
Expand All @@ -18,6 +19,7 @@ import LightsNode from "../lighting/LightsNode.js";
import { ShaderNodeObject } from "../shadernode/ShaderNode.js";
import LineBasicNodeMaterial from "./LineBasicNodeMaterial.js";
import MeshBasicNodeMaterial from "./MeshBasicNodeMaterial.js";
import MeshNormalNodeMaterial from "./MeshNormalNodeMaterial.js";
import MeshPhongNodeMaterial from "./MeshPhongNodeMaterial.js";
import MeshPhysicalNodeMaterial from "./MeshPhysicalNodeMaterial.js";
import MeshStandardNodeMaterial from "./MeshStandardNodeMaterial.js";
Expand Down Expand Up @@ -97,6 +99,7 @@ export default class NodeMaterial extends ShaderMaterial {

static fromMaterial(material: LineBasicMaterial): LineBasicNodeMaterial;
static fromMaterial(material: MeshBasicMaterial): MeshBasicNodeMaterial;
static fromMaterial(material: MeshNormalMaterial): MeshNormalNodeMaterial;
static fromMaterial(material: MeshPhongMaterial): MeshPhongNodeMaterial;
static fromMaterial(material: MeshPhysicalMaterial): MeshPhysicalNodeMaterial;
static fromMaterial(material: MeshStandardMaterial): MeshStandardNodeMaterial;
Expand Down

0 comments on commit a73ee28

Please sign in to comment.