NgtsPoints
import { ChangeDetectionStrategy, Component } from '@angular/core';import { SobaWrapper } from '@soba/wrapper.ts';import { NgtCanvas, provideNgtRenderer } from 'angular-three/dom';import { SceneGraph } from './scene-graph';
@Component({ selector: 'app-points', template: ` <ngt-canvas [camera]="{ position: [0, 0, 4], fov: 50 }"> <app-soba-wrapper *canvasContent [grid]="false" [lights]="false" background="#111"> <app-scene-graph /> </app-soba-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'points-demo relative block h-full' }, imports: [NgtCanvas, SobaWrapper, SceneGraph],})export default class Points { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, input, signal, viewChild,} from '@angular/core';import { extend, objectEvents } from 'angular-three';import { NgtsPoint, NgtsPointsInstances } from 'angular-three-soba/performances';import { shaderMaterial } from 'angular-three-soba/vanilla-exports';import { MathUtils } from 'three';
// Custom shader material for colorful pointsconst ColorPointsMaterial = shaderMaterial( {}, /* glsl */ ` attribute float size; attribute vec3 color; varying vec3 vColor;
void main() { vColor = color; vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); gl_PointSize = size * (300.0 / -mvPosition.z); gl_Position = projectionMatrix * mvPosition; } `, /* glsl */ ` varying vec3 vColor;
void main() { // Create circular points vec2 center = gl_PointCoord - vec2(0.5); if (length(center) > 0.5) discard;
gl_FragColor = vec4(vColor, 1.0); #include <tonemapping_fragment> #include <colorspace_fragment> } `,);
extend({ ColorPointsMaterial });
@Component({ selector: 'app-point-with-events', template: ` <ngts-point [options]="{ position: position(), size: finalSize(), color: $any(finalColor()) }" /> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtsPoint],})export class PointWithEvents { position = input<[number, number, number]>([0, 0, 0]); color = input<[number, number, number]>([1, 1, 1]); size = input(0.3);
pointRef = viewChild.required(NgtsPoint);
hovered = signal(false); clicked = signal(false);
finalColor = computed(() => (this.hovered() ? [1, 0.4, 0.7] : this.color())); // hotpink when hovered finalSize = computed(() => this.size() * (this.clicked() ? 1.5 : 1));
constructor() { objectEvents(() => this.pointRef().positionPointRef(), { pointerover: (event) => { event.stopPropagation(); this.hovered.set(true); }, pointerout: () => { this.hovered.set(false); }, click: (event) => { event.stopPropagation(); this.clicked.update((prev) => !prev); }, }); }}
@Component({ selector: 'app-scene-graph', template: ` <ngts-points-instances> @for (point of points; track $index) { <app-point-with-events [position]="point.position" [size]="point.size" [color]="point.color" /> } <ngt-color-points-material /> </ngts-points-instances> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtsPointsInstances, PointWithEvents],})export class SceneGraph { points: { position: [number, number, number]; color: [number, number, number]; size: number }[] = [];
constructor() { // Create a 6x6x6 grid of points const n = 6; for (let i = 0; i < n * n * n; i++) { this.points.push({ position: [MathUtils.randFloatSpread(4), MathUtils.randFloatSpread(4), MathUtils.randFloatSpread(4)], color: [Math.random(), Math.random(), Math.random()], size: Math.random() * 0.4 + 0.2, }); } }}Components for efficiently rendering point clouds with per-point control over position, color, and size.
NgtsPointsInstances
Renders many individual points with per-point control. Best for dynamic point clouds where individual points need to be updated.
import { NgtsPointsInstances, NgtsPoint } from 'angular-three-soba/performances';<ngts-points-instances [options]="{ limit: 100 }"> <ngt-points-material [size]="0.1" [vertexColors]="true" />
@for (i of points; track i) { <ngts-point [options]="{ position: [i * 2, 0, 0], color: 'red' }" /> }</ngts-points-instances>NgtsPoint
A single point within NgtsPointsInstances. Supports position, color, and size.
Point Options
| Property | Description |
|---|---|
position | Position [x, y, z] |
color | Point color |
size | Point size override |
NgtsPointsBuffer
Optimized for large arrays of pre-computed point data. Ideal for particle systems or data visualizations with thousands of points.
import { NgtsPointsBuffer } from 'angular-three-soba/performances';<ngts-points-buffer [positions]="positionsArray" [colors]="colorsArray" [sizes]="sizesArray"> <ngt-points-material [vertexColors]="true" /></ngts-points-buffer>Creating Point Cloud Data
@Component({ template: ` <ngts-points-buffer [positions]="positions()" [colors]="colors()"> <ngt-points-material [size]="0.05" [vertexColors]="true" /> </ngts-points-buffer> `})export class PointCloud { count = 10000;
positions = computed(() => { const arr = new Float32Array(this.count * 3); for (let i = 0; i < this.count; i++) { arr[i * 3] = (Math.random() - 0.5) * 10; arr[i * 3 + 1] = (Math.random() - 0.5) * 10; arr[i * 3 + 2] = (Math.random() - 0.5) * 10; } return arr; });
colors = computed(() => { const arr = new Float32Array(this.count * 3); for (let i = 0; i < this.count; i++) { arr[i * 3] = Math.random(); // R arr[i * 3 + 1] = Math.random(); // G arr[i * 3 + 2] = Math.random(); // B } return arr; });}When to Use Which
| Component | Use Case |
|---|---|
NgtsPointsInstances | Dynamic points, individual updates |
NgtsPointsBuffer | Static/bulk data, large point clouds |
2D Points
Use stride for 2D point data:
<ngts-points-buffer [positions]="positions2D" [stride]="2"> <ngt-points-material [size]="0.1" /></ngts-points-buffer>Inputs
| name | type | description | required |
|---|---|---|---|
| positions | Float32Array | Float32Array of point positions | yes |
| colors | Float32Array | Optional Float32Array of RGB colors | no |
| sizes | Float32Array | Optional Float32Array of point sizes | no |
| stride | number | Components per position (2 or 3), default to 3 | no |
Options
Properties
| name | type | description |
|---|---|---|
| limit | number | Maximum number of points, default to 1000 |
| range | number | Limits the number of visible points |