NgtsSpotLight
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-spot-light', template: ` <ngt-canvas [camera]="{ position: [5, 3, 5], fov: 50 }"> <app-soba-wrapper *canvasContent [grid]="false" [lights]="false"> <app-scene-graph /> </app-soba-wrapper> </ngt-canvas> `, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'spot-light-demo relative block h-full' }, imports: [NgtCanvas, SobaWrapper, SceneGraph],})export default class SpotLight { static clientProviders = [provideNgtRenderer()];}import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';import { NgtArgs } from 'angular-three';import { depthBuffer } from 'angular-three-soba/misc';import { NgtsSpotLight } from 'angular-three-soba/staging';
@Component({ selector: 'app-scene-graph', template: ` <!-- Floor --> <ngt-mesh [rotation]="[-Math.PI / 2, 0, 0]" receiveShadow> <ngt-plane-geometry *args="[20, 20]" /> <ngt-mesh-standard-material color="#222" /> </ngt-mesh>
<!-- Objects to illuminate --> <ngt-mesh [position]="[0, 0.5, 0]" castShadow> <ngt-box-geometry *args="[1, 1, 1]" /> <ngt-mesh-standard-material color="white" /> </ngt-mesh>
<ngt-mesh [position]="[-2, 0.4, 1]" castShadow> <ngt-sphere-geometry *args="[0.4, 32, 32]" /> <ngt-mesh-standard-material color="white" /> </ngt-mesh>
<ngt-mesh [position]="[2, 0.6, -1]" castShadow> <ngt-cone-geometry *args="[0.4, 0.8, 32]" /> <ngt-mesh-standard-material color="white" /> </ngt-mesh>
<!-- Volumetric spot lights --> <ngts-spot-light [options]="{ position: [-3, 4, 0], angle: 0.5, penumbra: 0.5, intensity: 2, color: '#ff005b', volumetric: true, attenuation: 5, anglePower: 5, depthBuffer: depth, }" />
<ngts-spot-light [options]="{ position: [3, 4, 0], angle: 0.5, penumbra: 0.5, intensity: 2, color: '#0EEC82', volumetric: true, attenuation: 5, anglePower: 5, depthBuffer: depth, }" />
<!-- Ambient light for base illumination --> <ngt-ambient-light [intensity]="0.1" /> `, schemas: [CUSTOM_ELEMENTS_SCHEMA], changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtArgs, NgtsSpotLight],})export class SceneGraph { protected readonly Math = Math;
// Depth buffer for soft volumetric lighting depth = depthBuffer(() => ({ size: 256, frames: Infinity }));}NgtsSpotLight is a port of Drei’s SpotLight which provides an enhanced spot light with optional volumetric lighting effect.
Creates a visible light cone that simulates light scattering through atmosphere or dust.
NgtsSpotLight
Basic Volumetric Spot Light
<ngts-spot-light [options]="{ position: [0, 5, 0], angle: 0.5, intensity: 1, color: 'white' }"/>Stage Lighting Effect
<ngts-spot-light [options]="{ position: [5, 10, 0], angle: 0.3, attenuation: 5, anglePower: 5, intensity: 2, color: '#ffaa00' }"/>Without Volumetric Cone
<ngts-spot-light [options]="{ position: [0, 5, 0], volumetric: false, intensity: 1, angle: 0.5 }"/>Debug Mode
<ngts-spot-light [options]="{ position: [3, 5, 3], debug: true, angle: 0.4, intensity: 1 }"/>With Depth Buffer for Soft Shadows
@Component({ template: ` <ngts-spot-light [options]="{ position: [0, 5, 0], depthBuffer: depthBuffer.texture(), angle: 0.5 }" /> `,})export class Scene { depthBuffer = depthBuffer();}Colored Light Cone
<ngts-spot-light [options]="{ position: [0, 8, 0], color: '#ff0066', angle: 0.6, attenuation: 8, opacity: 0.8, intensity: 2 }"/>Custom Cone Shape
<ngts-spot-light [options]="{ position: [0, 5, 0], radiusTop: 0.05, radiusBottom: 2, angle: 0.5, attenuation: 10 }"/>NgtsSpotLightShadow
A shadow caster that projects textured shadow patterns.
Basic Shadow Pattern
<ngts-spot-light [options]="{ position: [0, 5, 0], angle: 0.5 }"> <ngts-spot-light-shadow [options]="{ distance: 0.4, scale: 1 }" /></ngts-spot-light>With Texture Pattern
<ngts-spot-light [options]="{ position: [0, 5, 0], angle: 0.5 }"> <ngts-spot-light-shadow [options]="{ distance: 0.4, alphaTest: 0.5, scale: 1, width: 512, height: 512, map: shadowTexture }" /></ngts-spot-light>High Resolution Shadow
<ngts-spot-light [options]="{ position: [0, 8, 0], angle: 0.4 }"> <ngts-spot-light-shadow [options]="{ width: 1024, height: 1024, map: patternTexture }" /></ngts-spot-light>Custom Shader
Create animated or custom shadow effects with a GLSL shader:
<ngts-spot-light [options]="{ position: [0, 5, 0] }"> <ngts-spot-light-shadow [shader]="customShader" [options]="{ scale: 2 }" /></ngts-spot-light>customShader = ` varying vec2 vUv; uniform sampler2D uShadowMap; uniform float uTime;
void main() { vec2 uv = vUv; // Animated wave effect float wave = sin(uv.x * 10.0 + uTime) * 0.5 + 0.5; gl_FragColor = vec4(vec3(wave), 1.0); }`;Shader Uniforms
The shadow shader provides these uniforms and varyings:
| Type | Name | Description |
|---|---|---|
varying vec2 | vUv | UVs of the shadow casting plane |
uniform sampler2D | uShadowMap | The texture provided to the map prop |
uniform float | uTime | Current time for animations |
Output the alpha channel where 1 is opaque shadow and 0 is transparent:
gl_FragColor = vec4(vec3(1.), 1.); // Opaque shadowgl_FragColor = vec4(vec3(0.), 1.); // Transparent (no shadow)Notes
- Volumetric lighting creates a visible cone mesh simulating light scattering
- The
attenuationcontrols how quickly the volumetric effect fades - Use
depthBufferfrom thedepthBuffer()function for soft volumetric shadows anglePoweraffects the sharpness of the cone’s edge falloff- Shadow patterns require a texture with an alpha channel
- Custom shaders allow for animated or procedural shadow effects
Options
options input accepts any properties from THREE.SpotLight in addition to the following:
Properties
| name | type | description |
|---|---|---|
| depthBuffer | THREE.DepthTexture | Depth texture for soft volumetric lighting. Default: null |
| attenuation | number | Light attenuation factor. Controls how quickly light fades. Default: 5 |
| anglePower | number | Power of the light cone angle falloff. Default: 5 |
| radiusTop | number | Radius of the light cone at the top. Default: 0.1 |
| radiusBottom | number | Radius of the light cone at the bottom. Default: angle * 7 |
| opacity | number | Opacity of the volumetric light cone. Default: 1 |
| color | THREE.ColorRepresentation | Color of the light. Default: 'white' |
| volumetric | boolean | Whether to render the volumetric light cone mesh. Default: true |
| debug | boolean | Whether to show the SpotLightHelper for debugging. Default: false |
| distance | number | Distance of the light. Default: 5 |
| angle | number | Angle of the light cone. Default: 0.15 |