-
-
Notifications
You must be signed in to change notification settings - Fork 36.2k
Improved transparent rendering #25819
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
Merged
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
bf867ec
improved transparent rendering
elalish 7b20b52
updated for premultipliedAlpha: true
elalish 8ab28c3
revert premultiply
elalish c9ef020
transmission proof-of-concept
WestLangley c0de0c1
update builds
WestLangley 247b725
add dragon model
WestLangley ee34d06
CI fixes
WestLangley 8f6f5e5
Merge branch 'dev' of https://github.com/mrdoob/three.js into dev-tra…
WestLangley 4f7b4f7
Allow CSS background to show through model
WestLangley 3088693
Update builds
WestLangley e9e1ddc
Merge branch 'dev-transmission' of github.com:WestLangley/three.js in…
elalish c41abc6
merging two approaches
elalish 384b2ae
update screenshot
elalish 4b361b5
addressing feedback
elalish a196330
updating builds
elalish c06aff9
added comment
elalish e7added
added comment
elalish f518b10
merging dev
elalish 938bf46
update screenshot
elalish 91843df
revert files
elalish 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
Binary file not shown.
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,323 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <title>threejs webgl - materials - transmission 2</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> | ||
| body { | ||
| background-color: #ffffff; | ||
| } | ||
|
|
||
| #table { | ||
| margin-top: 100px; | ||
| border-collapse: collapse; | ||
| width: 100%; | ||
| } | ||
| #table td { | ||
| margin: 0; | ||
| padding: 0; | ||
| font-size: 16px; | ||
| text-align: center; | ||
| vertical-align: center; | ||
| } | ||
| #table tr { | ||
| height: 250px; | ||
| } | ||
|
|
||
| #block-ff0000 { background-color: #ff0000; color: white; } | ||
| #block-00ff00 { background-color: #00ff00; color: black; } | ||
| #block-0000ff { background-color: #0000ff; color: white; } | ||
| #block-000000 { background-color: #000000; color: black; } | ||
| </style> | ||
|
|
||
| </head> | ||
| <body> | ||
|
|
||
| <table id="table"> | ||
| <tbody> | ||
| <tr> | ||
| <td id="block-ff0000">ff0000</td> | ||
| <td id="block-00ff00">00ff00</td> | ||
| <td id="block-0000ff">0000ff</td> | ||
| <td id="block-000000">000000</td> | ||
| </tr> | ||
| </tbody> | ||
| </table> | ||
|
|
||
| <div id="container"></div> | ||
| <div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">threejs</a> - Transmission 2</div> | ||
|
|
||
| <!-- Import maps polyfill --> | ||
| <!-- Remove this when import maps will be widely supported --> | ||
| <script async src="https://unpkg.com/es-module-shims@1.6.3/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 { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | ||
| import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
| import { RGBELoader } from 'three/addons/loaders/RGBELoader.js'; | ||
| import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; | ||
|
|
||
| const params = { | ||
| color: 0xffffff, | ||
| transmission: 1, | ||
| opacity: 1, | ||
| metalness: 0, | ||
| roughness: 0, | ||
| ior: 1.5, | ||
| thickness: 0.01, | ||
| attenuationColor: 0xffffff, | ||
| attenuationDistance: 1, | ||
| specularIntensity: 1, | ||
| specularColor: 0xffffff, | ||
| envMapIntensity: 1, | ||
| lightIntensity: 1, | ||
| exposure: 1 | ||
| }; | ||
|
|
||
| let camera, scene, renderer; | ||
|
|
||
| let mesh, material; | ||
|
|
||
| const hdrEquirect = new RGBELoader() | ||
| .setPath( 'textures/equirectangular/' ) | ||
| .load( 'royal_esplanade_1k.hdr', function () { | ||
|
|
||
| hdrEquirect.mapping = THREE.EquirectangularReflectionMapping; | ||
|
|
||
| new GLTFLoader() | ||
| .setPath( 'models/gltf/' ) | ||
| .load( 'DragonAttenuation.glb', function ( gltf ) { | ||
|
|
||
| gltf.scene.traverse( function ( child ) { | ||
|
|
||
| if ( child.isMesh && child.material.isMeshPhysicalMaterial ) { | ||
|
|
||
| mesh = child; | ||
| material = mesh.material; | ||
|
|
||
| let color = new THREE.Color(); | ||
|
|
||
| params.color = color.copy( mesh.material.color ).getHex(); | ||
| params.roughness = mesh.material.roughness; | ||
| params.metalness = mesh.material.metalness; | ||
|
|
||
| params.ior = mesh.material.ior; | ||
| params.specularIntensity = mesh.material.specularIntensity; | ||
| params.emissiveIntensity = mesh.material.emissiveIntensity; | ||
|
|
||
| params.transmission = mesh.material.transmission; | ||
| params.thickness = mesh.material.thickness; | ||
| params.attenuationColor = color.copy( mesh.material.attenuationColor ).getHex(); | ||
| params.attenuationDistance = mesh.material.attenuationDistance; | ||
|
|
||
| } | ||
|
|
||
| } ); | ||
|
|
||
| init(); | ||
|
|
||
| scene.add( gltf.scene ); | ||
|
|
||
| scene.environment = hdrEquirect; | ||
| //scene.background = hdrEquirect; | ||
|
|
||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| } ); | ||
|
|
||
| function init() { | ||
|
|
||
| renderer = new THREE.WebGLRenderer( { antialias: true } ); | ||
| renderer.setPixelRatio( window.devicePixelRatio ); | ||
|
|
||
| // transparent background | ||
| renderer.setClearColor( 0x000000, 0 ); | ||
|
|
||
| renderer.setSize( window.innerWidth, window.innerHeight ); | ||
| renderer.shadowMap.enabled = true; | ||
| document.body.appendChild( renderer.domElement ); | ||
|
|
||
| renderer.toneMapping = THREE.ACESFilmicToneMapping; | ||
| renderer.toneMappingExposure = params.exposure; | ||
|
|
||
| // accommodate CSS table | ||
| renderer.domElement.style.position = 'absolute'; | ||
| renderer.domElement.style.top = 0; | ||
|
|
||
| scene = new THREE.Scene(); | ||
|
|
||
| const light = new THREE.DirectionalLight( 0xffffff, 1 ); | ||
| light.position.set( 0, 1, 1 ); | ||
| //scene.add( light ); | ||
|
|
||
| camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 ); | ||
| camera.position.set( -10, 2, 0 ); | ||
|
|
||
| const controls = new OrbitControls( camera, renderer.domElement ); | ||
| controls.addEventListener( 'change', render ); // use if there is no animation loop | ||
| controls.minDistance = 5; | ||
| controls.maxDistance = 20; | ||
|
|
||
| window.addEventListener( 'resize', onWindowResize ); | ||
|
|
||
| // | ||
|
|
||
| const gui = new GUI(); | ||
|
|
||
| gui.addColor( params, 'color' ) | ||
| .onChange( function () { | ||
|
|
||
| material.color.set( params.color ); | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'transmission', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.transmission = params.transmission; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'opacity', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.opacity = params.opacity; | ||
| const transparent = params.opacity < 1; | ||
| if(transparent !== material.transparent) { | ||
| material.transparent = transparent; | ||
| material.needsUpdate = true; | ||
| } | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'metalness', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.metalness = params.metalness; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'roughness', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.roughness = params.roughness; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'ior', 1, 2, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.ior = params.ior; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'thickness', 0, 5, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.thickness = params.thickness; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.addColor( params, 'attenuationColor' ) | ||
| .name( 'attenuation color' ) | ||
| .onChange( function () { | ||
|
|
||
| material.attenuationColor.set( params.attenuationColor ); | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'attenuationDistance', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.attenuationDistance = params.attenuationDistance; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'specularIntensity', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| material.specularIntensity = params.specularIntensity; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.addColor( params, 'specularColor' ) | ||
| .onChange( function () { | ||
|
|
||
| material.specularColor.set( params.specularColor ); | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'envMapIntensity', 0, 1, 0.01 ) | ||
| .name( 'envMap intensity' ) | ||
| .onChange( function () { | ||
|
|
||
| material.envMapIntensity = params.envMapIntensity; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.add( params, 'exposure', 0, 1, 0.01 ) | ||
| .onChange( function () { | ||
|
|
||
| renderer.toneMappingExposure = params.exposure; | ||
| render(); | ||
|
|
||
| } ); | ||
|
|
||
| gui.open(); | ||
|
|
||
| } | ||
|
|
||
| function onWindowResize() { | ||
|
|
||
| const width = window.innerWidth; | ||
| const height = window.innerHeight; | ||
|
|
||
| camera.aspect = width / height; | ||
| camera.updateProjectionMatrix(); | ||
|
|
||
| renderer.setSize( width, height ); | ||
|
|
||
| render(); | ||
|
|
||
| } | ||
|
|
||
| // | ||
|
|
||
| function render() { | ||
|
|
||
| renderer.render( scene, 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
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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a change from my PR. Are you aware that the render target will have premultiplied values?
So the two values of interest in this PR are
0xffffff * 0.5 = 0x7f7f7fand alpha =0.5.In my PR, the values are
0x7f7f7f * 0.8 = 0x666666and alpha =0.8.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, we talked offline. I think we're at consensus now. Correct me if I'm wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a subjective decision, and can be changed later.