Visual enhancement system with lighting effects and post-processing capabilities for photorealistic rendering and advanced visual effects in 3D visualizations.
Abstract base class for all visual effects applied during rendering.
/**
* Abstract base class for visual effects
* Provides hooks for pre-render and post-render processing
*/
abstract class Effect {
/** Initialize effect with properties */
constructor(props?: any);
/** Pre-render setup and preparation */
preRender(gl: WebGL2RenderingContext, opts: PreRenderOptions): void;
/** Post-render processing and cleanup */
postRender(gl: WebGL2RenderingContext, opts: PostRenderOptions): void;
/** Get shader modules required by this effect */
getModules(): ShaderModule[];
/** Get effect parameters for shader uniforms */
getParameters(): any;
/** Clean up effect resources */
cleanup(): void;
/** Effect configuration properties */
readonly props: any;
}
interface PreRenderOptions {
/** Current viewport */
viewport: Viewport;
/** Effect manager instance */
effectManager: any;
/** Current render pass */
renderPass: string;
/** Whether this is a picking pass */
isPicking: boolean;
/** Layers being rendered */
layers: Layer[];
}
interface PostRenderOptions {
/** Current viewport */
viewport: Viewport;
/** Effect manager instance */
effectManager: any;
/** Current render pass */
renderPass: string;
/** Whether this is a picking pass */
isPicking: boolean;
/** Rendered layers */
layers: Layer[];
/** Target framebuffer */
target?: Framebuffer;
}
interface EffectContext {
/** WebGL rendering context */
gl: WebGL2RenderingContext;
/** Luma.gl device */
device: Device;
/** Current viewport */
viewport: Viewport;
/** Render pass identifier */
renderPass: string;
/** Effect manager */
effectManager: any;
}Comprehensive lighting system managing multiple light sources for realistic 3D rendering.
/**
* Lighting effect managing multiple light sources
* Provides ambient, directional, and point lighting for 3D scenes
*/
class LightingEffect extends Effect {
/** Initialize lighting effect with light sources */
constructor(props: LightingEffectProps);
/** Add a light source */
addLight(light: AmbientLight | DirectionalLight | PointLight): void;
/** Remove a light source */
removeLight(light: AmbientLight | DirectionalLight | PointLight): void;
/** Update light configuration */
setProps(props: Partial<LightingEffectProps>): void;
/** Get shader modules for lighting */
getModules(): ShaderModule[];
/** Get lighting uniforms */
getParameters(): any;
/** Currently active lights */
readonly lights: (AmbientLight | DirectionalLight | PointLight)[];
}
interface LightingEffectProps {
/** Array of light sources */
lights?: (AmbientLight | DirectionalLight | PointLight)[];
/** Ambient light color when no ambient lights provided */
ambientLightColor?: [number, number, number];
/** Shadow mapping configuration */
shadowMaps?: boolean;
/** Number of shadow maps */
numberOfShadowMaps?: number;
}Usage Examples:
import {
LightingEffect,
AmbientLight,
DirectionalLight,
PointLight
} from "@deck.gl/core";
// Create comprehensive lighting setup
const ambientLight = new AmbientLight({
color: [255, 255, 255],
intensity: 0.3
});
const directionalLight = new DirectionalLight({
color: [255, 255, 255],
intensity: 1.0,
direction: [-1, -3, -1]
});
const pointLight = new PointLight({
color: [255, 255, 255],
intensity: 2.0,
position: [0, 0, 1000],
attenuation: [1, 0, 0.0001]
});
const lightingEffect = new LightingEffect({
lights: [ambientLight, directionalLight, pointLight]
});
// Use in Deck
const deck = new Deck({
effects: [lightingEffect],
// ... other props
});
// Dynamic lighting changes
const timeOfDay = (hour) => {
const sunIntensity = Math.max(0, Math.cos((hour - 12) * Math.PI / 12));
const sunColor = [255, 255 - 50 * (1 - sunIntensity), 200 + 55 * sunIntensity];
directionalLight.setProps({
color: sunColor,
intensity: sunIntensity,
direction: [
Math.sin((hour - 6) * Math.PI / 12),
-Math.cos((hour - 6) * Math.PI / 12),
-0.5
]
});
};Uniform ambient lighting affecting all surfaces equally.
/**
* Ambient light providing uniform illumination
* Affects all surfaces equally with no directionality
*/
class AmbientLight {
/** Initialize ambient light */
constructor(props: AmbientLightOptions);
/** Update light properties */
setProps(props: Partial<AmbientLightOptions>): void;
/** Light color RGB */
readonly color: [number, number, number];
/** Light intensity multiplier */
readonly intensity: number;
}
interface AmbientLightOptions {
/** Light color in RGB [0-255] */
color?: [number, number, number];
/** Light intensity [0-1+] */
intensity?: number;
}Directional light source simulating distant light like the sun.
/**
* Directional light simulating distant light sources
* Provides parallel light rays from a specific direction (like sunlight)
*/
class DirectionalLight {
/** Initialize directional light */
constructor(props: DirectionalLightOptions);
/** Update light properties */
setProps(props: Partial<DirectionalLightOptions>): void;
/** Light color RGB */
readonly color: [number, number, number];
/** Light intensity multiplier */
readonly intensity: number;
/** Light direction vector */
readonly direction: [number, number, number];
/** Shadow map configuration */
readonly shadow: boolean;
}
interface DirectionalLightOptions {
/** Light color in RGB [0-255] */
color?: [number, number, number];
/** Light intensity [0-1+] */
intensity?: number;
/** Direction vector [x, y, z] */
direction?: [number, number, number];
/** Enable shadow casting */
shadow?: boolean;
/** Shadow map size */
shadowMapSize?: number;
/** Shadow bias to prevent shadow acne */
shadowBias?: number;
}Point light source with position and attenuation.
/**
* Point light source with position-based attenuation
* Emits light in all directions from a specific point
*/
class PointLight {
/** Initialize point light */
constructor(props: PointLightOptions);
/** Update light properties */
setProps(props: Partial<PointLightOptions>): void;
/** Light color RGB */
readonly color: [number, number, number];
/** Light intensity multiplier */
readonly intensity: number;
/** Light position in world coordinates */
readonly position: [number, number, number];
/** Attenuation coefficients [constant, linear, quadratic] */
readonly attenuation: [number, number, number];
}
interface PointLightOptions {
/** Light color in RGB [0-255] */
color?: [number, number, number];
/** Light intensity [0-1+] */
intensity?: number;
/** Light position [x, y, z] */
position?: [number, number, number];
/** Attenuation [constant, linear, quadratic] */
attenuation?: [number, number, number];
}Experimental light source attached to camera position.
/**
* Experimental camera-attached light source
* Light follows camera position and direction
*/
class _CameraLight {
/** Initialize camera light */
constructor(props: CameraLightOptions);
/** Update light properties */
setProps(props: Partial<CameraLightOptions>): void;
/** Light color RGB */
readonly color: [number, number, number];
/** Light intensity multiplier */
readonly intensity: number;
}
interface CameraLightOptions {
/** Light color in RGB [0-255] */
color?: [number, number, number];
/** Light intensity [0-1+] */
intensity?: number;
}Experimental sun light with time-based positioning calculations.
/**
* Experimental sun light with astronomical calculations
* Automatically positions sun based on time and location
*/
class _SunLight {
/** Initialize sun light */
constructor(props: SunLightOptions);
/** Update sun properties */
setProps(props: Partial<SunLightOptions>): void;
/** Calculate sun position for given time and location */
getSunPosition(timestamp: number, latitude: number, longitude: number): {
azimuth: number;
elevation: number;
};
/** Light color RGB */
readonly color: [number, number, number];
/** Light intensity multiplier */
readonly intensity: number;
/** Current sun direction */
readonly direction: [number, number, number];
/** Timestamp for sun calculation */
readonly timestamp: number;
}
interface SunLightOptions {
/** Light color in RGB [0-255] */
color?: [number, number, number];
/** Light intensity [0-1+] */
intensity?: number;
/** Timestamp for sun position (Unix timestamp) */
timestamp?: number;
/** Latitude for sun calculation */
latitude?: number;
/** Longitude for sun calculation */
longitude?: number;
}Usage Examples:
import { _SunLight } from "@deck.gl/core";
// Realistic sun lighting based on time and location
const sunLight = new _SunLight({
color: [255, 255, 240],
intensity: 1.0,
timestamp: Date.now(),
latitude: 37.7749, // San Francisco
longitude: -122.4194
});
// Animate sun through the day
const animateSun = () => {
const now = Date.now();
sunLight.setProps({
timestamp: now
});
const sunPos = sunLight.getSunPosition(now, 37.7749, -122.4194);
console.log(`Sun elevation: ${sunPos.elevation}°, azimuth: ${sunPos.azimuth}°`);
};
setInterval(animateSun, 60000); // Update every minuteAbstract base class for post-processing effects applied after layer rendering.
/**
* Abstract base class for post-processing effects
* Applied after all layers are rendered to the screen
*/
abstract class PostProcessEffect extends Effect {
/** Initialize post-process effect */
constructor(props?: any);
/** Setup render targets and resources */
abstract setup(context: EffectContext): void;
/** Render the post-processing effect */
abstract render(context: EffectContext): void;
/** Whether effect modifies the color buffer */
abstract getModuleParameters(): any;
/** Clean up effect resources */
cleanup(): void;
}Usage Examples:
// Custom post-processing effect
class BloomEffect extends PostProcessEffect {
constructor(props = {}) {
super(props);
this.threshold = props.threshold || 0.7;
this.intensity = props.intensity || 1.0;
this.radius = props.radius || 1.0;
}
setup({device, viewport}) {
// Create framebuffers and shaders for bloom effect
this.bloomFramebuffer = device.createFramebuffer({
width: viewport.width,
height: viewport.height
});
this.blurFramebuffers = [
device.createFramebuffer({width: viewport.width / 2, height: viewport.height / 2}),
device.createFramebuffer({width: viewport.width / 4, height: viewport.height / 4})
];
}
render({gl, viewport, effectManager}) {
// 1. Extract bright areas
// 2. Apply Gaussian blur
// 3. Combine with original scene
// Implementation details...
}
getModuleParameters() {
return {
bloomThreshold: this.threshold,
bloomIntensity: this.intensity,
bloomRadius: this.radius
};
}
}
// Use custom effect
const deck = new Deck({
effects: [
new LightingEffect({lights: [...]}),
new BloomEffect({
threshold: 0.8,
intensity: 1.5,
radius: 2.0
})
]
});Built-in shader modules for lighting calculations.
// Shader modules for lighting (imported from shaderlib)
const gouraudLighting: ShaderModule;
const phongLighting: ShaderModule;
const shadow: ShaderModule;
interface ShaderModule {
/** Module name */
name: string;
/** Vertex shader code */
vs?: string;
/** Fragment shader code */
fs?: string;
/** Uniform definitions */
uniforms?: any;
/** Module dependencies */
dependencies?: ShaderModule[];
}How effects integrate with the rendering pipeline.
interface EffectManager {
/** Add effect to manager */
addEffect(effect: Effect): void;
/** Remove effect from manager */
removeEffect(effect: Effect): void;
/** Process all pre-render effects */
preDraw(opts: PreRenderOptions): void;
/** Process all post-render effects */
postDraw(opts: PostRenderOptions): void;
/** Get combined shader modules from all effects */
getModules(): ShaderModule[];
/** Get combined parameters from all effects */
getParameters(): any;
}Usage Examples:
import {
Deck,
LightingEffect,
AmbientLight,
DirectionalLight,
PointLight
} from "@deck.gl/core";
// Complex lighting scenario
const createDynamicLighting = () => {
// Base ambient lighting
const ambient = new AmbientLight({
color: [30, 30, 60],
intensity: 0.4
});
// Key light (main directional)
const keyLight = new DirectionalLight({
color: [255, 245, 235],
intensity: 1.2,
direction: [-1, -2, -1],
shadow: true
});
// Fill light (softer directional)
const fillLight = new DirectionalLight({
color: [235, 245, 255],
intensity: 0.6,
direction: [1, -1, 0.5]
});
// Accent point lights
const accentLights = [
new PointLight({
color: [255, 100, 100],
intensity: 2.0,
position: [-1000, -1000, 500],
attenuation: [1, 0, 0.0001]
}),
new PointLight({
color: [100, 255, 100],
intensity: 2.0,
position: [1000, 1000, 500],
attenuation: [1, 0, 0.0001]
})
];
return new LightingEffect({
lights: [ambient, keyLight, fillLight, ...accentLights],
shadowMaps: true,
numberOfShadowMaps: 2
});
};
// Create deck with dynamic lighting
const deck = new Deck({
effects: [createDynamicLighting()],
views: [new MapView({id: 'map'})],
initialViewState: {
longitude: -122.4,
latitude: 37.8,
zoom: 12,
pitch: 45
}
});
// Animate lighting based on time of day
const animateLighting = (hour) => {
const sunAngle = (hour - 6) * Math.PI / 12; // 6 AM = 0, 6 PM = π
const sunIntensity = Math.max(0.1, Math.sin(Math.max(0, sunAngle)));
// Update sun color based on angle
const sunColor = [
255,
255 - 80 * (1 - sunIntensity),
200 + 55 * sunIntensity
];
const lightingEffect = deck.props.effects[0];
const keyLight = lightingEffect.lights.find(light => light instanceof DirectionalLight);
keyLight.setProps({
color: sunColor,
intensity: sunIntensity,
direction: [
Math.sin(sunAngle),
-Math.cos(sunAngle),
-0.3
]
});
deck.redraw();
};
// Simulate day/night cycle
let currentHour = 6;
setInterval(() => {
currentHour = (currentHour + 0.25) % 24; // 15 minutes = 1 hour
animateLighting(currentHour);
}, 1000);