Skip to content

Commit 6e7fc85

Browse files
authored
PBR Neutral docs (#4687)
* update commerce to PBR Neutral * added adoption info
1 parent ebd55ed commit 6e7fc85

4 files changed

Lines changed: 72 additions & 45 deletions

File tree

packages/modelviewer.dev/examples/config.ocio

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ roles:
5757
displays:
5858
sRGB:
5959
- !<View> {name: Standard, colorspace: sRGB}
60-
- !<View> {name: Commerce, colorspace: Commerce sRGB}
60+
- !<View> {name: PBR Neutral, colorspace: PBR Neutral sRGB}
6161
- !<View> {name: AgX, colorspace: AgX Base sRGB}
6262
- !<View> {name: Filmic, colorspace: Filmic sRGB}
6363
- !<View> {name: Filmic Log, colorspace: Filmic Log}
@@ -79,7 +79,7 @@ displays:
7979
- !<View> {name: False Color, colorspace: AgX False Color Rec.2020}
8080
- !<View> {name: Raw, colorspace: Non-Color}
8181
active_displays: [sRGB, Display P3, Rec.1886, Rec.2020]
82-
active_views: [Standard, Commerce, AgX, Filmic, Filmic Log, False Color, Raw]
82+
active_views: [Standard, PBR Neutral, AgX, Filmic, Filmic Log, False Color, Raw]
8383
inactive_colorspaces: [Luminance Compensation Rec.2020, Luminance Compensation sRGB, Luminance Compensation P3, AgX False Color Rec.709, AgX False Color P3, AgX False Color Rec.1886, AgX False Color Rec.2020]
8484

8585
colorspaces:
@@ -487,18 +487,18 @@ colorspaces:
487487
- !<ColorSpaceTransform> {src: Rec.1886, dst: Rec.2020}
488488

489489
- !<ColorSpace>
490-
name: Commerce sRGB
491-
family: Commerce
490+
name: PBR Neutral sRGB
491+
family: PBR Neutral
492492
equalitygroup:
493493
bitdepth: 32f
494494
description: |
495-
Commerce Image Encoding for sRGB Display
495+
Khronos PBR Neutral Image Encoding for sRGB Display
496496
isdata: false
497497
from_scene_reference: !<GroupTransform>
498498
children:
499499
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709}
500500
- !<AllocationTransform> {allocation: lg2, vars: [-6, 12]}
501-
- !<FileTransform> {src: commerce.cube, interpolation: tetrahedral}
501+
- !<FileTransform> {src: pbrNeutral.cube, interpolation: tetrahedral}
502502
- !<ColorSpaceTransform> {src: Linear Rec.709, dst: sRGB}
503503

504504
looks:

packages/modelviewer.dev/examples/lut-writer.mjs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
// Running:
1717
// node lut-writer.mjs
18-
// produces: commerce.cube
18+
// produces: pbrNeutral.cube
1919

2020
import * as fs from 'fs';
2121

@@ -25,8 +25,8 @@ const log2Min = -6;
2525
const log2Max = 12;
2626

