-
-
Notifications
You must be signed in to change notification settings - Fork 36k
WebGLRenderer: Support "Linear Display P3" working color space and "Display P3" unlit rendering #26644
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mrdoob
merged 21 commits into
mrdoob:dev
from
donmccurdy:feat/webglrenderer-displayp3-v2
Sep 7, 2023
Merged
WebGLRenderer: Support "Linear Display P3" working color space and "Display P3" unlit rendering #26644
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
80689ad
WIP: Display P3 render example
donmccurdy 47e0977
WIP: P3 implementation
donmccurdy caabb88
Clean up
donmccurdy a0c0c43
TransferFunction -> Transfer
donmccurdy d0736da
Clean up
donmccurdy d687708
Clean up
donmccurdy 6339846
Clean up
donmccurdy 8db039b
Move capabilities check out of WebGL.js
donmccurdy b990e5d
Fix regressions
donmccurdy 253e141
Clean up, fix typo
donmccurdy 5091edb
Clean up
donmccurdy 7fcb67a
Listen for display gamut changes.
donmccurdy c9c7a9e
Clean up
donmccurdy 6aaa778
Fix regression in OutputPass.
donmccurdy 499149d
Add 'LinearTosRGB' for backward-compatibility.
donmccurdy 1fcc38b
Add 'LinearToLinear' for backward-compatibility.
donmccurdy 8b2fb84
Clean up
donmccurdy 9b42148
Align labels
donmccurdy 98d5556
Move detection of display-p3 capabilility to WebGL.js
donmccurdy bb5b1f3
Apply suggestions from code review
donmccurdy b313f11
Remove renderer.resetColorManangement()
donmccurdy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgl - test - wide gamut</title> | ||
<meta charset="utf-8"> | ||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | ||
<link type="text/css" rel="stylesheet" href="main.css"> | ||
<style> | ||
.container { | ||
position: absolute; | ||
overflow: hidden; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
.slider { | ||
position: absolute; | ||
cursor: ew-resize; | ||
|
||
width: 40px; | ||
height: 40px; | ||
background-color: #F32196; | ||
opacity: 0.7; | ||
border-radius: 50%; | ||
|
||
top: calc(50% - 20px); | ||
left: calc(50% - 20px); | ||
} | ||
|
||
.label { | ||
position: fixed; | ||
top: calc(50% - 1em); | ||
height: 2em; | ||
line-height: 2em; | ||
background: rgba(0, 0, 0, 0.5); | ||
margin: 0; | ||
padding: 0.2em 0.5em; | ||
border-radius: 4px; | ||
font-size: 14px; | ||
user-select: none; | ||
-webkit-user-select: none; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
|
||
<div id="info"> | ||
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - wide gamut test<br /> | ||
</div> | ||
|
||
<div class="container"> | ||
<div class="slider"></div> | ||
<p class="label" style="left: 1em;">sRGB</p> | ||
<p class="label" style="right: 1em;">Display P3</p> | ||
</div> | ||
|
||
<!-- Import maps polyfill --> | ||
<!-- Remove this when import maps will be widely supported --> | ||
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "../build/three.module.js", | ||
"three/addons/": "./jsm/" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
|
||
import WebGL from 'three/addons/capabilities/WebGL.js'; | ||
|
||
let container, camera, renderer, loader; | ||
let sceneL, sceneR, textureL, textureR; | ||
|
||
let sliderPos = window.innerWidth / 2; | ||
|
||
const isP3Context = WebGL.isColorSpaceAvailable( THREE.DisplayP3ColorSpace ); | ||
|
||
if ( isP3Context ) { | ||
|
||
THREE.ColorManagement.workingColorSpace = THREE.LinearDisplayP3ColorSpace; | ||
|
||
} | ||
|
||
init(); | ||
|
||
function init() { | ||
|
||
container = document.querySelector( '.container' ); | ||
|
||
sceneL = new THREE.Scene(); | ||
sceneR = new THREE.Scene(); | ||
|
||
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.1, 100 ); | ||
camera.position.z = 6; | ||
|
||
loader = new THREE.TextureLoader(); | ||
|
||
initTextures(); | ||
initSlider(); | ||
|
||
renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
renderer.setScissorTest( true ); | ||
renderer.setAnimationLoop( render ); | ||
container.appendChild( renderer.domElement ); | ||
|
||
if ( isP3Context && window.matchMedia( '( color-gamut: p3 )' ).matches ) { | ||
|
||
renderer.outputColorSpace = THREE.DisplayP3ColorSpace; | ||
|
||
} | ||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
window.matchMedia( '( color-gamut: p3 )' ).addEventListener( 'change', onGamutChange ); | ||
|
||
} | ||
|
||
async function initTextures() { | ||
|
||
const path = 'textures/wide_gamut/logo_{colorSpace}.png'; | ||
|
||
textureL = await loader.loadAsync( path.replace( '{colorSpace}', 'srgb' ) ); | ||
textureR = await loader.loadAsync( path.replace( '{colorSpace}', 'p3' ) ); | ||
|
||
textureL.colorSpace = THREE.SRGBColorSpace; | ||
textureR.colorSpace = THREE.DisplayP3ColorSpace; | ||
|
||
sceneL.background = containTexture( window.innerWidth / window.innerHeight, textureL ); | ||
sceneR.background = containTexture( window.innerWidth / window.innerHeight, textureR ); | ||
|
||
} | ||
|
||
function initSlider() { | ||
|
||
const slider = document.querySelector( '.slider' ); | ||
|
||
function onPointerDown() { | ||
|
||
if ( event.isPrimary === false ) return; | ||
|
||
window.addEventListener( 'pointermove', onPointerMove ); | ||
window.addEventListener( 'pointerup', onPointerUp ); | ||
|
||
} | ||
|
||
function onPointerUp() { | ||
|
||
window.removeEventListener( 'pointermove', onPointerMove ); | ||
window.removeEventListener( 'pointerup', onPointerUp ); | ||
|
||
} | ||
|
||
function onPointerMove( e ) { | ||
|
||
if ( event.isPrimary === false ) return; | ||
|
||
sliderPos = Math.max( 0, Math.min( window.innerWidth, e.pageX ) ); | ||
|
||
slider.style.left = sliderPos - ( slider.offsetWidth / 2 ) + 'px'; | ||
|
||
} | ||
|
||
slider.style.touchAction = 'none'; // disable touch scroll | ||
slider.addEventListener( 'pointerdown', onPointerDown ); | ||
|
||
} | ||
|
||
function onWindowResize() { | ||
|
||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
|
||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
|
||
containTexture( window.innerWidth / window.innerHeight, sceneL.background ); | ||
containTexture( window.innerWidth / window.innerHeight, sceneR.background ); | ||
|
||
} | ||
|
||
function onGamutChange( { matches } ) { | ||
|
||
renderer.outputColorSpace = isP3Context && matches ? THREE.DisplayP3ColorSpace : THREE.SRGBColorSpace; | ||
|
||
textureL.needsUpdate = true; | ||
textureR.needsUpdate = true; | ||
|
||
} | ||
|
||
function containTexture ( aspect, target ) { | ||
|
||
// Sets the matrix uv transform so the texture image is contained in a region having the specified aspect ratio, | ||
// and does so without distortion. Akin to CSS object-fit: contain. | ||
// Source: https://github.com/mrdoob/three.js/pull/17199 | ||
|
||
var imageAspect = ( target.image && target.image.width ) ? target.image.width / target.image.height : 1; | ||
|
||
if ( aspect > imageAspect ) { | ||
|
||
target.matrix.setUvTransform( 0, 0, aspect / imageAspect, 1, 0, 0.5, 0.5 ); | ||
|
||
} else { | ||
|
||
target.matrix.setUvTransform( 0, 0, 1, imageAspect / aspect, 0, 0.5, 0.5 ); | ||
|
||
} | ||
|
||
target.matrixAutoUpdate = false; | ||
|
||
return target; | ||
|
||
} | ||
|
||
function render() { | ||
|
||
renderer.setScissor( 0, 0, sliderPos, window.innerHeight ); | ||
renderer.render( sceneL, camera ); | ||
|
||
renderer.setScissor( sliderPos, 0, window.innerWidth, window.innerHeight ); | ||
renderer.render( sceneR, camera ); | ||
|
||
} | ||
|
||
</script> | ||
</body> | ||
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.