Procedural Caustics Generator — Settings, Tips, and Workflow ExamplesCaustics — the shimmering patterns of light created when rays refract through or reflect off a curved, transmissive surface — are a hallmark of realism in rendered water, glass, and other translucent materials. A procedural caustics generator produces these patterns algorithmically, enabling flexible, resolution-independent, and often real-time solutions suitable for VFX, games, simulations, and architectural visualization.
This article covers core concepts, practical settings, optimization tips, and workflow examples for integrating a procedural caustics generator into your pipeline. Whether you’re a shader artist, technical artist, or indie developer, you’ll gain insight into making believable caustics without relying on pre-baked textures.
1. Fundamentals of Caustics
Caustics occur when light is concentrated by refraction (through transparent media like water or glass) or reflection (off shiny surfaces). Two common visual types:
- Transmission caustics: Patterns on surfaces beneath water or behind glass due to refraction and internal focusing.
- Reflection caustics: Bright, often sharper highlights created by specular reflection off curved surfaces.
Key physical factors:
- Light direction and intensity
- Surface curvature and normals
- Index of refraction (IOR)
- Surface roughness and scattering
- Depth and absorption in participating media
A procedural generator simulates or approximates these factors using mathematical models inside shaders or compute routines.
2. Approaches to Procedural Caustics
- Ray-traced caustics (physically accurate)
- Pros: Highly accurate, physically plausible results.
- Cons: Expensive; requires ray tracing or photon mapping.
- Shadow-map / projective methods
- Pros: Fast and compatible with raster pipelines.
- Cons: Artifacts where projection doesn’t match geometry or when surfaces move.
- Screen-space caustics
- Pros: Real-time friendly; uses depth and normal buffers.
- Cons: Limited to visible pixels; can miss off-screen light paths.
- Texture-based procedural patterns
- Pros: Simple, artist-controllable, cheap.
- Cons: Not physically driven; may tile or look repetitive.
- Hybrid systems
- Combine offline/expensive solution for high accuracy with cheaper approximations at runtime.
3. Core Settings and Their Effects
Below are the typical parameters exposed in a caustics generator and guidance on how to use them.
- Light Direction (vector)
- Controls orientation of pattern; low-angle light stretches caustics.
- Light Intensity
- Scales brightness; use tone-mapped values for HDR workflows.
- Caustic Strength (gain)
- Multiplies generated pattern; useful to blend into scene lighting.
- Caustic Scale / Frequency
- Controls size of caustic features. Smaller scale = finer ripples.
- Anisotropy / Stretch
- Stretches pattern along one axis to simulate elongated specular paths.
- Smoothness / Blur Radius
- Softens high-frequency detail; simulates scattering and roughness.
- IOR (Index of Refraction)
- Influences focal behavior for refractive caustics; higher IOR intensifies bending.
- Absorption / Attenuation
- Darkens caustics with depth; critical for colored water.
- Depth Falloff / Distance Influence
- Reduces caustic contribution with distance to avoid far-field noise.
- Projection Mode (world, local, screen)
- Determines how patterns are projected onto surfaces.
- Temporal Jitter / Animation Speed
- Adds movement; match to water surface animation frequency.
- Sample Count / Quality
- Controls accuracy in stochastic or ray-based techniques.
4. Shader Implementation Patterns
- Compute surface normals and curvature
- Use analytic normals for parametric meshes or normal maps for complex surfaces.
- Generate light interaction
- For refraction, compute refracted ray direction using Snell’s law and trace toward receiving surfaces (approx via screen-space or ray-trace).
- Accumulate energy
- Map refracted/reflected rays to a light accumulation buffer (caustic map) using additive blending or splatting.
- Blur and filter
- Apply multi-scale blur / bilateral filtering to emulate scattering without losing pattern fidelity.
- Composite
- Blend caustic map into scene lighting using multiply/additive modes; modulate by albedo and shadowing.
Example pseudocode snippet (screen-space, conceptual):
// inputs: depthTex, normalTex, lightDir, causticParams vec3 worldPos = reconstructWorldPos(depthTex, uv); vec3 n = sampleNormal(normalTex, uv); vec3 refracted = refract(-lightDir, n, 1.0 / causticParams.ior); vec2 projUV = projectToSurface(refracted, worldPos); float energy = computeIntensity(n, lightDir) * occlusion(worldPos, refracted); causticMap[projUV] += energy;
(Place actual implementation details according to engine/shader language requirements.)
5. Performance & Optimization Tips
- Use screen-space or projective methods for most real-time needs; reserve ray tracing for high-end targets.
- Render caustics at a lower resolution and upsample with edge-aware upscaling or bilateral filters.
- Temporal accumulation: accumulate noisy caustics over frames and denoise with spatial-temporal filtering.
- Limit the area affected by caustics (mask by water volume or bounding box).
- Cache static or slow-moving caustics as lightmaps or atlases when possible.
- Use analytic approximations (e.g., normal derivatives or curvature maps) instead of tracing per pixel.
- Reduce sample counts with importance sampling; bias direction toward light lobes.
- Combine multiple LODs: high-detail caustics near camera, low-detail far away.
6. Artistic Controls and Practical Tips
- Match caustic scale to real-world scale: smaller ripples on a puddle produce smaller caustic spots than ocean waves.
- Use color absorption to convey depth and material (e.g., green/blue for water).
- Blend caustics with diffuse lighting rather than simply adding brightness; multiply by surface albedo to avoid blown-out highlights on dark surfaces.
- For glass objects, increase sharpness and reduce blur; for murky water, soften and tint the pattern.
- Animate parameters subtly: slight phase shift in pattern or light direction mimics sun movement and water flow.
- Balance realism and readability: strong caustics can distract from other scene details — dial strength accordingly.
7. Workflow Examples
Example A — Real-time Game Engine (Screen-Space Caustics)
- Render scene depth and normals.
- From the water surface mesh, compute surface normals (optionally via normal map).
- For each screen pixel under water, compute refracted ray direction using Snell’s law in view space.
- Project refracted ray to the receiving plane/depth buffer and splat energy into a low-res caustic render target.
- Temporal accumulate and bilateral blur to denoise.
- Composite into lighting pass using multiply with surface albedo and add specular contribution.
Practical tips:
- Use a ⁄2 or ⁄4 resolution buffer.
- Use a simple binary mask of water surface to skip non-water pixels.
- Use temporal reprojection to reduce noise.
Example B — Offline Render / VFX (High-Quality)
- Use photon mapping or path tracing with dedicated caustic photons.
- Emit photons from light sources; store hits after refracting through glass/water.
- Build a photon map or use density estimation to render caustic irradiance.
- Filter photons with kernel density estimation; composite into final render with physically-based shading.
Practical tips:
- Increase photon count for small-scale, high-frequency caustics.
- Use importance sampling near sharp curvature or high IOR materials.
Example C — Hybrid (Precomputed + Dynamic)
- Precompute high-frequency caustic detail for static parts (like a pool floor) into an atlas.
- For dynamic elements (moving water, glass), use a screen-space overlay blended with the atlas.
- Switch between precomputed and dynamic based on camera proximity.
Practical tips:
- Bake multiple tiles for different lighting angles or use spherical harmonics to approximate directional dependence.
- Use blending weights to smoothly transition between precomputed and dynamic maps.
8. Troubleshooting Common Issues
- Tiling/repetition: increase noise or use multiple layered procedural frequencies.
- Flat, unrealistic caustics: check normals and curvature; low normal variance produces weak patterns.
- Flicker when using temporal accumulation: ensure correct motion vectors and temporal reprojection.
- Caustics too bright: reduce gain or use HDR tone mapping; modulate by surface albedo.
- Missing caustics on thin geometry: project onto nearest large receiving surface or render a thin proxy plane for accumulation.
9. Example Parameter Presets (Starting Points)
- Calm pond: scale = 0.5, strength = 0.6, blur = 0.8, IOR = 1.33, absorption = low
- Choppy sea: scale = 2.5, strength = 0.9, blur = 0.3, IOR = 1.33, temporal jitter = medium
- Thick glass: scale = 0.8, strength = 1.2, blur = 0.1, IOR = 1.5, absorption = very low
- Murky pool: scale = 1.0, strength = 0.5, blur = 1.5, IOR = 1.33, absorption = high
10. Further Reading & Tools (Topics to Explore)
- Photon mapping and bidirectional path tracing (for offline accuracy)
- Screen-space algorithms and depth reprojection
- Wave and surface synthesis (Gerstner waves, FFT)
- Denoising (spatial-temporal bilateral filters, wavelet denoising)
- Engine-specific implementations: Unity shader graphs/HDRP caustics, Unreal Engine water/real-time ray tracing caustics, custom Vulkan/DirectX compute pipelines
Practical procedural caustics are a balance between physical principles and artistic control. Start with cheap, screen-space approaches for interactivity, then layer quality where needed with hybrid or ray-traced solutions. With careful masking, temporal filtering, and artist-friendly parameters, you can achieve convincing, performant caustics for a wide range of projects.
Leave a Reply