TL;DR
The post examines the visual problem caused by the classic Lambertian term max(0, L·N), which leaves surfaces facing away from a single directional light uniformly dark. The author explores two simple one-line remaps — a linear shift and its square — and shows the squared variant matches values and derivatives at the domain endpoints via Hermite interpolation and is used by the author for rendering clouds.
What happened
The author revisits the common Lambertian diffuse factor max(0, L·N), noting that the clamping hides geometry on faces facing away from a single directional light. Typical production work avoids this via multiple lights, textures, ambient occlusion, or environment lighting, but those are not convenient one-liners for quick tests or demos. A straightforward fix is to map the dot product from [-1,1] to [0,1] with 0.5 + 0.5*(L·N); that eliminates fully black regions but brightens the scene. Squaring that expression — (0.5 + 0.5*(L·N))^2 — produces images that keep shading gradients on backfaces while remaining closer to the original Lambertian response in lit areas. The author points out that this squared function matches values and slopes of the clamped function at x = ±1, and that Hermite interpolation explains why this quadratic is an optimal low-order polynomial for those constraints. Screenshots shown use light intensity of 1, include gamma correction, and omit tone mapping and other post-processing.
Why it matters
- Provides a single-line shading alternative that preserves visible geometry on backfaces without adding extra lights or textures.
- Maintains smoother gradients on surfaces not directly facing the light, improving visual cues in simple scenes and tests.
- Matches values and derivatives at the domain endpoints, making it an algebraically motivated low-order approximation.
- Easy to implement in shaders and useful for quick prototypes or stylistic rendering where strict physical accuracy is not required.
Key facts
- Standard diffuse (Lambertian) reflectance is typically implemented as max(0, L·N), where L is light direction and N is surface normal.
- The dot product term arises from geometric spreading of light over surface area; the clamp prevents negative contributions from backfacing surfaces.
- A linear remap 0.5 + 0.5*(L·N) maps the dot product from [-1,1] to [0,1], removing completely black regions but increasing overall brightness.
- Squaring that remap, (0.5 + 0.5*(L·N))^2, yields a darker response than the linear tweak in bright areas while retaining gradients on backfaces.
- The squared formula coincides in value and first derivative with the clamped max(0, x) at x = -1 and x = 1, making it the optimal low-order polynomial under those Hermite constraints.
- Hermite interpolation can produce a polynomial that matches specified values and derivatives at points; here N=3 (four conditions) leads to a quadratic solution for this case.
- Screenshots in the post were produced with light intensity set to 1, gamma correction applied, and no tone-mapping or additional post-processing.
- The author reports using the squared remap for rendering clouds in their own game.
What to watch next
- Whether this quadratic remap behaves acceptably when integrated into full PBR pipelines or with multiple light sources: not confirmed in the source.
- How the approach interacts with environment lighting or more complex BRDFs — the author speculates a relation to a hemisphere-limited environment map but did not check the math.
- Practical adoption details such as energy conservation effects, artistic controls, or artifacts in high-dynamic-range scenes: not confirmed in the source.
- The author's reported use for clouds in their game, suggesting at least one real-world application (confirmed in the source).
Quick glossary
- Lambertian / diffuse reflection: A simple surface model that reflects light equally in all directions; commonly approximated in renderers by max(0, L·N).
- Dot product (L·N): A scalar product of two unit vectors (light direction and surface normal) that encodes the cosine of the angle between them, used to scale incoming light by incidence angle.
- Hermite interpolation: A polynomial interpolation technique that matches specified values and derivatives at given points, producing a polynomial of minimal degree that satisfies those constraints.
- Gamma correction: A nonlinear adjustment applied to image intensities to account for display and perceptual nonlinearities; often applied to rendered images before display.
- Tone mapping: Post-processing that remaps high-dynamic-range image values to a displayable range; the post's screenshots omitted this step.
Reader FAQ
Does the squared remap keep backfaces from being completely black?
Yes; (0.5 + 0.5*(L·N))^2 maps negative dot-product values to positive intensities, so backfaces retain shading gradients.
Is this formula physically correct or energy conserving?
Not confirmed in the source.
Why square the linear remap?
Squaring darkens the bright side while preserving gradients on the dark side; algebraically it also matches value and slope at the domain endpoints, making it a low-order Hermite match.
Has the author used this in real projects?
The author says they use the squared remap for clouds in their game (confirmed in the source).
lisyarus blog Articles Projects Contacts About // I write stuff about math, simulation, graphics, gamedev, and programming RSS feed A silly diffuse shading model 2025 Dec 31 Happy New Year…
Sources
- A silly diffuse shading model
- How do I get rid of these strange black patterns?
- Black spots on the model
- Shading with squared falloff always makes everything black
Related posts
- Exploring Whether Bundler Can Match uv’s Package Installation Speed
- MIT OCW: Street-Fighting Mathematics — Course Readings and Textbook (2008)
- Interactive Cycling Simulation Shows Mini Neural Net Riders Evolving