|
| 1 | +import { Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, ViewChild } from '@angular/core'; |
| 2 | +import { NgtArgs, NgtCanvas, NgtStore } from 'angular-three'; |
| 3 | +// @ts-expect-error no type def for nice-color-palettes |
| 4 | +import niceColors from 'nice-color-palettes'; |
| 5 | +import * as THREE from 'three'; |
| 6 | +const niceColor = niceColors[Math.floor(Math.random() * niceColors.length)]; |
| 7 | + |
| 8 | +@Component({ |
| 9 | + selector: 'demo-colors-instances', |
| 10 | + standalone: true, |
| 11 | + template: ` |
| 12 | + <ngt-instanced-mesh #instanced *args="[undefined, undefined, length]"> |
| 13 | + <ngt-box-geometry *args="[0.15, 0.15, 0.15]"> |
| 14 | + <ngt-instanced-buffer-attribute attach="attributes.color" *args="[colors, 3]" /> |
| 15 | + </ngt-box-geometry> |
| 16 | + <ngt-mesh-lambert-material [vertexColors]="true" [toneMapped]="false" /> |
| 17 | + </ngt-instanced-mesh> |
| 18 | + `, |
| 19 | + imports: [NgtArgs], |
| 20 | + schemas: [CUSTOM_ELEMENTS_SCHEMA], |
| 21 | +}) |
| 22 | +export class ColorsInstances { |
| 23 | + readonly length = 125000; |
| 24 | + |
| 25 | + private readonly o = new THREE.Object3D(); |
| 26 | + private readonly c = new THREE.Color(); |
| 27 | + private readonly colorsArr = Array.from({ length: this.length }, () => niceColor[Math.floor(Math.random() * 5)]); |
| 28 | + |
| 29 | + readonly colors = Float32Array.from( |
| 30 | + Array.from({ length: this.length }, (_, index) => |
| 31 | + this.c.set(this.colorsArr[index]).convertSRGBToLinear().toArray() |
| 32 | + ).flat() |
| 33 | + ); |
| 34 | + |
| 35 | + @ViewChild('instanced') set instanced({ nativeElement }: ElementRef<THREE.InstancedMesh>) { |
| 36 | + let i = 0; |
| 37 | + for (let x = 0; x < 50; x++) { |
| 38 | + for (let y = 0; y < 50; y++) { |
| 39 | + for (let z = 0; z < 50; z++) { |
| 40 | + const id = i++; |
| 41 | + this.o.position.set(25 - x, 25 - y, 25 - z); |
| 42 | + this.o.updateMatrix(); |
| 43 | + nativeElement.setMatrixAt(id, this.o.matrix); |
| 44 | + } |
| 45 | + } |
| 46 | + } |
| 47 | + } |
| 48 | +} |
| 49 | + |
| 50 | +@Component({ |
| 51 | + standalone: true, |
| 52 | + template: ` |
| 53 | + <ngt-ambient-light /> |
| 54 | + <ngt-directional-light [intensity]="0.55" [position]="150" /> |
| 55 | + <demo-colors-instances /> |
| 56 | + <ngt-orbit-controls |
| 57 | + *args="[camera, glDom]" |
| 58 | + [enableDamping]="true" |
| 59 | + [autoRotate]="true" |
| 60 | + (beforeRender)="$any($event).object.update()" |
| 61 | + /> |
| 62 | + `, |
| 63 | + imports: [NgtArgs, ColorsInstances], |
| 64 | + schemas: [CUSTOM_ELEMENTS_SCHEMA], |
| 65 | +}) |
| 66 | +export class Scene { |
| 67 | + private readonly store = inject(NgtStore); |
| 68 | + readonly camera = this.store.get('camera'); |
| 69 | + readonly glDom = this.store.get('gl', 'domElement'); |
| 70 | +} |
| 71 | + |
| 72 | +@Component({ |
| 73 | + standalone: true, |
| 74 | + template: ` <ngt-canvas [sceneGraph]="SceneGraph" [camera]="{ position: [0, 0, 1] }" /> `, |
| 75 | + imports: [NgtCanvas], |
| 76 | +}) |
| 77 | +export default class DemoVertexColorsInstances { |
| 78 | + readonly SceneGraph = Scene; |
| 79 | +} |
0 commit comments