Skip to content

Commit 0a561c7

Browse files
committed
docs: adjust webgpu tsl scene
1 parent 2d7120f commit 0a561c7

File tree

5 files changed

+51
-38
lines changed

5 files changed

+51
-38
lines changed

apps/examples/src/app/misc/misc.routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ const routes: Routes = [
4242
loadComponent: () => import('./webgpu-tsl/webgpu-tsl'),
4343
data: {
4444
credits: {
45-
title: "Threlte's WebGPU TSL example",
46-
link: 'https://threlte.xyz/docs/learn/advanced/webgpu#tsl',
45+
title: 'THREE.js TSL Angular Slicing',
46+
link: 'https://threejs.org/examples/?q=tsl#webgpu_tsl_angular_slicing',
4747
},
4848
},
4949
},
Binary file not shown.

apps/examples/src/app/misc/webgpu-tsl/scene.ts

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { NgTemplateOutlet } from '@angular/common';
12
import {
23
ChangeDetectionStrategy,
34
Component,
@@ -8,33 +9,29 @@ import {
89
signal,
910
viewChild,
1011
} from '@angular/core';
11-
import { extend, injectBeforeRender, injectStore } from 'angular-three';
12+
import { extend, injectBeforeRender, injectLoader, injectStore } from 'angular-three';
1213
import { NgtsPerspectiveCamera } from 'angular-three-soba/cameras';
1314
import { NgtsOrbitControls } from 'angular-three-soba/controls';
1415
import { injectGLTF } from 'angular-three-soba/loaders';
16+
import { NgtTweakCheckbox, NgtTweakColor, NgtTweakNumber, NgtTweakPane } from 'angular-three-tweakpane';
17+
import { GLTF, RGBELoader } from 'three-stdlib';
1518
import * as THREE from 'three/webgpu';
19+
import { DirectionalLight, MeshPhysicalNodeMaterial } from 'three/webgpu';
20+
import { SliceMaterial } from './slice-material';
1621

17-
import { NgTemplateOutlet } from '@angular/common';
18-
import { NgtsEnvironment } from 'angular-three-soba/staging';
19-
import { NgtTweakCheckbox, NgtTweakColor, NgtTweakNumber, NgtTweakPane } from 'angular-three-tweakpane';
20-
import { GLTF } from 'three-stdlib';
2122
import gearsGLB from './gears.glb' with { loader: 'file' };
22-
import { SliceMaterial } from './slice-material';
23+
import royalHDR from './royal_esplanade_1k.hdr' with { loader: 'file' };
2324

2425
injectGLTF.preload(() => gearsGLB);
2526

2627
interface GearsGLB extends GLTF {
27-
nodes: {
28-
axle: THREE.Mesh;
29-
gears: THREE.Mesh;
30-
outerHull: THREE.Mesh;
31-
};
28+
nodes: { axle: THREE.Mesh; gears: THREE.Mesh; outerHull: THREE.Mesh };
3229
}
3330

3431
@Component({
3532
selector: 'app-scene-graph',
3633
template: `
37-
<ngts-perspective-camera [options]="{ makeDefault: true, position: [-5, 5, 12] }" />
34+
<ngts-perspective-camera [options]="{ makeDefault: true, position: [-5, 5, 5] }" />
3835
3936
<ngt-directional-light
4037
castShadow
@@ -64,7 +61,7 @@ interface GearsGLB extends GLTF {
6461
</ngt-mesh>
6562
</ng-template>
6663
67-
<ngt-group #gears [position]="gearsPosition">
64+
<ngt-group #gears>
6865
@if (gltf(); as gltf) {
6966
@let gears = gltf.nodes.gears;
7067
@let axle = gltf.nodes.axle;
@@ -86,19 +83,18 @@ interface GearsGLB extends GLTF {
8683
[arcAngle]="arcAngle()"
8784
[startAngle]="startAngle()"
8885
[sliceColor]="sliceColor()"
89-
[parameters]="{ metalness, roughness, envMapIntensity, color, side: DoubleSide }"
86+
[parameters]="{ metalness, roughness, envMapIntensity, color }"
9087
/>
9188
</ngt-mesh>
9289
}
9390
</ngt-group>
9491
95-
<ngt-mesh #plane [position]="[-4, -3, -4]" [scale]="10" receiveShadow>
92+
<ngt-mesh [position]="[-4, -3, -4]" [scale]="10" receiveShadow (updated)="$event.lookAt(0, 0, 0)">
9693
<ngt-plane-geometry />
9794
<ngt-mesh-standard-material color="#aaaaaa" />
9895
</ngt-mesh>
9996
100-
<ngts-environment [options]="{ preset: 'warehouse', background: true, blur: 0.5 }" />
101-
<ngts-orbit-controls />
97+
<ngts-orbit-controls [options]="{ zoomSpeed: 0.2 }" />
10298
10399
<ngt-tweak-pane title="Slice Material" left="8px">
104100
<ngt-tweak-checkbox [(value)]="rotate" label="rotate" />
@@ -120,7 +116,6 @@ interface GearsGLB extends GLTF {
120116
imports: [
121117
NgtsPerspectiveCamera,
122118
NgtsOrbitControls,
123-
NgtsEnvironment,
124119
NgTemplateOutlet,
125120
SliceMaterial,
126121
NgtTweakPane,
@@ -132,21 +127,21 @@ interface GearsGLB extends GLTF {
132127
schemas: [CUSTOM_ELEMENTS_SCHEMA],
133128
})
134129
export class SceneGraph {
135-
protected readonly DoubleSide = THREE.DoubleSide;
136-
137130
private gearsRef = viewChild.required<ElementRef<THREE.Group>>('gears');
138-
private planeRef = viewChild.required<ElementRef<THREE.Mesh>>('plane');
139131

132+
protected environmentMap = injectLoader(
133+
() => RGBELoader,
134+
() => royalHDR,
135+
);
140136
protected gltf = injectGLTF<GearsGLB>(() => gearsGLB);
137+
141138
private store = injectStore();
142139

143140
protected metalness = 0.5;
144141
protected roughness = 0.25;
145142
protected envMapIntensity = 0.5;
146143
protected color = '#858080';
147144

148-
protected gearsPosition = new THREE.Vector3();
149-
150145
protected rotate = signal(true);
151146
protected sliceColor = signal('#9370DB');
152147
protected startAngleDegrees = signal(60);
@@ -156,29 +151,33 @@ export class SceneGraph {
156151
protected startAngle = computed(() => THREE.MathUtils.DEG2RAD * this.startAngleDegrees());
157152

158153
constructor() {
159-
extend(THREE);
154+
extend({ MeshPhysicalNodeMaterial, DirectionalLight });
160155

161156
injectBeforeRender(({ delta }) => {
162-
const [gears, plane] = [this.gearsRef().nativeElement, this.planeRef().nativeElement];
163-
plane.lookAt(gears.position);
164-
165157
if (!this.rotate()) return;
166-
167-
gears.rotation.y += 0.1 * delta;
158+
this.gearsRef().nativeElement.rotation.y += 0.1 * delta;
168159
});
169160

170161
effect((onCleanup) => {
171-
const [scene, gl] = [this.store.scene(), this.store.gl()];
162+
const environmentMap = this.environmentMap();
163+
if (!environmentMap) return;
164+
165+
const scene = this.store.scene();
172166

167+
const oldBackground = scene.background;
168+
const oldEnvironment = scene.environment;
173169
const blurriness = scene.backgroundBlurriness;
174-
const lastToneMapping = gl.toneMapping;
175170

171+
environmentMap.mapping = THREE.EquirectangularReflectionMapping;
172+
173+
scene.background = environmentMap;
176174
scene.backgroundBlurriness = 0.5;
177-
gl.toneMapping = THREE.ACESFilmicToneMapping;
175+
scene.environment = environmentMap;
178176

179177
onCleanup(() => {
178+
scene.background = oldBackground;
179+
scene.environment = oldEnvironment;
180180
scene.backgroundBlurriness = blurriness;
181-
gl.toneMapping = lastToneMapping;
182181
});
183182
});
184183
}

apps/examples/src/app/misc/webgpu-tsl/slice-material.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ export class SliceMaterial {
2525
startAngle: this.uStartAngle,
2626
arcAngle: this.uArcAngle,
2727
});
28+
this.material.nativeElement.side = THREE.DoubleSide;
2829

2930
effect(() => {
3031
const [arcAngle, startAngle, sliceColor] = [this.arcAngle(), this.startAngle(), this.sliceColor()];
31-
this.uStartAngle.value = arcAngle;
32-
this.uArcAngle.value = startAngle;
32+
this.uStartAngle.value = startAngle;
33+
this.uArcAngle.value = arcAngle;
3334
this.uColor.value.set(sliceColor);
3435
});
3536
}

apps/examples/src/app/misc/webgpu-tsl/webgpu-tsl.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import { SceneGraph } from './scene';
99
<ngt-canvas shadows [gl]="glFactory" [frameloop]="frameloop()">
1010
<app-scene-graph *canvasContent />
1111
</ngt-canvas>
12+
13+
<code class="absolute top-10 right-4 px-4 max-w-[50%]">
14+
* There seems to be an issue with WebGPURenderer and dispose process. Environment map will not load properly
15+
on navigating away and back.
16+
</code>
1217
`,
1318
changeDetection: ChangeDetectionStrategy.OnPush,
1419
imports: [NgtCanvas, SceneGraph],
@@ -19,7 +24,6 @@ export default class WebGPUTSL {
1924
protected glFactory: NgtGLOptions = (defaultOptions) => {
2025
const renderer = new THREE.WebGPURenderer({
2126
canvas: defaultOptions.canvas as HTMLCanvasElement,
22-
powerPreference: 'high-performance',
2327
antialias: true,
2428
forceWebGL: false,
2529
});
@@ -28,6 +32,15 @@ export default class WebGPUTSL {
2832
this.frameloop.set('always');
2933
});
3034

35+
const dispose = renderer.dispose.bind(renderer);
36+
Object.assign(renderer, {
37+
dispose: () => {
38+
renderer._renderLists?.dispose();
39+
renderer._renderContexts?.dispose();
40+
dispose();
41+
},
42+
});
43+
3144
return renderer;
3245
};
3346
}

0 commit comments

Comments
 (0)