Working notes: rendering primer

Not part of the article. Context for the author and for a fresh Claude Code session picking this up.

Where this came from

Drafted between 2026-09-03 and 2026-09-08 in ~/maritime_ws/src/bluerobotics_models, as docs/reference/rendering-primer.md, alongside an audit of that repository’s glTF parts library. It was moved here on 2026-09-08 because the content is general background and nothing in it is specific to that project. The originating repository keeps its own project-specific documents (model-spec.md, VISUAL_ASSET_PIPELINE_REVIEW.md, pbr-and-gltf.md); this article deliberately shares none of their content.

Full history is in the git log of bluerobotics_models under docs/reference/rendering-primer.md, ending at commit f94df76.

Stage

Stage 2, annotated outline, per AUTHOR_WORKFLOW.md. About 5,600 words, nearly all of it italic notes describing what each subsection will say. Front matter carries draft: true and no AI disclosure callout, since disclosure is added at stage 3.

Settled content that should survive into the draft rather than being rewritten:

  • the two tables in section 1, shading models and formats;
  • the naming table and the terminology paragraph in section 1;
  • the BRDF expression and the notes under 1.1.1;
  • the rendered figure and its caption.

Audience and voice

Written for a general engineer who does not work in graphics, does not work in CAD, and is not a computer vision specialist. Ordinary engineering vocabulary; graphics jargon is defined at first use or not used.

The terminology, and how it was settled

This took several rounds and is the spine of the article. Do not re-open it without cause.

shading model = reflection model + parameterization. The shading model is the package a renderer evaluates at a point on a surface. Its two halves are the reflection model, the equation, and the parameterization, the author-facing values plus the rule mapping them onto the equation’s variables.

“Shading model” is the name used, and the overload is disclosed rather than avoided. An earlier draft banned the phrase over a claimed collision. That was wrong. The collision is with “Phong shading” alone, which also names a per-pixel renderer technique; “shading model” itself is safe and is the term Marschner and Shirley, Hoffman, Burley, Unreal and OpenPBR all use. Section 1 carries a table of the five names in use and says which sources use which.

“Material model” is avoided because glTF already uses material for the data object holding a shading model’s parameters, so the two would sit one word apart.

The reflection model and the parameterization are not one to one. One reflection model can take several parameterizations: Cook-Torrance takes metallic-roughness and specular-glossiness. The reverse never happens. That asymmetry is the reason the two are named separately at all.

Empirical against physically based is a statement about derivation, not a test. The checkable test is physically plausible, from Lewis 1994: energy conserving and reciprocal. The two do not nest. Normalized Blinn-Phong is empirical yet passes; shipped physically based models routinely fail because real-time renderers approximate. Section 2.3 holds both cases. An earlier draft got this backwards.

The layered supersets are not parameterizations. Disney principled, Standard Surface and OpenPBR add lobes, so both halves grow. They live in section 2.2.4, not section 3. Section 3 covers only the two genuine parameterizations of one reflection model.

Section 2 is named for reflection models, not shading models. Settled during the first PMR. Section 2’s subsections treat Phong, Lambert, Cook-Torrance and the rest, and those are reflection models; only paired with a parameterization do they become the shading models of the 1.1.3 table. Section 2 is therefore “The reflection models in common use”, 2.1 and 2.2 likewise, and 2.2.2 says explicitly that Cook-Torrance is the reflection model half and section 3 makes the pairing. Section 3 remains parameterizations, and 1.1.3 remains the place the two are put together.

Names are used consistently. The table in 1.1.3 names shading models by their pairing, so “Cook-Torrance with metallic-roughness”. The format table uses those same names. The article notes that most sources shorten this to “metallic-roughness”, letting the parameterization stand for the pair.

SDF and URDF were removed as off topic. They describe scenes rather than carry geometry, and the question that prompted them was answered elsewhere.

What was verified, and against what

Everything factual was checked against a primary source rather than recalled. Sources actually consulted:

Source Used for
Marschner and Shirley, Fundamentals of Computer Graphics, 4th ed. ch. 4.5 shading; 8.2.5 the Phong shading name collision; ch. 10 surface shading; 18.1 radiometry and the BRDF definition; 18.3 photometry; ch. 24 reflection models, the plausibility test, the coupled model, the Phong tuning quote
Eck, Introduction to Computer Graphics ch. 4 the five empirical coefficients; 4.1.3 flat and smooth shading; the PBR glossary entry; declines to cover PBR in the body
glTF 2.0 specification source §3.9 materials; Appendix B the full BRDF, the metallic blend, the squared-roughness statement, and its own admission that its Fresnel mix breaks energy conservation
Filament PBR documentation the BSDF decomposition sentence; the split of Standard model from Parameterization; roughness remapping; clearcoat as a second specular lobe; multiscattering energy loss
Hoffman, SIGGRAPH 2013 course notes the D and G slot point; plausibility as reciprocity plus energy conservation
Burley, SIGGRAPH 2012 the five principles, quoted from page 12; the parameter list; the metallic blend as the ancestor of metallic-roughness
pbrt 4th ed. the alternative taxonomy by origin: measured, phenomenological, simulation, wave optics, geometric optics
OpenPBR specification the slab model and the fixed layer order

