Skip to content

Commit a598e30

Browse files
committed
docs(examples): update instances routes
1 parent aac821d commit a598e30

File tree

3 files changed

+159
-11
lines changed

3 files changed

+159
-11
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { ChangeDetectionStrategy, Component } from '@angular/core';
2+
import { NgtCanvas, NgtCanvasContent } from 'angular-three/dom';
3+
import { SceneGraph } from './scene';
4+
5+
@Component({
6+
template: `
7+
<ngt-canvas [camera]="{ position: [0, 0, 0.01] }">
8+
<app-instances-scene-graph *canvasContent />
9+
</ngt-canvas>
10+
`,
11+
changeDetection: ChangeDetectionStrategy.OnPush,
12+
host: { class: 'instances-soba' },
13+
imports: [NgtCanvas, SceneGraph, NgtCanvasContent],
14+
})
15+
export default class Instances {}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
CUSTOM_ELEMENTS_SCHEMA,
5+
effect,
6+
ElementRef,
7+
input,
8+
viewChild,
9+
} from '@angular/core';
10+
import { extend, NgtArgs } from 'angular-three';
11+
import { NgtsCameraControls } from 'angular-three-soba/controls';
12+
import { shaderMaterial } from 'angular-three-soba/vanilla-exports';
13+
import { BoxGeometry, Color, InstancedMesh, Object3D, Vector3 } from 'three';
14+
import niceColors from '../../colors';
15+
16+
const MeshEdgesMaterial = shaderMaterial(
17+
{
18+
color: new Color('white'),
19+
size: new Vector3(1, 1, 1),
20+
thickness: 0.01,
21+
smoothness: 0.2,
22+
},
23+
/* language=glsl glsl */ `varying vec3 vPosition;
24+
void main() {
25+
vPosition = position;
26+
gl_Position = projectionMatrix * viewMatrix * instanceMatrix * vec4(position, 1.0);
27+
}`,
28+
/* language=glsl glsl*/ `varying vec3 vPosition;
29+
uniform vec3 size;
30+
uniform vec3 color;
31+
uniform float thickness;
32+
uniform float smoothness;
33+
void main() {
34+
vec3 d = abs(vPosition) - (size * 0.5);
35+
float a = smoothstep(thickness, thickness + smoothness, min(min(length(d.xy), length(d.yz)), length(d.xz)));
36+
gl_FragColor = vec4(color, 1.0 - a);
37+
}`,
38+
);
39+
40+
@Component({
41+
selector: 'app-boxes',
42+
template: `
43+
<ngt-group>
44+
<ngt-instanced-mesh #instances *args="[undefined, undefined, length]">
45+
<ngt-box-geometry #boxGeometry *args="[0.15, 0.15, 0.15]">
46+
<ngt-instanced-buffer-attribute attach="attributes.color" *args="[randomColors, 3]" />
47+
</ngt-box-geometry>
48+
<ngt-mesh-lambert-material vertexColors [toneMapped]="false" />
49+
</ngt-instanced-mesh>
50+
<ngt-instanced-mesh #outlines *args="[undefined, undefined, length]">
51+
<ngt-mesh-edges-material
52+
transparent
53+
polygonOffset
54+
[polygonOffsetFactor]="-10"
55+
[size]="[0.15, 0.15, 0.15]"
56+
color="black"
57+
[thickness]="0.001"
58+
[smoothness]="0.005"
59+
/>
60+
</ngt-instanced-mesh>
61+
</ngt-group>
62+
`,
63+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
64+
changeDetection: ChangeDetectionStrategy.OnPush,
65+
imports: [NgtArgs],
66+
})
67+
export class Boxes {
68+
protected length = 100_000;
69+
70+
private c = new Color();
71+
protected randomColors = new Float32Array(
72+
Array.from({ length: this.length }, () => this.c.set(niceColors[Math.floor(Math.random() * 5)]).toArray()).flat(),
73+
);
74+
75+
private instancesRef = viewChild<ElementRef<InstancedMesh>>('instances');
76+
private outlinesRef = viewChild<ElementRef<InstancedMesh>>('outlines');
77+
private boxGeometryRef = viewChild<ElementRef<BoxGeometry>>('boxGeometry');
78+
79+
constructor() {
80+
extend({ MeshEdgesMaterial });
81+
82+
const o = new Object3D();
83+
84+
effect(() => {
85+
const [instances, outlines, boxGeometry] = [
86+
this.instancesRef()?.nativeElement,
87+
this.outlinesRef()?.nativeElement,
88+
this.boxGeometryRef()?.nativeElement,
89+
];
90+
if (!instances || !outlines || !boxGeometry) return;
91+
92+
let i = 0;
93+
const root = Math.round(Math.pow(this.length, 1 / 3));
94+
const halfRoot = root / 2;
95+
for (let x = 0; x < root; x++)
96+
for (let y = 0; y < root; y++)
97+
for (let z = 0; z < root; z++) {
98+
const id = i++;
99+
o.rotation.set(Math.random(), Math.random(), Math.random());
100+
o.position.set(halfRoot - x + Math.random(), halfRoot - y + Math.random(), halfRoot - z + Math.random());
101+
o.updateMatrix();
102+
instances.setMatrixAt(id, o.matrix);
103+
}
104+
instances.instanceMatrix.needsUpdate = true;
105+
// Re-use geometry + instance matrix
106+
outlines.geometry = boxGeometry;
107+
outlines.instanceMatrix = instances.instanceMatrix;
108+
});
109+
}
110+
}
111+
112+
@Component({
113+
selector: 'app-instances-scene-graph',
114+
template: `
115+
<ngt-color attach="background" *args="['#e0e0e0']" />
116+
117+
<ngt-ambient-light [intensity]="0.85" />
118+
<ngt-directional-light [position]="[150, 150, 150]" [intensity]="1" />
119+
120+
<app-boxes />
121+
122+
@if (!asRenderTexture()) {
123+
<ngts-camera-controls />
124+
}
125+
`,
126+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
127+
changeDetection: ChangeDetectionStrategy.OnPush,
128+
host: { class: 'instances-soba-experience' },
129+
imports: [NgtsCameraControls, Boxes, NgtArgs],
130+
})
131+
export class SceneGraph {
132+
asRenderTexture = input(false);
133+
}

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,17 @@ const routes: Routes = [
101101
// },
102102
// },
103103
// },
104-
// {
105-
// path: 'instances',
106-
// loadComponent: () => import('./instances/instances'),
107-
// data: {
108-
// credits: {
109-
// title: 'Instances',
110-
// link: 'https://pmndrs.github.io/examples/demos/instances',
111-
// class: 'p-2 rounded border border-black bg-white',
112-
// },
113-
// },
114-
// },
104+
{
105+
path: 'instances',
106+
loadComponent: () => import('./instances/instances'),
107+
data: {
108+
credits: {
109+
title: 'Instances',
110+
link: 'https://pmndrs.github.io/examples/demos/instances',
111+
class: 'p-2 rounded border border-black bg-white',
112+
},
113+
},
114+
},
115115
// {
116116
// path: 'inverted-stencil-buffer',
117117
// loadComponent: () => import('./inverted-stencil-buffer/inverted-stencil-buffer'),

0 commit comments

Comments
 (0)