Skip to content

Commit 3d0df06

Browse files
add Cineon, Reinhard, Linear, none tone mapping options and update documention
1 parent 9066abc commit 3d0df06

File tree

12 files changed

+64
-50
lines changed

12 files changed

+64
-50
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/model-viewer-effects/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ npm install three @google/model-viewer @google/model-viewer-effects
5252
<script type="importmap">
5353
{
5454
"imports": {
55-
"three": "https://cdn.jsdelivr.net/npm/three@^0.170.0/build/three.module.min.js"
55+
"three": "https://cdn.jsdelivr.net/npm/three@^0.172.0/build/three.module.min.js"
5656
}
5757
}
5858
</script>

packages/model-viewer-effects/src/effect-composer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {ModelScene} from '@google/model-viewer/lib/three-components/ModelScene.j
1818
import {ReactiveElement} from 'lit';
1919
import {property} from 'lit/decorators.js';
2020
import {EffectComposer as PPEffectComposer, EffectPass, NormalPass, Pass, RenderPass, Selection} from 'postprocessing';
21-
import {ACESFilmicToneMapping, Camera, HalfFloatType, NeutralToneMapping, ToneMapping, UnsignedByteType, WebGLRenderer} from 'three';
21+
import {Camera, HalfFloatType, NeutralToneMapping, ToneMapping, UnsignedByteType, WebGLRenderer} from 'three';
2222

