AcademySoftwareFoundation / AcademySoftwareFoundation/OpenPBR
Clarify the coat absorption behaviour for partial coverage
- Dominant language
- CSS
- Stars
- 793
- Forks
- 44
- PR merge metrics
- No merged PRs in 30d
Description
While working on an implementation of OpenPBR, I’ve noticed an ambiguity in how `coat_weight` affects coat absorption.
In summary, the question is whether `coat_weight` should be treated as partial coverage of a full-thickness coat (applying full coat absorption first then interpolating, i.e. “exponent → lerp”) or as a variable thickness applied uniformly (interpolating the `coat_color` first then applying the exponential absorption, i.e. “lerp → exponent”).
This distinction affects the resulting colour, in particular hue, especially for mid-range values of `coat_weight` that are neither fully off (0) nor fully on (1). The current specification does not clarify the exact behaviour (an explicit equation would be welcome), and each interpretation has valid arguments in its favor. The wording (_"Coverage weight of coat slab"_, _"presence weight of the coat"_) suggests “exponent → lerp”, but both Adobe and Autodesk implementations I’ve tested give results consistent with “lerp → exponent” with a distinctive hue shift.
## Fraction of coverage (exponent → lerp)
This interpretation treats `coat_weight` as a fraction of a fully dense, full-thickness coat layer. The model applies the absorption exponent to the `coat_color` first, then interpolates based on `coat_weight` between that absorption and the absence of absorption (i.e. white).
From an artist's perspective:
- Because the absorption is fully computed first, then simply blended, it is easier to anticipate how adjusting `coat_weight` will affect the final colour.
- There's a more direct link between the input `coat_color` and the result: the resulting hue remains closely tied to the given `coat_color` when using partial weights, making it easier to obtain a target result.
- Since both reflection intensity and absorption scale consistently with `coat_weight`, the relationship between them can feel more intuitive.
- It is not the behaviour they are used to in Subtance and Arnold.

## Fraction of thickness (lerp → exponent)
This interpretation treats `coat_weight` as partial thickness of the coat layer. The model interpolates based on `coat_weight` between an absence of absorption (i.e. white) and the given `coat_color` first, then applies the exponential absorption of that colour.
Partial weights lead to a “physically expected” hue shift. As you reduce thickness, the hue changes due to less absorption. For example the resulting appearance of a coat with an orange `coat_color` will shift toward pink or an eggshell tint at intermediate weights. This aligns with the behaviour I have observed in Substance and Arnold.
From an artist's perspective:
- This hue shift can be unintuitive, and achieving a desired result can be more difficult since there is no direct link between the `coat_color` and the obtained result.
- This hue shift can be desirable if the intent is to represent wear or brush strokes, as it more closely physically models such cases.
- The coat reflection intensity decreases linearly with the `coat_weight`, but the absorption color shift does not.
- In fact, if we treated the `coat_weight` as a shorthand for thickness, we should do so for coat reflectivity as well, which means it could only be "on" or "off".

## Current behaviour in existing implementations
Here are some comparisons. Note how despite the differences in the models, all three show this egg-shell hue shift with partial coverage.
Also note how the tinting effect drops more rapidly than the reflectivity when `coat_weight` reduces.
Coating effect in Substance with Adobe Standard Material:

Coating effect in Arnold with Standard Surface:

Coating effect in Arnold with OpenPBR:

## Conclusion
The fact that both Substance and Arnold implement a similar behaviour is a strong argument in favour of keeping and formalising that behaviour. However, what matters for artists is predictability and direct control, and it might be easier for them to manually add a missing hue shift than to correct an unexpected or unwanted one. Eitherway, the specification should be explicit about the expected effect.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reviewing the specification wording for coat_weight, coat_color, and coat absorption, then compare the two described interpretations: “exponent → lerp” and “lerp → exponent.” The issue is done when the specification explicitly selects and defines one behavior, ideally with an equation that resolves partial-coverage results.
Written by the indexing model from the issue text.
Assessment
- Domain
- computer-graphics
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100