NgtpEffectComposer
angular-three-postprocessing
1import { NgtpEffectComposer } from 'angular-three-postprocessing';
1@Component({2 standalone: true,3 imports: [NgtpEffectComposer],4 template: `5 <ngtp-effect-composer>6 <!-- effects -->7 </ngtp-effect-composer>8 `,9 schemas: [CUSTOM_ELEMENTS_SCHEMA],10})11export class SceneGraph {}
1import { NgtpEffectComposer } from 'angular-three-postprocessing';2import { NgtpEffectComposer, NgtpBloom, NgtpNoise } from 'angular-three-postprocessing';3 4@Component({5 standalone: true,6 imports: [NgtpEffectComposer, NgtpBloom, NgtpNoise],7 template: `8 <ngtp-effect-composer>9 <ngtp-bloom />10 <ngtp-noise />11 </ngtp-effect-composer>12 `,13 schemas: [CUSTOM_ELEMENTS_SCHEMA],14})15export class SceneGraph {}
1/* credit: https://codesandbox.io/p/sandbox/react-postprocessing-dof-blob-forked-7hj8w3?file=/src/App.js:29,15 */2 3import {4 ChangeDetectionStrategy,5 Component,6 computed,7 CUSTOM_ELEMENTS_SCHEMA,8 type ElementRef,9 input,10 viewChild,11 viewChildren,12} from '@angular/core';13import { extend, injectBeforeRender, injectLoader, NgtArgs, NgtCanvas } from 'angular-three';14import { NgtpBloom, NgtpDepthOfField, NgtpEffectComposer, NgtpVignette } from 'angular-three-postprocessing';15import { injectTexture, NgtsLoader } from 'angular-three-soba/loaders';16import { NgtsMeshDistortMaterial } from 'angular-three-soba/materials';17import * as THREE from 'three';18import { CubeTextureLoader, Material, MathUtils, type Mesh } from 'three';19 20extend(THREE);21 22@Component({23 selector: 'app-main-sphere',24 standalone: true,25 template: `26 <ngt-mesh #mesh [material]="material()">27 <ngt-icosahedron-geometry *args="[1, 4]" />28 </ngt-mesh>29 `,30 schemas: [CUSTOM_ELEMENTS_SCHEMA],31 changeDetection: ChangeDetectionStrategy.OnPush,32 imports: [NgtArgs],33})34export class MainSphere {35 material = input.required<Material>();36 37 meshRef = viewChild.required<ElementRef<Mesh>>('mesh');38 39 constructor() {40 injectBeforeRender(({ clock, pointer }) => {41 const mesh = this.meshRef().nativeElement;42 mesh.rotation.z = clock.getElapsedTime();43 mesh.rotation.y = MathUtils.lerp(mesh.rotation.y, pointer.x * Math.PI, 0.1);44 mesh.rotation.x = MathUtils.lerp(mesh.rotation.x, pointer.y * Math.PI, 0.1);45 });46 }47}48 49@Component({50 selector: 'app-sphere-instances',51 standalone: true,52 template: `53 <!-- we render the material with attach="none" so we can share it between instances -->54 <ngts-mesh-distort-material #distortMaterial attach="none" [options]="materialOptions()" />55 56 <app-main-sphere [material]="distortMaterial.material" />57 @for (position of initialPositions; track $index) {58 <ngt-mesh #mesh [material]="distortMaterial.material" [position]="position">59 <ngt-icosahedron-geometry *args="[1, 4]" />60 </ngt-mesh>61 }62 `,63 schemas: [CUSTOM_ELEMENTS_SCHEMA],64 changeDetection: ChangeDetectionStrategy.OnPush,65 imports: [MainSphere, NgtArgs, NgtsMeshDistortMaterial],66})67export class SphereInstances {68 private envMap = injectLoader(69 // @ts-expect-error - CubeTextureLoader is ok70 () => CubeTextureLoader,71 () => [['px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png']],72 { extensions: (loader) => loader.setPath('/cube/') },73 );74 private bumpMap = injectTexture(() => '/bump.jpg');75 76 materialOptions = computed(() => ({77 envMap: this.envMap()?.[0],78 bumpMap: this.bumpMap(),79 emissive: '#010101',80 emissiveIntensity: 2,81 roughness: 0.1,82 metalness: 1,83 bumpScale: 0.005,84 clearcoat: 1,85 clearcoatRoughness: 1,86 radius: 1,87 distort: 0.4,88 toneMapped: false,89 }));90 91 initialPositions = [92 [-4, 20, -12],93 [-10, 12, -4],94 [-11, -12, -23],95 [-16, -6, -10],96 [12, -2, -3],97 [13, 4, -12],98 [14, -2, -23],99 [8, 10, -20],100 ];101 102 private meshesRef = viewChildren<ElementRef<Mesh>>('mesh');103 104 constructor() {105 injectBeforeRender(() => {106 const meshes = this.meshesRef();107 meshes.forEach(({ nativeElement: mesh }) => {108 mesh.position.y += 0.02;109 if (mesh.position.y > 19) mesh.position.y = -18;110 mesh.rotation.x += 0.06;111 mesh.rotation.y += 0.06;112 mesh.rotation.z += 0.02;113 });114 });115 }116}117 118@Component({119 standalone: true,120 template: `121 <ngt-color attach="background" *args="['#050505']" />122 <ngt-fog attach="fog" *args="['#161616', 8, 30]" />123 124 <app-sphere-instances />125 126 <ngtp-effect-composer [options]="{ multisampling: 0, disableNormalPass: true }">127 <ngtp-depth-of-field [options]="{ focusDistance: 0, focalLength: 0.02, bokehScale: 2, height: 480 }" />128 <ngtp-bloom [options]="{ kernelSize: 3, luminanceThreshold: 0, luminanceSmoothing: 0.9, intensity: 1.5 }" />129 <ngtp-vignette [options]="{ eskil: false, offset: 0.1, darkness: 1.1 }" />130 </ngtp-effect-composer>131 `,132 schemas: [CUSTOM_ELEMENTS_SCHEMA],133 changeDetection: ChangeDetectionStrategy.OnPush,134 imports: [SphereInstances, NgtArgs, NgtpEffectComposer, NgtpDepthOfField, NgtpBloom, NgtpVignette],135})136export class SceneGraph {}137 138@Component({139 standalone: true,140 template: `141 <ngt-canvas [sceneGraph]="sceneGraph" [camera]="{ position: [0, 0, 3] }" />142 <ngts-loader />143 `,144 changeDetection: ChangeDetectionStrategy.OnPush,145 host: { class: 'postprocessing-sample' },146 imports: [NgtCanvas, NgtsLoader],147})148export default class PostprocessingSample {149 sceneGraph = SceneGraph;150}