2727
const text = [
28-
`TITLE "Commerce sRGB"`,
29-
`# Commerce sRGB LUT`,
28+
`TITLE "PBR Neutral sRGB"`,
29+
`# PBR Neutral sRGB LUT`,
3030
`DOMAIN_MIN 0 0 0`,
3131
`DOMAIN_MAX 1 1 1`,
3232
`LUT_3D_SIZE ${size}`,
@@ -49,7 +49,7 @@ function rgb2string(r, g, b) {
4949
return `${round(r)} ${round(g)} ${round(b)}`;
5050
}
5151

52-
function commerce(r, g, b) {
52+
function pbrNeutral(r, g, b) {
5353
const startCompression = 0.8 - 0.04;
5454
const desaturation = 0.15;
5555

@@ -87,10 +87,10 @@ function commerce(r, g, b) {
8787
for (let b = 0; b < size; ++b) {
8888
for (let g = 0; g < size; ++g) {
8989
for (let r = 0; r < size; ++r) {
90-
text.push(commerce(r, g, b));
90+
text.push(pbrNeutral(r, g, b));
9191
}
9292
}
9393
}
9494
text.push('');
9595

96-
fs.writeFileSync('commerce.cube', text.join('\n'));
96+
fs.writeFileSync('pbrNeutral.cube', text.join('\n'));

packages/modelviewer.dev/examples/commerce.cube renamed to packages/modelviewer.dev/examples/pbrNeutral.cube

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
TITLE "Commerce sRGB"
2-
# Commerce sRGB LUT
1+
TITLE "PBR Neutral sRGB"
2+
# PBR Neutral sRGB LUT
33
DOMAIN_MIN 0 0 0
44
DOMAIN_MAX 1 1 1
55
LUT_3D_SIZE 57

packages/modelviewer.dev/examples/tone-mapping.html

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<!DOCTYPE html>
1818
<html lang="en">
1919
<head>
20-
<title>PBR Tone Mapping</title>
20+
<title>PBR Neutral Tone Mapping</title>
2121
<meta charset="utf-8">
2222
<meta name="description" content="Performance optimization for &lt;model-viewer&gt;">
2323
<meta name="viewport" content="width=device-width, initial-scale=1">
@@ -134,9 +134,10 @@ <h2>Tone Mapping Considerations for Physically-Based Rendering</h2>
134134
<a href="#purpose">The purpose of tone mapping</a><br/>
135135
<a href="#tradeoffs">Tradeoffs</a><br/>
136136
<a href="#needs">The needs of e-commerce</a><br/>
137-
<a href="#commerce">Commerce tone mapper</a><br/>
137+
<a href="#commerce">Khronos PBR Neutral tone mapper</a><br/>
138138
<a href="#validation">Validation</a><br/>
139139
<a href="#ocio">OpenColorIO profile</a><br/>
140+
<a href="#adoption">Adoption</a><br/>
140141
<a href="#white">White point</a><br/>
141142
</p>
142143

@@ -279,16 +280,16 @@ <h3 id="tradeoffs">Tradeoffs</h3>
279280
src="../assets/ACESset.glb"
280281
camera-orbit="150deg auto auto"
281282
camera-controls
282-
alt="3D model of ACES/Commerce tone mapping reachable colors."
283+
alt="3D model of ACES/Neutral tone mapping reachable colors."
283284
>
284285
<p>
285286
<select id="set">
286287
<option value="../assets/ACESset.glb">ACES</option>
287-
<option value="../assets/CommerceSet.glb">Commerce</option>
288+
<option value="../assets/CommerceSet.glb">PBR Neutral</option>
288289
</select>Tone Mapping Function
289290
</p>
290291
</model-viewer>
291-
<figcaption>Comparison of the ACES and Commerce tone mapping reachable colors. The cube represents the [0, 1] space in linear light - no sRGB curve has been applied.</figcaption>
292+
<figcaption>Comparison of the ACES and PBR Neutral tone mapping reachable colors. The cube represents the [0, 1] space in linear light - no sRGB curve has been applied.</figcaption>
292293
</figure>
293294

294295
<p>Note that canary yellow, bright greens and blues are all impossible to
@@ -361,14 +362,16 @@ <h3 id="needs">The needs of e-commerce</h3>
361362
generalizable to these situations, but there will be additional challenges
362363
beyond tone mapping as well.</p>
363364

364-
<h3 id="commerce">Commerce tone mapper</h3>
365+
<h3 id="commerce">Khronos PBR Neutral tone mapper</h3>
365366

366-
<p>The Commerce tone mapper is designed to be simple to implement, fast to
367-
run, and faithfully reproduce color as much as possible while eliminating
368-
HDR artifacts around highlights. It is intended to be 1:1 for colors up to a
369-
certain maximum value, with the remainder used as headroom for the
370-
compressed highlights. It turns out 1:1 is a little trickier than it
371-
sounds.</p>
367+
<p>The Khronos PBR Neutral tone mapper is designed to be simple to
368+
implement, fast to run, and faithfully reproduce color as much as possible
369+
while eliminating HDR artifacts around highlights. It is intended to be 1:1
370+
for colors up to a certain maximum value, with the remainder used as
371+
headroom for the compressed highlights. I developed it under the auspices of
372+
the Khronos 3D Commerce working group to create an industry standard for
373+
e-commerce and an improved alternative for any PBR render that currently
374+
disables tone mapping.</p>
372375

373376
<p>I found that an actual 1:1 tone mapping function led to slightly
374377
desaturated colors, most noticeably for dark colors. I tracked this problem
@@ -397,7 +400,7 @@ <h3 id="commerce">Commerce tone mapper</h3>
397400
<p>I chose to fit a simple 1/x function and match the piecewise slope of our
398401
1:1 portion, as this gives an asymptote with a reasonable tail. It has only
399402
a single parameter: the value where we switch from the linear to the
400-
nonlinear function. The purpose of the Commerce tone mapper is to be a
403+
nonlinear function. The purpose of the Khronos PBR Neutral tone mapper is to be a
401404
standard and thus without parameters, so I chose 0.8 after much testing.
402405
However, this is likely the most natural place to adjust the curve to HDR
403406
output from sRGB.</p>
@@ -425,8 +428,11 @@ <h3 id="commerce">Commerce tone mapper</h3>
425428
brain an alternate perceptual cue, which smoothly encodes several orders of
426429
magnitude more brightness than is available in the output screen.</p>
427430

428-
<p>The complete shader code is quite small, with only three divides and
429-
those only applied to colors over the 1:1 limit:<br/>
431+
<p>Careful use of the minimum and maximum of the three color channel values
432+
ensures that this tone mapping function has continuous gradients everywhere
433+
and in all dimensions, which is key to avoiding eye-catching artifacts in
434+
the output renders. The complete shader code is quite small, with only three
435+
divides and those only applied to colors over the 1:1 limit:<br/>
430436
<code>
431437
float startCompression = 0.8 - 0.04;
432438
float desaturation = 0.15;
@@ -451,7 +457,7 @@ <h3 id="commerce">Commerce tone mapper</h3>
451457

452458
<figure>
453459
<img src="../assets/commerce-linear.png"/>
454-
<figcaption>The Commerce tone mapping function, which maps linear brightness to the [0, 1] range. The compression function is piecewise in three parts: blue for the contrast toe, green for the linear 1:1 region, and red for the compression region. The desaturation curve is purple.</figcaption>
460+
<figcaption>The Khronos PBR Neutral tone mapping function, which maps linear brightness to the [0, 1] range. The compression function is piecewise in three parts: blue for the contrast toe, green for the linear 1:1 region, and red for the compression region. The desaturation curve is purple.</figcaption>
455461
</figure>
456462

457463
<figure>
@@ -482,7 +488,7 @@ <h3 id="commerce">Commerce tone mapper</h3>
482488
>
483489
<p>
484490
<select id="tonemapper">
485-
<option value="5">Commerce</option>
491+
<option value="5">PBR Neutral</option>
486492
<option value="1">Linear/Clamped</option>
487493
<option value="4">ACES</option>
488494
<option value="6">AgX</option>
@@ -532,7 +538,7 @@ <h3 id="validation">Validation</h3>
532538
shadow-intensity="1"
533539
>
534540
</model-viewer>
535-
<figcaption>Commerce tone mapper white furnace validation.</figcaption>
541+
<figcaption>Khronos PBR Neutral tone mapper white furnace validation.</figcaption>
536542
</figure>
537543

538544
<p>The first difference is due to multi-scattering, which causes the
@@ -556,29 +562,28 @@ <h3 id="ocio">OpenColorIO profile</h3>
556562
representing color space conversions and color grading, supported by many 3D
557563
authoring tools. To represent the most general possible functions, instead
558564
of specifying equations they use 3D lookup tables (LUTs). To help authors
559-
try out Commerce tone mapping within their existing workflows, I have
565+
try out Khronos PBR Neutral tone mapping within their existing workflows, I have
560566
generated an equivalent OCIO config and a LUT in the common .cube format.
561-
You can download <a href="commerce.cube">commerce.cube</a> and <a
567+
You can download <a href="pbrNeutral.cube">pbrNeutral.cube</a> and <a
562568
href="config.ocio">config.ocio</a>, which is modified from the
563-
<a href="https://www.blender.org/">Blender</a> config to add Commerce as a
569+
<a href="https://www.blender.org/">Blender</a> config to add PBR Neutral as a
564570
view transform for color management with an sRGB display device.</p>
565571

566-
<p>In order to try Commerce tone mapping in Blender, you need to replace the
572+
<p>In order to try PBR Neutral tone mapping in Blender, you need to replace the
567573
config.ocio file with the above version. The original file can be found in
568574
the Blender install directory, e.g.
569575
<code>Blender/Contents/Resources/4.0/datafiles/colormanagement</code> on a
570-
Mac install. You will also need to add <code>commerce.cube</code> to the
576+
Mac install. You will also need to add <code>pbrNeutral.cube</code> to the
571577
<code>luts</code> directory on the same path. Then start Blender and at the
572578
bottom of the Render tab, under Color Management, select sRGB for Display
573-
Device and Commerce for View Transform.</p>
579+
Device and PBR Neutral for View Transform.</p>
574580

575581
<p>I have tested this on a Macbook Pro, which uses a P3 display, but found
576582
that I achieved consistent colors when setting the display device to sRGB.
577583
This was to achieve consistency with Chrome and Safari rendering on the same
578584
device, so this may change in the future as color management on the web
579-
improves. Note that Blender is not glTF-compliant for unlit materials,
580-
because it applies its view transform to the entire scene, when it should
581-
not be applied to unlit materials. This makes the 3D Macbeth model above a
585+
improves. Note that unlike &lt;model-viewer&gt;, Blender also applies its
586+
view transform to unlit materials. This makes the 3D Macbeth model above a
582587
little harder to use, as the unlit spheres can no longer be used as a
583588
reference.</p>
584589

@@ -588,21 +593,43 @@ <h3 id="ocio">OpenColorIO profile</h3>
588593

589594
<p><code>
590595
- !&lt;ColorSpace&gt;
591-
name: Commerce sRGB
592-
family: Commerce
596+
name: PBR Neutral sRGB
597+
family: PBR Neutral
593598
equalitygroup:
594599
bitdepth: 32f
595600
description: |
596-
Commerce Image Encoding for sRGB Display
601+
Khronos PBR Neutral Image Encoding for sRGB Display
597602
isdata: false
598603
from_scene_reference: !&lt;GroupTransform&gt;
599604
children:
600605
- !&lt;ColorSpaceTransform&gt; {src: Linear CIE-XYZ E, dst: Linear Rec.709}
601606
- !&lt;AllocationTransform&gt; {allocation: lg2, vars: [-6, 12]}
602-
- !&lt;FileTransform&gt; {src: commerce.cube, interpolation: tetrahedral}
607+
- !&lt;FileTransform&gt; {src: pbrNeutral.cube, interpolation: tetrahedral}
603608
- !&lt;ColorSpaceTransform&gt; {src: Linear Rec.709, dst: sRGB}
604609
</code></p>
605610

611+
<h3 id="adoption">Adoption</h3>
612+
613+
<p>Of course a standardized color-accurate tone mapper is most useful when
614+
it is universally available, so that everyone from artists to marketers to
615+
end users can see the product the same way and ensure quality. This is
616+
precisely why Khronos is pushing this as an industry standard for renderers
617+
and authoring tools alike to adopt, as an option for tools that support
618+
multiple tone mappers, and as the default for those that don't. This section
619+
will be occasionally updated to reflect our progress in adoption across
620+
industry tools.</p>
621+
622+
<p>So far two major open-source renderers have added PBR Neutral tone
623+
mapping, and both should be available in public releases in March 2024: <a
624+
href="https://github.com/mrdoob/three.js/pull/27668">Three.js</a> and <a
625+
href="https://github.com/google/filament/pull/7597">Filament</a>.
626+
<a href="lightingandenv/#toneMapping">&lt;model-viewer&gt;</a> already
627+
supports it, currently under the name "commerce", and it will become default
628+
in v4. It is already the default in the &lt;model-viewer&gt; <a
629+
href="../editor">editor</a>. A proposal has been made to add it to <a
630+
href="https://projects.blender.org/blender/blender/issues/118824">Blender</a>,
631+
and discussions are ongoing with other major 3D authoring tools.</p>
632+
606633
<h3 id="white">White point</h3>
607634

608635
<p>The tl;dr of this section is that you can safely skip it. It is a

0 commit comments

Comments
 (0)