A local JSON file stores this scene, lights, emission images, surface paint, finishes, blocker settings and camera. No account or server.
Optional artistic cutoff, not part of the paper. Smoothly fades to zero at each light’s reach. Both Compare paths use the same cutoff.
GPU time is asynchronous timer-query data when available; CPU submission is not GPU time. Direct area lighting, with analytic visibility in the one-blocker shadow stage. No reflection probes, point lights or bounced light. Fill, cosmetic accents and bloom are presentation effects.
H or Escape restores hidden UI. All code, geometry and LUT data live in this file.
DOI: 10.1145/2897824.2925895
Eric Heitz · Jonathan Dupuy
Stephen Hill · David Neubelt
ACM TRANSACTIONS ON GRAPHICS · SIGGRAPH 2016 · 35(4)
This workshop is an independent interactive implementation of the authors’ LTC technique. The research, mathematical construction, GGX fitting approach and polygon-integration method are theirs—not a new technique invented for this demo.
A transformed cosine approximates the cosine-weighted BRDF. Apply the inverse transform to the light polygon, clip to the cosine hemisphere, then analytically sum its oriented spherical edges (§§3–5.1). Textured emitters use an additional filtering approximation (§§5.2–5.4).
The workshop, shield, material brushes, conveyor, disc trails, editors and linked inspector. The inherited lookup tables were regenerated locally; they are not the original published binary tables. The textured filter is approximate. The dedicated shadow stage adds one planar blocker beneath a rectangular light. Other scenes are unshadowed. There is no indirect illumination.
Click a light or surface to select it. Paint the light in Emission; use Surface to coat, polish, scuff, spray or wipe. After Hours adds an editable sign and curved bench. The shadow stage isolates one blocker, with ray-tested LTC and GGX comparisons. Save setup keeps painted images and finishes.
Choose Scenes for five separate environments. Scene gives a few useful controls; Paint edits materials; Lights → Outline opens the polygon editor. The shield and disc are available in the Impact range and Surface works.
Inspect is the only main entry into the lighting analysis. Inside, choose Explain or Compare. Back to scene or Escape returns to the same scene and previous pause state. Clicking ordinary geometry no longer opens an unexpected mode.
Left-drag empty space to orbit; right-drag to look; WASD to move; Q/E vertically. B opens Paint. F holds the shield, T fires the launcher, R recalls the disc. H toggles photo mode. Mouse capture is never automatic.
Scene switches preserve each scene’s current lights, painted floor, and camera during this session. Options → Save setup exports the currently open scene. Prior Surface Works v3 setups remain supported. Browser graphics only. Shadows are limited to the dedicated stage; no reflected non-emissive geometry, bounced light, or validated headset frame budget.
Move light as a physical object, paint a receiving material, freeze the action, then inspect the math at one pixel. The bay is a custom Three.js implementation of Real-Time Polygonal-Light Shading with Linearly Transformed Cosines, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt, SIGGRAPH 2016.
The scanner is one real, moving rectangular LTC emitter, reusing the overhead fixture. The conveyor carries three rotating test pieces. Painting or coating them changes their actual materials. The rolling disc and floor contacts write polish, scuff or coating trails into the same material maps as your brush. These are authored finish changes, not a physical abrasion simulation. Workshop motion pauses in Explain/Compare and resumes on return unless you had frozen it yourself.
W A S D moves; Q E moves vertically; Shift accelerates. Right drag looks, Wheel dollies. No automatic pointer lock. Drag a light to translate it; Alt + drag tilts it. On Shield, hold Space to charge and release to pulse. F holds/drops the shield; T tests an impact. On Disc, click the scene to throw toward the cursor; R recalls; G suspends it. P freezes the whole simulation. H hides the UI; Escape restores it.
Paint brushes the floor and stamps whole surface parts on props. Probe pins any visible receiving surface. Explain selects the actual emitting polygon to inspect. Compare freezes simulation and textures automatically, but still allows camera and material edits; every relevant edit resets the reference.
Fit the cosine-weighted isotropic GGX BRDF with a transformed cosine. Transform the polygon by M⁻¹, clip against the cosine horizon, normalize directions, then sum oriented spherical edges. This integral is analytic for the fitted LTC; the fit to GGX is approximate. Concave shapes preserve signed contributions. Up to five independent emitters, with 3–12 vertices each, are summed per fragment.
The emitting image is generated into a linear HDR atlas. Seven spatially filtered levels use a masked, normalized, separable Gaussian with a half-texture margin. The eighth level is a shared per-emitter mean. The filter widens outside the polygon; a 12×12 mask-weighted far-field mean is computed once per dirty emitter into a 1×5 target and shared by all receiving pixels. Shading orthogonally projects onto the emitter plane in cosine space and chooses blur from σ = √(r² / (2A)). Diffuse and specular use their own transformed configuration. This is an implementation of the paper's approximate filtering idea, not an exact texture integral or a byte-for-byte reproduction of its filter. Finite taps, finite resolution, separability, the margin and the isotropic kernel add error. Highly varied textures and rough/grazing configurations can differ visibly from the reference.
Shield impact rings are part of the actual emission texture. Panel flashes also change whole-polygon radiance. Dark structural frames and tiny decorative accent strips are presentation geometry; they do not become extra lights. The field face is an opaque emissive surface, not physically correct transmissive glass.
Four samples per emitter per pixel per pass: two uniform-area and two GGX-NDF samples, with balance-heuristic multiple importance sampling and correlated Smith masking. Concave sampling uses non-overlapping triangles. The reference samples the original, unfiltered emission atlas; textured diffuse is integrated numerically as well. Constant-color diffuse shares the analytic Lambertian integral. Linear floating-point accumulation, identical exposure, no denoiser. Relative RGB error is length(LTC − reference) / max(length(reference), 0.03). It includes reference noise and texture-filter error, not just LTC fitting error. These are finite-sample reference estimates, not exact ground truth.
The embedded 64×64 lookup tables are preserved from Light Lab v1. They were regenerated locally from the reference fitting approach, not copied byte-for-byte from the authors' published data. Coordinates are (r, √(1−N·V)), with α = r². Four matrix coefficients, norm and average Schlick Fresnel are interpolated explicitly. The original paper describes a θ-based coordinate instead. The fitting source is included below in a non-executed source block.
General scene shadows, indirect illumination, anisotropic material fitting, mirror-scene reflections and physical transparent-shield transmission are not supported. The shadow stage handles one planar blocker and one rectangular emitter. Disc collisions are a lightweight toy simulation with floor, room bounds and coarse prop bounds—not a general rigid-body engine. The original clean studio remains available under Settings.
The entire application, Three.js r140, procedural art, shaders and LUT data are embedded. Requires WebGL 2 and floating-point color attachments. No runtime network requests. GPU timing is shown only when timer queries are supported; frame rate and CPU work are not substitutes for GPU timing.
THREE.JS — MIT LICENSE Copyright © 2010–2022 Three.js authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. LTC REFERENCE FITTING APPROACH — BSD-STYLE LICENSE Copyright (c) 2017, Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * If you use (or adapt) the source code in your own work, please include a reference to the paper: Real-Time Polygonal-Light Shading with Linearly Transformed Cosines. Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt. ACM Transactions on Graphics (Proceedings of ACM SIGGRAPH 2016) 35(4), 2016. Project page: https://eheitzresearch.wordpress.com/415-2/ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IMPLEMENTATION NOTES The embedded LUTs were regenerated locally; they are not the original published binary tables. The local C++ fitting source is included in this HTML as a non-executed text block named “ltc-fit-source”. The renderer uses the paper's analytic, horizon-clipped spherical-edge expression, evaluated with atan2 for numerical robustness.
Preparing the scenes and polygon-light shaders...