NgtsAccumulativeShadows
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-accumulative-shadows', template: ` <ngt-canvas shadows [camera]="{ position: [4, 4, 4], fov: 50 }"> <app-soba-wrapper *canvasContent [grid]="false" [lights]="false"> <app-scene-graph /> </app-soba-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'accumulative-shadows-demo relative block h-full' }, imports: [NgtCanvas, SobaWrapper, SceneGraph],})export default class AccumulativeShadows { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import { NgtArgs } from 'angular-three';import { NgtsAccumulativeShadows, NgtsEnvironment, NgtsRandomizedLights } from 'angular-three-soba/staging';
@Component({ selector: 'app-scene-graph', template: ` <!-- Objects casting shadows - positioned above shadow plane --> <ngt-mesh [position]="[0, 0.5, 0]" castShadow> <ngt-sphere-geometry *args="[0.5, 32, 32]" /> <ngt-mesh-standard-material color="#ff6b6b" /> </ngt-mesh>
<ngt-mesh [position]="[-1.2, 0.4, 0.5]" castShadow> <ngt-box-geometry *args="[0.6, 0.6, 0.6]" /> <ngt-mesh-standard-material color="#4ecdc4" /> </ngt-mesh>
<ngt-mesh [position]="[1.2, 0.35, 0.3]" castShadow> <ngt-cone-geometry *args="[0.4, 0.7, 32]" /> <ngt-mesh-standard-material color="#a29bfe" /> </ngt-mesh>
<!-- Accumulative shadows plane - positioned at y=0 (ground level) --> <ngts-accumulative-shadows [options]="{ temporal: true, frames: 100, color: '#316d39', colorBlend: 2, alphaTest: 0.65, opacity: 2, scale: 14, position: [0, 0.001, 0], }" > <ngts-randomized-lights [options]="{ amount: 8, radius: 4, ambient: 0.5, intensity: Math.PI, position: [5, 5, -10], bias: 0.001, }" /> </ngts-accumulative-shadows>
<!-- Environment for lighting --> <ngts-environment [options]="{ preset: 'city' }" /> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtArgs, NgtsAccumulativeShadows, NgtsRandomizedLights, NgtsEnvironment],})export class SceneGraph { protected readonly Math = Math;}NgtsAccumulativeShadows is a port of Drei’s AccumulativeShadows which creates a planar, Y-up oriented shadow-catcher that can accumulate into soft shadows with zero performance impact after all frames have accumulated.
It can be temporal (accumulating over time for better performance) or instantaneous (more expensive depending on frame count).
You must pair it with light sources and scene objects that cast shadows. Best used with NgtsRandomizedLights, which jiggles lights around to create realistic raycast-like shadows and ambient occlusion.
<ngt-color *args="['goldenrod']" attach="background" /><app-scene-objects />
<ngts-accumulative-shadows [options]="{ temporal: true, frames: 100, color: 'black', colorBlend: 2, opacity: 0.8, scale: 12, alphaTest: 0.75 }"> <ngts-randomized-lights [options]="{ amount: 8, radius: 4, ambient: 0.5, bias: 0.001, position: [5, 5, -10] }" /></ngts-accumulative-shadows>
<ngts-environment [options]="{ preset: 'city' }" />Options
options input accepts any properties from THREE.Group in addition to the following:
Properties
| name | type | description |
|---|---|---|
| frames | number | How many frames it can render, more yields cleaner results but takes more time. Default: 40 |
| blend | number | If frames is set to Infinity, blend controls the refresh ratio. Default: 20 |
| limit | number | Limits the amount of frames rendered if frames is set to Infinity, usually to recover performance once a movable scene has settled. Default: Infinity |
| scale | number | Scale of the shadow plane. Default: 10 |
| temporal | boolean | Temporal accumulates shadows over time which is more performant but has visual regression over instant results. Default: false |
| opacity | number | Opacity of the shadow plane. Default: 1 |
| alphaTest | number | Discards alpha pixels below this threshold. Default: 0.75 |
| color | THREE.ColorRepresentation | Shadow color. Default: 'black' |
| colorBlend | number | Color blend, how much colors turn to black. 0 is black. Default: 2 |
| resolution | number | Buffer resolution for shadow map. Default: 1024 |
| toneMapped | boolean | Texture tone mapping. Default: true |