2323
import {IMVEffect, IntegrationOptions, MVEffectBase} from './effects/mixins/effect-base.js';
2424
import {disposeEffectPass, isConvolution, validateLiteralType} from './utilities.js';
@@ -71,7 +71,7 @@ export class EffectComposer extends PPEffectComposer {
7171

7272
private postRender() {
7373
const renderer = this.getRenderer();
74-
renderer.toneMapping = ACESFilmicToneMapping;
74+
renderer.toneMapping = NeutralToneMapping;
7575
renderer.autoClear = true;
7676
}
7777

packages/model-viewer-effects/src/effects/color-grade.ts

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,56 +13,59 @@
1313
* limitations under the License.
1414
*/
1515

16-
import { property } from 'lit/decorators.js';
17-
import { BlendFunction, BrightnessContrastEffect, HueSaturationEffect, ToneMappingEffect } from 'postprocessing';
18-
import { clamp, validateLiteralType, wrapClamp } from '../utilities.js';
19-
import { $updateProperties, MVEffectBase } from './mixins/effect-base.js';
20-
import { ToneMappingMode as PPToneMappingMode } from 'postprocessing';
21-
import { $effectComposer, $tonemapping } from '../effect-composer.js';
22-
import { ACESFilmicToneMapping, NoToneMapping } from 'three';
16+
import {property} from 'lit/decorators.js';
17+
import {BlendFunction, BrightnessContrastEffect, HueSaturationEffect, ToneMappingEffect, ToneMappingMode as PPToneMappingMode} from 'postprocessing';
18+
import {NeutralToneMapping, NoToneMapping} from 'three';
19+
20+
import {$effectComposer, $tonemapping} from '../effect-composer.js';
21+
import {clamp, validateLiteralType, wrapClamp} from '../utilities.js';
22+
23+
import {$updateProperties, MVEffectBase} from './mixins/effect-base.js';
2324

2425
const TWO_PI = Math.PI * 2;
2526

26-
export type ToneMappingMode = keyof typeof PPToneMappingMode;;
27-
export const TONEMAPPING_MODES = Object.keys(PPToneMappingMode) as ToneMappingMode[];
27+
export type ToneMappingMode = keyof typeof PPToneMappingMode;
28+
;
29+
export const TONEMAPPING_MODES =
30+
Object.keys(PPToneMappingMode) as ToneMappingMode[];
2831

2932
export class MVColorGradeEffect extends MVEffectBase {
3033
static get is() {
3134
return 'color-grade-effect';
3235
}
3336

3437
/**
35-
* `reinhard | reinhard2 | reinhard_adaptive | optimized_cineon | aces_filmic | linear`
38+
* `reinhard | reinhard2 | reinhard_adaptive | optimized_cineon | aces_filmic
39+
* | linear`
3640
* @default 'aces_filmic'
3741
*/
38-
@property({ type: String, attribute: 'tonemapping', reflect: true})
42+
@property({type: String, attribute: 'tonemapping', reflect: true})
3943
tonemapping: ToneMappingMode = 'ACES_FILMIC'
4044

41-
/**
42-
* Value in the range of (-1, 1).
43-
*/
44-
@property({ type: Number, attribute: 'brightness', reflect: true })
45-
brightness = 0;
45+
/**
46+
* Value in the range of (-1, 1).
47+
*/
48+
@property({type: Number, attribute: 'brightness', reflect: true})
49+
brightness = 0;
4650

4751
/**
4852
* Value in the range of (-1, 1).
4953
*/
50-
@property({ type: Number, attribute: 'contrast', reflect: true })
51-
contrast = 0;
54+
@property({type: Number, attribute: 'contrast', reflect: true}) contrast = 0;
5255

5356
/**
5457
* Value in the range of (-1, 1).
5558
*/
56-
@property({ type: Number, attribute: 'saturation', reflect: true })
59+
@property({type: Number, attribute: 'saturation', reflect: true})
5760
saturation = 0;
5861

5962
/**
6063
* Value in the range of (0, 2 * PI).
6164
*
62-
* This property is wrapping, meaning that if you set it above the max it resets to the minimum and vice-versa.
65+
* This property is wrapping, meaning that if you set it above the max it
66+
* resets to the minimum and vice-versa.
6367
*/
64-
@property({ type: Number, attribute: 'hue', reflect: true })
65-
hue = 0;
68+
@property({type: Number, attribute: 'hue', reflect: true}) hue = 0;
6669

6770
constructor() {
6871
super();
@@ -88,23 +91,20 @@ export class MVColorGradeEffect extends MVEffectBase {
8891
this[$updateProperties]();
8992
}
9093

91-
updated(changedProperties: Map<string | number | symbol, any>) {
94+
updated(changedProperties: Map<string|number|symbol, any>) {
9295
super.updated(changedProperties);
93-
if (
94-
changedProperties.has('tonemapping') ||
95-
changedProperties.has('brightness') ||
96-
changedProperties.has('contrast') ||
97-
changedProperties.has('hue') ||
98-
changedProperties.has('saturation') ||
99-
changedProperties.has('blendMode')
100-
) {
96+
if (changedProperties.has('tonemapping') ||
97+
changedProperties.has('brightness') ||
98+
changedProperties.has('contrast') || changedProperties.has('hue') ||
99+
changedProperties.has('saturation') ||
100+
changedProperties.has('blendMode')) {
101101
this[$updateProperties]();
102102
}
103103
}
104104

105105
[$updateProperties]() {
106106
if (this.blendMode === 'SKIP') {
107-
this.effectComposer[$effectComposer][$tonemapping] = ACESFilmicToneMapping;
107+
this.effectComposer[$effectComposer][$tonemapping] = NeutralToneMapping;
108108
} else {
109109
this.effectComposer[$effectComposer][$tonemapping] = NoToneMapping;
110110
}
@@ -119,7 +119,8 @@ export class MVColorGradeEffect extends MVEffectBase {
119119
try {
120120
this.tonemapping = this.tonemapping.toUpperCase() as ToneMappingMode;
121121
validateLiteralType(TONEMAPPING_MODES, this.tonemapping);
122-
(this.effects[0] as ToneMappingEffect).mode = PPToneMappingMode[this.tonemapping];
122+
(this.effects[0] as ToneMappingEffect).mode =
123+
PPToneMappingMode[this.tonemapping];
123124
} finally {
124125
this.effectComposer.queueRender();
125126
}

packages/model-viewer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
"@monogrid/gainmap-js": "^3.1.0"
8888
},
8989
"peerDependencies": {
90-
"three": "^0.170.0"
90+
"three": "^0.172.0"
9191
},
9292
"devDependencies": {
9393
"@rollup/plugin-commonjs": "^28.0.2",

packages/model-viewer/src/features/environment.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515

1616
import {property} from 'lit/decorators.js';
17-
import {ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping, Texture} from 'three';
17+
import {ACESFilmicToneMapping, AgXToneMapping, CineonToneMapping, LinearToneMapping, NeutralToneMapping, NoToneMapping, ReinhardToneMapping, Texture} from 'three';
1818

1919
import ModelViewerElementBase, {$needsRender, $progressTracker, $renderer, $scene, $shouldAttemptPreload} from '../model-viewer-base.js';
2020
import {clamp, Constructor, deserializeUrl} from '../utilities.js';
@@ -24,7 +24,8 @@ const DEFAULT_SHADOW_INTENSITY = 0.0;
2424
const DEFAULT_SHADOW_SOFTNESS = 1.0;
2525
const DEFAULT_EXPOSURE = 1.0;
2626

27-
export type ToneMappingValue = 'auto'|'aces'|'agx'|'commerce'|'neutral';
27+
export type ToneMappingValue = 'auto'|'aces'|'agx'|'commerce'|'neutral'|
28+
'reinhard'|'cineon'|'linear'|'none';
2829

2930
export const $currentEnvironmentMap = Symbol('currentEnvironmentMap');
3031
export const $currentBackground = Symbol('currentBackground');
@@ -90,8 +91,12 @@ export const EnvironmentMixin = <T extends Constructor<ModelViewerElementBase>>(
9091
if (changedProperties.has('toneMapping')) {
9192
this[$scene].toneMapping = this.toneMapping === 'aces' ?
9293
ACESFilmicToneMapping :
93-
this.toneMapping === 'agx' ? AgXToneMapping :
94-
NeutralToneMapping;
94+
this.toneMapping === 'agx' ? AgXToneMapping :
95+
this.toneMapping === 'reinhard' ? ReinhardToneMapping :
96+
this.toneMapping === 'cineon' ? CineonToneMapping :
97+
this.toneMapping === 'linear' ? LinearToneMapping :
98+
this.toneMapping === 'none' ? NoToneMapping :
99+
NeutralToneMapping;
95100
this[$needsRender]();
96101
}
97102

packages/model-viewer/src/three-components/ModelScene.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import {ACESFilmicToneMapping, AnimationAction, AnimationActionLoopStyles, AnimationClip, AnimationMixer, AnimationMixerEventMap, Box3, Camera, Euler, Event as ThreeEvent, LoopOnce, LoopPingPong, LoopRepeat, Material, Matrix3, Mesh, Object3D, PerspectiveCamera, Raycaster, Scene, Sphere, Texture, ToneMapping, Triangle, Vector2, Vector3, WebGLRenderer, XRTargetRaySpace} from 'three';
16+
import {NeutralToneMapping, AnimationAction, AnimationActionLoopStyles, AnimationClip, AnimationMixer, AnimationMixerEventMap, Box3, Camera, Euler, Event as ThreeEvent, LoopOnce, LoopPingPong, LoopRepeat, Material, Matrix3, Mesh, Object3D, PerspectiveCamera, Raycaster, Scene, Sphere, Texture, ToneMapping, Triangle, Vector2, Vector3, WebGLRenderer, XRTargetRaySpace} from 'three';
1717
import {CSS2DRenderer} from 'three/examples/jsm/renderers/CSS2DRenderer.js';
1818
import {reduceVertices} from 'three/examples/jsm/utils/SceneUtils.js';
1919

@@ -104,7 +104,7 @@ export class ModelScene extends Scene {
104104
public bakedShadows = new Set<Mesh>();
105105

106106
public exposure = 1;
107-
public toneMapping: ToneMapping = ACESFilmicToneMapping;
107+
public toneMapping: ToneMapping = NeutralToneMapping;
108108
public canScale = true;
109109

110110
private isDirty = false;

packages/model-viewer/src/three-components/Renderer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16-
import {ACESFilmicToneMapping, Event, EventDispatcher, NeutralToneMapping, Vector2, WebGLRenderer} from 'three';
16+
import {Event, EventDispatcher, NeutralToneMapping, Vector2, WebGLRenderer} from 'three';
1717

1818
import {$updateEnvironment} from '../features/environment.js';
1919
import {ModelViewerGlobalConfig} from '../features/loading.js';
@@ -158,7 +158,7 @@ export class Renderer extends
158158

159159
// ACESFilmicToneMapping appears to be the most "saturated",
160160
// and similar to Filament's gltf-viewer.
161-
this.threeRenderer.toneMapping = ACESFilmicToneMapping;
161+
this.threeRenderer.toneMapping = NeutralToneMapping;
162162
} catch (error) {
163163
console.warn(error);
164164
}

packages/modelviewer.dev/data/docs.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,13 +897,13 @@
897897
{
898898
"name": "tone-mapping",
899899
"htmlName": "toneMapping",
900-
"description": "Selects the function that compresses the HDR rendering to an SDR image on your screen. ACES is a film industry standard that is commonly used, though it has serious color-accuracy problems. AgX is a new and improved tone mapper seeing broad adoption in film and games. Khronos PBR Neutral ('neutral') is a standard function designed specifically for accurate color reproduction in e-commerce. Our current default is neutral, but prior to v4.0 this default was ACES. The deprecated name commerce is an alias for neutral.",
900+
"description": "Selects the function that compresses the HDR rendering to an SDR image on your screen. ACES is a film industry standard that is commonly used, though it has serious color-accuracy problems. AgX is a new and improved tone mapper seeing broad adoption in film and games. Khronos PBR Neutral ('neutral') is a standard function designed specifically for accurate color reproduction in e-commerce. Our current default is neutral, but prior to v4.0 this default was ACES. The deprecated name commerce is an alias for neutral. Other options include NoToneMapping, which disables tone mapping entirely, LinearToneMapping, a simple linear scaling of brightness values, ReinhardToneMapping, a balanced approach for natural-looking HDR images, and CineonToneMapping, which emulates the look of traditional film. Each tone mapper has its use cases, depending on the desired visual outcome and application requirements.",
901901
"links": [
902902
"<a href=\"../examples/lightingandenv/#toneMapping\"><span class='attribute'>tone-mapping</span> example</a>"
903903
],
904904
"default": {
905905
"default": "neutral",
906-
"options": "neutral, aces, agx"
906+
"options": "neutral, aces, agx, reinhard, cineon, linear, none"
907907
}
908908
},
909909
{

packages/modelviewer.dev/examples/color.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ <h3 id="photography">How does rendering compare to photography?</h3>
421421
<option value="neutral">PBR Neutral</option>
422422
<option value="aces">ACES</option>
423423
<option value="agx">AgX</option>
424+
<option value="cineon">Cineon</option>
425+
<option value="reinhard">Reinhard</option>
426+
<option value="linear">Linear</option>
427+
<option value="none">None</option>
424428
</select><br/>
425429
Model:
426430
<select id="model">

packages/modelviewer.dev/examples/lightingandenv/index.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ <h2 class="demo-title">Comparing tone mapping</h2>
244244
<option value="neutral">Neutral</option>
245245
<option value="aces">ACES</option>
246246
<option value="agx">AgX</option>
247+
<option value="cineon">Cineon</option>
248+
<option value="reinhard">Reinhard</option>
249+
<option value="linear">Linear</option>
250+
<option value="none">None</option>
247251
</select>
248252
<p>Model:</p>
249253
<select id="model">

packages/modelviewer.dev/examples/postprocessing/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<script type="importmap">
3434
{
3535
"imports": {
36-
"three": "https://cdn.jsdelivr.net/npm/three@^0.170.0/build/three.module.min.js"
36+
"three": "https://cdn.jsdelivr.net/npm/three@^0.172.0/build/three.module.min.js"
3737
}
3838
}
3939
</script>
@@ -114,7 +114,7 @@ <h2 class="demo-title">Setup Post Processing</h2>
114114
<script type="importmap-noexecute">
115115
{
116116
"imports": {
117-
"three": "https://cdn.jsdelivr.net/npm/three@^0.170.0/build/three.module.min.js"
117+
"three": "https://cdn.jsdelivr.net/npm/three@^0.172.0/build/three.module.min.js"
118118
}
119119
}
120120
</script>

0 commit comments

Comments
 (0)