Skip to content

Commit 9a085df

Browse files
committed
docs(examples): update bruno routes
1 parent 5ebb619 commit 9a085df

File tree

3 files changed

+230
-10
lines changed

3 files changed

+230
-10
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { NgtCanvas, NgtCanvasContent } from 'angular-three/dom';
3+
import { ToggleButton } from '../../toggle-button';
4+
import { debug, SceneGraph, withN8ao } from './scene';
5+
6+
@Component({
7+
template: `
8+
<ngt-canvas
9+
flat
10+
shadows
11+
[gl]="{ antialias: false }"
12+
[camera]="{ position: [-30, 35, -15], near: 30, far: 55, fov: 12 }"
13+
>
14+
<app-bruno-scene-graph *canvasContent />
15+
</ngt-canvas>
16+
17+
<div class="absolute top-10 right-2 flex gap-2 items-center">
18+
<button [(toggleButton)]="debug">Toggle debug</button>
19+
<button [(toggleButton)]="withN8ao">Toggle N8ao</button>
20+
</div>
21+
`,
22+
changeDetection: ChangeDetectionStrategy.OnPush,
23+
host: { class: 'bruno-simons-2k-soba' },
24+
imports: [NgtCanvas, NgtCanvasContent, ToggleButton, SceneGraph],
25+
})
26+
export default class BrunoSimons20k {
27+
protected debug = debug;
28+
protected withN8ao = withN8ao;
29+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, input, signal } from '@angular/core';
2+
import { NgtArgs, NgtEuler, NgtVector3 } from 'angular-three';
3+
import { NgtpDepthOfField, NgtpEffectComposer, NgtpToneMapping } from 'angular-three-postprocessing';
4+
import { NgtpN8AO } from 'angular-three-postprocessing/n8ao';
5+
import { NgtrCuboidCollider, NgtrInstancedRigidBodies, NgtrPhysics, NgtrRigidBody } from 'angular-three-rapier';
6+
import { NgtsOrbitControls } from 'angular-three-soba/controls';
7+
import { injectGLTF } from 'angular-three-soba/loaders';
8+
import {
9+
NgtsAccumulativeShadows,
10+
NgtsEnvironment,
11+
NgtsLightformer,
12+
NgtsRandomizedLights,
13+
} from 'angular-three-soba/staging';
14+
import { MathUtils, Mesh, MeshStandardMaterial } from 'three';
15+
import { GLTF } from 'three-stdlib';
16+
17+
export const debug = signal(false);
18+
export const withN8ao = signal(true);
19+
20+
type HatGLTF = GLTF & {
21+
nodes: { Plane006: Mesh; Plane006_1: Mesh };
22+
materials: { Material: MeshStandardMaterial; boxCap: MeshStandardMaterial };
23+
};
24+
25+
@Component({
26+
selector: 'app-hats',
27+
template: `
28+
@if (gltf(); as gltf) {
29+
<ngt-object3D [instancedRigidBodies]="instances" [options]="{ colliders: 'hull' }">
30+
<ngt-instanced-mesh
31+
*args="[gltf.nodes.Plane006_1.geometry, gltf.materials.boxCap, 80]"
32+
[dispose]="null"
33+
[receiveShadow]="true"
34+
[castShadow]="true"
35+
/>
36+
</ngt-object3D>
37+
}
38+
`,
39+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
40+
changeDetection: ChangeDetectionStrategy.OnPush,
41+
imports: [NgtrInstancedRigidBodies, NgtArgs],
42+
})
43+
export class Hats {
44+
protected gltf = injectGLTF<HatGLTF>(() => './blender-threejs-journey-20k-hat-transformed.glb');
45+
46+
protected instances = Array.from({ length: 80 }, (_, index) => ({
47+
key: index,
48+
position: [MathUtils.randFloatSpread(2) + 1, 10 + index / 2, MathUtils.randFloatSpread(2) - 2] as NgtVector3,
49+
rotation: [Math.random(), Math.random(), Math.random()] as NgtEuler,
50+
}));
51+
52+
// NOTE: GLTF of the hat has 2 parts: the cap and the tassel. InstancedMesh
53+
// can only have 1 geometry, so we need something like CSG to merge the geometries into one.
54+
// Angular Three does not have this yet.
55+
// <Geometry useGroups>
56+
// <Base geometry={nodes.Plane006.geometry} material={materials.Material} />
57+
// <Addition geometry={nodes.Plane006_1.geometry} material={materials.boxCap} />
58+
// </Geometry>
59+
}
60+
61+
type ModelGLTF = GLTF & {
62+
nodes: { boxBase: Mesh; boxBack: Mesh; Text: Mesh };
63+
materials: { boxBase: MeshStandardMaterial; inside: MeshStandardMaterial };
64+
};
65+
66+
@Component({
67+
selector: 'app-model',
68+
template: `
69+
@if (gltf(); as gltf) {
70+
<ngt-group [position]="position()" [dispose]="null">
71+
<ngt-object3D rigidBody="fixed" [options]="{ colliders: 'trimesh' }">
72+
<ngt-mesh
73+
castShadow
74+
receiveShadow
75+
[geometry]="gltf.nodes.boxBase.geometry"
76+
[material]="gltf.materials.boxBase"
77+
/>
78+
<ngt-mesh receiveShadow [geometry]="gltf.nodes.boxBack.geometry" [material]="gltf.materials.inside" />
79+
<ngt-mesh
80+
castShadow
81+
receiveShadow
82+
[geometry]="gltf.nodes.Text.geometry"
83+
[material]="gltf.materials.boxBase"
84+
/>
85+
</ngt-object3D>
86+
</ngt-group>
87+
}
88+
`,
89+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
90+
changeDetection: ChangeDetectionStrategy.OnPush,
91+
imports: [NgtrRigidBody],
92+
})
93+
export class Model {
94+
position = input<NgtVector3>([0, 0, 0]);
95+
96+
protected gltf = injectGLTF<ModelGLTF>(() => './blender-threejs-journey-20k-transformed.glb');
97+
}
98+
99+
@Component({
100+
selector: 'app-bruno-scene-graph',
101+
template: `
102+
<ngt-color attach="background" *args="['#f0f0f0']" />
103+
<ngt-ambient-light [intensity]="0.5" />
104+
<ngt-directional-light [position]="[-10, 10, 5]" [castShadow]="true">
105+
<ngt-value [rawValue]="-0.0001" attach="shadow.bias" />
106+
<ngt-vector2 *args="[256, 256]" attach="shadow.mapSize" />
107+
<ngt-orthographic-camera *args="[-10, 10, -10, 10]" attach="shadow.camera" />
108+
</ngt-directional-light>
109+
110+
<ngts-environment [options]="{ resolution: 32 }">
111+
<ng-template>
112+
<ngts-lightformer [options]="{ position: [10, 10, 10], scale: 10, intensity: 4 }" />
113+
<ngts-lightformer [options]="{ position: [10, 0, -10], scale: 10, color: 'red', intensity: 6 }" />
114+
<ngts-lightformer [options]="{ position: [-10, -10, -10], scale: 10, intensity: 4 }" />
115+
</ng-template>
116+
</ngts-environment>
117+
118+
<ngtr-physics [options]="{ debug: debug(), gravity: [0, -4, 0] }">
119+
<ng-template>
120+
<app-model [position]="[1, 0, -1.5]" />
121+
<app-hats />
122+
<ngt-object3D rigidBody="fixed" [options]="{ colliders: false }" [position]="[0, -1, 0]">
123+
<ngt-object3D cuboidCollider [args]="[1000, 1, 1000]" />
124+
</ngt-object3D>
125+
</ng-template>
126+
</ngtr-physics>
127+
128+
<ngts-accumulative-shadows
129+
[options]="{
130+
temporal: true,
131+
frames: Infinity,
132+
alphaTest: 1,
133+
blend: 200,
134+
limit: 1500,
135+
scale: 25,
136+
position: [0, -0.05, 0],
137+
}"
138+
>
139+
<ngts-randomized-lights
140+
[options]="{ amount: 1, mapSize: 512, radius: 5, ambient: 0.5, position: [-10, 10, 5], size: 10, bias: 0.001 }"
141+
/>
142+
</ngts-accumulative-shadows>
143+
144+
<ngtp-effect-composer>
145+
@if (withN8ao()) {
146+
<ngtp-n8ao [options]="{ aoRadius: 0.5, intensity: 1 }" />
147+
}
148+
149+
<ngtp-depth-of-field [options]="{ target: [0, 0, -2.5], focusRange: 0.1, bokehScale: 10 }" />
150+
<ngtp-tone-mapping />
151+
</ngtp-effect-composer>
152+
153+
<ngts-orbit-controls
154+
[options]="{
155+
autoRotate: true,
156+
autoRotateSpeed: 0.1,
157+
enablePan: false,
158+
enableZoom: false,
159+
minPolarAngle: Math.PI / 4,
160+
maxPolarAngle: Math.PI / 4,
161+
}"
162+
/>
163+
`,
164+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
165+
changeDetection: ChangeDetectionStrategy.OnPush,
166+
host: { class: 'bruno-simons-2k-soba-experience' },
167+
imports: [
168+
NgtArgs,
169+
NgtsEnvironment,
170+
NgtsLightformer,
171+
NgtrPhysics,
172+
Model,
173+
NgtrRigidBody,
174+
NgtrCuboidCollider,
175+
NgtsAccumulativeShadows,
176+
NgtsRandomizedLights,
177+
NgtpEffectComposer,
178+
NgtpN8AO,
179+
NgtpDepthOfField,
180+
NgtsOrbitControls,
181+
NgtpToneMapping,
182+
Hats,
183+
],
184+
})
185+
export class SceneGraph {
186+
protected readonly Infinity = Infinity;
187+
protected readonly Math = Math;
188+
189+
protected debug = debug;
190+
protected withN8ao = withN8ao;
191+
}

apps/kitchen-sink-new/src/app/soba/soba.routes.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,16 @@ const routes: Routes = [
143143
// },
144144
// },
145145
// },
146-
// {
147-
// path: 'bruno-simons-20k',
148-
// loadComponent: () => import('./bruno-simons-20k/bruno-simons-20k'),
149-
// data: {
150-
// credits: {
151-
// title: 'Bruno Simons 20k',
152-
// link: 'https://pmndrs.github.io/examples/demos/bruno-simons-20k-challenge',
153-
// },
154-
// },
155-
// },
146+
{
147+
path: 'bruno-simons-20k',
148+
loadComponent: () => import('./bruno-simons-20k/bruno-simons-20k'),
149+
data: {
150+
credits: {
151+
title: 'Bruno Simons 20k',
152+
link: 'https://pmndrs.github.io/examples/demos/bruno-simons-20k-challenge',
153+
},
154+
},
155+
},
156156
// {
157157
// path: 'instanced-vertex-colors',
158158
// loadComponent: () => import('./instanced-vertex-colors/instanced-vertex-colors'),

0 commit comments

Comments
 (0)