The two textbook PDFs now sit in refs/ beside this file. That directory is gitignored (**/refs/ in the repository’s .gitignore) and is local only: they are source texts consulted while drafting, not article assets, and this repository publishes to a public site. Text was extracted with pdftotext -layout.

Claims that did not survive checking, and are now stated correctly: that a physically based model must take measurable parameters (Burley’s first principle says the opposite); that Disney principled is the common ancestor of both parameterizations (specular-glossiness predates it); that COLLADA and OpenGL materials have four coefficients (five, with emission).

The figure

shading_models.png, generated by shading_models_figure.py, which needs only numpy and pillow. Eight spheres, one per row of the table in 1.1.3, identical geometry and identical lighting in every panel so the shading model is the only variable. The Cook-Torrance panels follow glTF Appendix B: GGX distribution, height-correlated Smith visibility, Schlick Fresnel, the dielectric and metal BRDFs mixed by metallic. Lighting is computed in linear space and encoded to sRGB at the end.

Two things the figure is meant to demonstrate rather than assert. The constant sphere reads as a flat disc, which makes the case for lighting better than a sentence. And the metallic-roughness and specular-glossiness panels are identical to within 4e-15, which is the parameterization argument of 1.1.2 shown rather than claimed. Verify with:

python3 -c "
import numpy as np, shading_models_figure as R
n,mask=R.sphere_normals(); v=np.zeros_like(n); v[...,2]=1.0
a=R.PANELS[6][2](n,v)[mask]; b=R.PANELS[7][2](n,v)[mask]
print(np.abs(a-b).max())"

Rerun python3 shading_models_figure.py after any change; it writes beside itself.

brdf_lobes.png, generated by lobe_figure.py, added during the first PMR to answer the author’s request for a visual demonstration of the lobe with units. Six polar plots, the light fixed at 45 degrees, radius the BRDF value in inverse steradians on a logarithmic scale spanning six decades, the same scale in every panel. It imports _ggx and _smith_vis from shading_models_figure.py so both figures use one implementation. The captions state measured numbers, so rerun and re-measure before changing them: peaks run 0.159 for Lambert to 8,266 for Cook-Torrance at roughness 0.03, and the full width at half maximum is 1.48 degrees at roughness 0.1 and 0.13 degrees at 0.03.

Building it exposed a bug in _ggx, now fixed: the denominator carried an additive 1e-9, which is negligible at the roughness the sphere figure uses but dominates it for a smooth surface, where the denominator falls to alpha squared. It capped the roughness 0.03 peak at 17 instead of 8,266. The guard is now multiplicative, np.maximum(np.pi * d * d, 1e-30). shading_models.png regenerates bit-identical across the change, so nothing in the settled figure moved.

Decisions settled by the author, 2026-09-08

The stage-2 open questions were put to the author and answered. These are settled; treat them as constraints on the stage-3 draft rather than as things to re-litigate.

  1. Length: one long article. No split. All eleven sections stay in a single post, which will run well past the 800 to 2500 words CLAUDE.md calls typical for this site. The argument runs continuously and a split would force restating the terminology of section 1 in the second half. Flag the overrun in the response when the draft lands, per AUTHOR_WORKFLOW.md stage 3, but do not compress to hit a target.
  2. Section 10, the glossary: keep it in full. All four subsections. The duplication against the in-place definitions is accepted, because a reference-length article is read for lookup as well as end to end.
  3. Section 9, the worked example: a Khronos sample asset. From glTF-Sample-Assets, so the reader can open the same bytes. Pick one that ships in both .gltf and .glb and carries a metallic-roughness material with more than one texture, so 9.2’s reference chain, 9.3’s material-to-texture-to-image path and 9.4’s two containers all land on one object. BoxTextured is the smallest that works; DamagedHelmet exercises the full six-property material. Choose when drafting section 9 and record which, with its upstream URL and license.
  4. Figures: produce all four. Lobe illustrations for section 2, the cost comparison for 2.4, a roughness and metallic sweep for 6.8, and sRGB against linear for 8.4. All four go in shading_models_figure.py or siblings beside it, keeping the numpy and pillow only constraint. Each follows the rule the existing figure set: hold everything fixed but the one variable, and demonstrate the claim the text makes rather than illustrating it decoratively.

Still open, and not yet put to the author:

  • The thread. graphics is the category tag and this is the first post in it. Under carrel’s own thresholds a dedicated folder is warranted at three posts and a landing page at five, so nothing is due yet.

Style rules the author has set

These came up repeatedly during drafting and are worth honoring.

  • No overt significance framing. Do not announce that a point matters, that something is the crux, or that a distinction is important. State the thing.
  • Use the field’s standard terms. Verify a claimed overload against sources before banning a word or coining a replacement.
  • Do not introduce a term without defining it at first use. “Lobe”, “layer”, “slot” and “family” were each challenged on this ground.
  • US spellings.
  • Do not hard-wrap prose.
  • Bold sparingly.