forked from mrdoob/three.js
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d1042cb
commit cbff8c0
Showing
16 changed files
with
447 additions
and
29 deletions.
There are no files selected for viewing
This file contains 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.
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 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,240 @@ | ||
<!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; | ||
bottom: 50%; | ||
background: rgba(0, 0, 0, 0.5); | ||
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'; | ||
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | ||
|
||
let container, camera, renderer, loader; | ||
let sceneL, sceneR, textureL, textureR; | ||
|
||
let sliderPos = window.innerWidth / 2; | ||
|
||
const IMAGE_OPTIONS = { | ||
'Yellow flower': 'yellow_flower_{colorSpace}.jpg', | ||
'Webkit logo': 'webkit_logo_{colorSpace}.png', | ||
}; | ||
|
||
const params = { | ||
|
||
image: Object.values( IMAGE_OPTIONS )[ 0 ], | ||
|
||
}; | ||
|
||
if ( WebGL.isColorSpaceAvailable( THREE.DisplayP3ColorSpace ) ) { | ||
|
||
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().setPath( 'textures/wide_gamut/' ); | ||
|
||
const light = new THREE.HemisphereLight( 0xffffff, 0x444444, 3 ); | ||
light.position.set( - 2, 2, 2 ); | ||
sceneL.add( light.clone() ); | ||
sceneR.add( light.clone() ); | ||
|
||
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 ( WebGL.isColorSpaceAvailable( THREE.DisplayP3ColorSpace ) ) { | ||
|
||
renderer.outputColorSpace = THREE.DisplayP3ColorSpace; | ||
|
||
} | ||
|
||
const gui = new GUI(); | ||
|
||
gui.add( params, 'image', IMAGE_OPTIONS ).onChange( initTextures ); | ||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
|
||
} | ||
|
||
async function initTextures() { | ||
|
||
// TODO: With workingColorSpace="p3-linear", outputColorSpace="srgb", images display quite differently. Expected? | ||
// TODO: Where should .unpackColorSpace be set? Per texture or globally on the renderer? | ||
// TODO: What happens given a Linear-sRGB texture when working color space is Linear-P3? Can we support that? | ||
// TODO: How to detect support for drawingBufferColorSpace="display-p3"? | ||
|
||
textureL = await loader.loadAsync( params.image.replace( '{colorSpace}', 'srgb' ) ); | ||
textureR = await loader.loadAsync( params.image.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 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. | ||
|
||
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 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 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.