third_party/tinyexr/tools/envmap/README.md
Pure-C11 tool for image-based-lighting representations. Converts between
environment-map projections and fits compact lighting bases (spherical
harmonics, spherical gaussians). Links tir + texcomp + texpipe + libtinyexr3;
only the CLI does HDR EXR I/O.
convert) — resample between equirectangular
(Y-up), cube (KTX/D3D/GL face order +X,-X,+Y,-Y,+Z,-Z, matching
texpipe's cube convention), and octahedral (Y-up pole). Cube output
writes 6 face EXRs that texpipe --cube-face consumes directly; octa output
feeds texpipe --octa.sh) — project an env onto real SH up to order 4
((L+1)² RGB coeffs), with an optional Hanning window to curb ringing. Order 2
(9 coeffs) is the classic diffuse-irradiance ambient term.sg) — fit K SG lobes (Fibonacci axes, shared
sharpness ≈ 0.35·K, non-negative least-squares amplitudes) — a compact
all-frequency-ish lighting representation.ibl / irradiance / brdflut) — GGX-prefiltered
specular radiance as a roughness-indexed BC6H cube KTX2, cosine-convolved
diffuse irradiance cube, and the split-sum BRDF DFG LUT (R=scale,
G=bias). Together these are the split-sum inputs a PBR shader samples.shade) — builds the float IBL from an env and
renders a lit sphere (split-sum diffuse + specular) to an HDR EXR. Doubles as
the ground truth for the validation harness (make envmap-pbr-test), which
shades under the IBL with source vs BC7-compressed material and reports the
shaded-image PSNR + normal angular error — the "does compression hurt the final
image" gate. It also demonstrates PBR-tuned format choice: BC5 (2-channel,
reconstruct-Z) vs BC7 for normals — BC5 mean 0.35°/max 0.99° vs BC7 1.39°/8.00°.sh/sg also write <out>_recon.exr, an equirect reconstruction from the
coefficients for eyeballing quality.
make envmap # build/envmap/envmap
make envmap-c11-gate # strict pure-C11 (no <stdio.h> outside the CLI)
make envmap-test # projection round-trips, solid-angle, SH/SG
# equirect HDR -> 6 cube face EXRs (feed texpipe --cube-face)
envmap convert -i env.exr --from equirect --to cube --size 256 -o cube.exr
# equirect -> octahedral (feed texpipe --octa)
envmap convert -i env.exr --to octa --size 512 -o octa.exr
# order-2 SH (9 coeffs) + reconstruction
envmap sh -i env.exr --order 2 -o env.sh
# 24-lobe spherical gaussians + reconstruction
envmap sg -i env.exr --lobes 24 -o env.sg
# split-sum IBL inputs
envmap ibl -i env.exr --face 128 --samples 64 -o spec.ktx2 # BC6H roughness cube
envmap irradiance -i env.exr --face 32 -o irr.ktx2 # BC6H diffuse cube
envmap brdflut --size 256 -o brdf.exr # DFG LUT (R=scale G=bias)
envmap shade -i env.exr --albedo 0.9,0.3,0.2 --roughness 0.25 --metallic 0 -o sphere.exr
envmap convert -i env.exr --to octa --size 512 -o octa.exr
texpipe -i octa.exr -o octa.ktx2 --format bc6h --octa --container ktx2
include/envmap.h, prefix em_)em_convert, em_dir_to_uv/em_uv_to_dir, em_texel_solid_angle,
em_sample, em_foreach_texel; em_sh_project/em_sh_eval/em_sh_window;
em_sg_fit/em_sg_eval; plus em_hammersley and hemisphere/sphere sampling.
Direction round-trips < 1e-6 (all 3 projections); per-texel solid angles sum to 4π within 0.03%; equirect→cube→equirect resample ≈ 87 dB PSNR; SH white-furnace (constant env → DC only) and SH-4 smooth-field RMS ≈ 4e-4; SG constant-energy preserved with bounded ripple.
--asg (anisotropic SG) is reserved; the fit is isotropic today.Apache-2.0. Depends on tir (BSD-3), texcomp/texpipe (Apache-2.0),
TinyEXR core (BSD-3).
envmap is original work and ships no third-party code — the library is pure
C11 and the CLI reads/writes HDR images through the TinyEXR core (exr.h) only.
It does implement several published algorithms; credit is due to their authors
(techniques/math, independently implemented — no code copied):
src/envmap_ibl.c): Karis, "Real Shading
in Unreal Engine 4", SIGGRAPH 2013 course notes — GGX importance sampling,
the prefiltered environment map, and the environment BRDF LUT.src/envmap_proj.c): Cigolle, Donow,
Evangelakos, Mara, McGuire & Meyer, "A Survey of Efficient Representations
for Independent Unit Vectors", JCGT 2014 (building on Meyer et al., 2010).src/envmap_sample.c):
the standard radical-inverse construction.src/envmap_sh.c): Ramamoorthi & Hanrahan,
"An Efficient Representation for Irradiance Environment Maps", SIGGRAPH 2001;
Sloan, "Stupid Spherical Harmonics (SH) Tricks", GDC 2008.src/envmap_sg.c): Wang, Ren, Gong, Snyder & Guo,
"All-Frequency Rendering of Dynamic, Spatially-Varying Reflectance",
SIGGRAPH Asia 2009 (SG lighting representation); Green, "Spherical Harmonic
Lighting", GDC 2003.tir (BSD-3-Clause), texcomp/texpipe (Apache-2.0),
TinyEXR core (BSD-3-Clause).