NgtpColorAverage
import { ChangeDetectionStrategy, Component } from '@angular/core';import { PostprocessingWrapper } from '@postprocessing/wrapper.ts';import { NgtCanvas, provideNgtRenderer } from 'angular-three/dom';import { SceneGraph } from './scene-graph';
@Component({ selector: 'app-color-average', template: ` <ngt-canvas [camera]="{ position: [0, 0, 5], fov: 50 }"> <app-postprocessing-wrapper *canvasContent> <app-scene-graph /> </app-postprocessing-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'color-average-demo relative block h-full' }, imports: [NgtCanvas, PostprocessingWrapper, SceneGraph],})export default class ColorAverage { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, ElementRef, viewChild } from '@angular/core';import { beforeRender, NgtArgs } from 'angular-three';import { NgtpColorAverage, NgtpEffectComposer, NgtpVignette } from 'angular-three-postprocessing';import * as THREE from 'three';
@Component({ selector: 'app-scene-graph', template: ` <!-- Colorful scene that will be converted to grayscale --> <ngt-mesh #mesh1 [position]="[-1.5, 0, 0]"> <ngt-torus-knot-geometry *args="[0.4, 0.15, 100, 16]" /> <ngt-mesh-standard-material color="#ff6b6b" [metalness]="0.3" [roughness]="0.4" /> </ngt-mesh>
<ngt-mesh #mesh2 [position]="[0, 0, 0]"> <ngt-dodecahedron-geometry *args="[0.6, 0]" /> <ngt-mesh-standard-material color="#4ecdc4" [metalness]="0.3" [roughness]="0.4" /> </ngt-mesh>
<ngt-mesh #mesh3 [position]="[1.5, 0, 0]"> <ngt-octahedron-geometry *args="[0.5, 0]" /> <ngt-mesh-standard-material color="#ffe66d" [metalness]="0.3" [roughness]="0.4" /> </ngt-mesh>
<ngtp-effect-composer> <ngtp-color-average /> <ngtp-vignette [options]="{ darkness: 0.5, offset: 0.3 }" /> </ngtp-effect-composer> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtArgs, NgtpEffectComposer, NgtpColorAverage, NgtpVignette],})export class SceneGraph { private mesh1Ref = viewChild.required<ElementRef<THREE.Mesh>>('mesh1'); private mesh2Ref = viewChild.required<ElementRef<THREE.Mesh>>('mesh2'); private mesh3Ref = viewChild.required<ElementRef<THREE.Mesh>>('mesh3');
constructor() { beforeRender(({ clock }) => { const t = clock.getElapsedTime(); const mesh1 = this.mesh1Ref().nativeElement; const mesh2 = this.mesh2Ref().nativeElement; const mesh3 = this.mesh3Ref().nativeElement;
mesh1.rotation.x = t * 0.5; mesh1.rotation.y = t * 0.3; mesh2.rotation.x = t * 0.4; mesh2.rotation.y = t * 0.6; mesh3.rotation.x = t * 0.3; mesh3.rotation.y = t * 0.5; }); }}The color average effect converts the scene to grayscale by averaging the RGB channels, creating a desaturated look.
import { NgtpEffectComposer, NgtpColorAverage } from 'angular-three-postprocessing';
@Component({ template: ` <ngtp-effect-composer> <ngtp-color-average /> </ngtp-effect-composer> `, imports: [NgtpEffectComposer, NgtpColorAverage],})export class SceneGraph {}Options
Section titled “Options”| Property | Type | Default | Description |
|---|---|---|---|
blendFunction | BlendFunction | BlendFunction.NORMAL | How the effect blends with scene |
Example: Grayscale Scene
Section titled “Example: Grayscale Scene”import { BlendFunction } from 'postprocessing';
@Component({ template: ` <ngt-mesh> <ngt-sphere-geometry *args="[1, 32, 32]" /> <ngt-mesh-standard-material color="hotpink" /> </ngt-mesh>
<ngtp-effect-composer> <ngtp-color-average [options]="{ blendFunction: BlendFunction.NORMAL }" /> </ngtp-effect-composer> `, imports: [NgtpEffectComposer, NgtpColorAverage, NgtArgs], schemas: [CUSTOM_ELEMENTS_SCHEMA],})export class SceneGraph { protected BlendFunction = BlendFunction;}- Use
BlendFunction.SOFT_LIGHTorBlendFunction.OVERLAYfor partial desaturation - Combine with
NgtpVignettefor a classic black-and-white film look - This effect is simpler than
NgtpHueSaturationwhen you just need grayscale