未验证 提交 d39dabbd 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #17114 from WestLangley/dev_pbr_transparency

MeshPhysicalMaterial: added transparency
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<body> <body>
<div id="container"></div> <div id="container"></div>
<div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">threejs</a> - Transparency with Premultiplied Alpha (right) and without (left)<br /> using RGBA8 Buffers by <a href="http://clara.io/" target="_blank" rel="noopener">Ben Houston</a>.</div> <div id="info"><a href="http://threejs.org" target="_blank" rel="noopener">threejs</a> - Transparency with Premultiplied Alpha (right) and without (left)</div>
<script type="module"> <script type="module">
...@@ -19,120 +19,195 @@ ...@@ -19,120 +19,195 @@
import { GUI } from './jsm/libs/dat.gui.module.js'; import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
var params = { opacity: 0.25 }; import { PMREMGenerator } from './jsm/pmrem/PMREMGenerator.js';
import { PMREMCubeUVPacker } from './jsm/pmrem/PMREMCubeUVPacker.js';
var params = {
color: 0xffffff,
transparency: 0.90,
envMapIntensity: 1,
lightIntensity: 1,
exposure: 1
};
var container, stats; var container, stats;
var camera, scene, renderer; var camera, scene, renderer;
init(); var hdrCubeRenderTarget;
animate(); var spotLight1, spotLight2;
var mesh1, mesh2;
var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
var hdrCubeMap = new HDRCubeTextureLoader()
.setPath( './textures/cube/pisaHDR/' )
.setDataType( THREE.UnsignedByteType )
.load( hdrUrls, function () {
init();
animate();
} );
function init() { function init() {
container = document.createElement( 'div' ); container = document.createElement( 'div' );
document.body.appendChild( container ); document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 ); renderer = new THREE.WebGLRenderer( { antialias: true } );
camera.position.set( 0.0, 40, 40 * 3.5 ); renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = params.exposure;
renderer.gammaOutput = true;
scene = new THREE.Scene(); scene = new THREE.Scene();
scene.background = hdrCubeMap;
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 0, 0, 120 );
// //
var geometry = new THREE.SphereBufferGeometry( 18, 30, 30 ); var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var material1 = new THREE.MeshStandardMaterial( { var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
opacity: params.opacity, pmremCubeUVPacker.update( renderer );
transparent: true
} );
var material2 = new THREE.MeshStandardMaterial( { hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
opacity: params.opacity,
premultipliedAlpha: true,
transparent: true
} );
var textureLoader = new THREE.TextureLoader(); hdrCubeMap.magFilter = THREE.LinearFilter;
textureLoader.load( "textures/hardwood2_diffuse.jpg", function ( map ) { hdrCubeMap.needsUpdate = true;
map.anisotropy = 8; pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
material1.map = map; //
material1.needsUpdate = true;
material2.map = map;
material2.needsUpdate = true;
var geometry = new THREE.SphereBufferGeometry( 20, 64, 32 );
var texture = new THREE.CanvasTexture( generateTexture() );
texture.magFilter = THREE.NearestFilter;
texture.wrapT = THREE.RepeatWrapping;
texture.wrapS = THREE.RepeatWrapping;
texture.repeat.set( 1, 3.5 );
var material = new THREE.MeshPhysicalMaterial( {
color: params.color,
metalness: 0,
roughness: 0,
alphaMap: texture,
alphaTest: 0.5,
envMap: hdrCubeRenderTarget.texture,
envMapIntensity: params.envMapIntensity,
depthTest: false,
transparency: params.transparency,
transparent: true
} ); } );
var textureLoader = new THREE.TextureLoader(); var material1 = new THREE.MeshPhysicalMaterial().copy( material );
textureLoader.load( "textures/hardwood2_roughness.jpg", function ( map ) {
map.anisotropy = 8; var material1b = new THREE.MeshPhysicalMaterial().copy( material );
material1b.side = THREE.BackSide;
material1.roughnessMap = map; var material2 = new THREE.MeshPhysicalMaterial().copy( material );
material1.needsUpdate = true; material2.premultipliedAlpha = true;
material2.roughnessMap = map;
material2.needsUpdate = true;
} ); var material2b = new THREE.MeshPhysicalMaterial().copy( material );
material2b.premultipliedAlpha = true;
material2b.side = THREE.BackSide;
var mesh = new THREE.Mesh( geometry, material1 ); mesh1 = new THREE.Mesh( geometry, material1 );
mesh.position.x = - 25.0; mesh1.position.x = - 30.0;
scene.add( mesh ); scene.add( mesh1 );
var mesh = new THREE.Mesh( geometry, material2 ); var mesh = new THREE.Mesh( geometry, material1b );
mesh.position.x = 25.0; mesh.renderOrder = - 1;
scene.add( mesh ); mesh1.add( mesh );
// mesh2 = new THREE.Mesh( geometry, material2 );
mesh2.position.x = 30.0;
scene.add( mesh2 );
var geometry = new THREE.PlaneBufferGeometry( 800, 800 ); var mesh = new THREE.Mesh( geometry, material2b );
var material = new THREE.MeshStandardMaterial( { color: 0x333333 } ); mesh.renderOrder = - 1;
var mesh = new THREE.Mesh( geometry, material ); mesh2.add( mesh );
mesh.position.y = - 50;
mesh.rotation.x = - Math.PI * 0.5;
scene.add( mesh );
// Lights //
var spotLight = new THREE.SpotLight( 0xff8888 ); spotLight1 = new THREE.SpotLight( 0xffffff, params.lightIntensity );
spotLight.position.set( 100, 200, 100 ); spotLight1.position.set( 100, 200, 100 );
spotLight.angle = Math.PI / 6; spotLight1.angle = Math.PI / 6;
spotLight.penumbra = 0.9; scene.add( spotLight1 );
scene.add( spotLight );
var spotLight = new THREE.SpotLight( 0x8888ff ); spotLight2 = new THREE.SpotLight( 0xffffff, params.lightIntensity );
spotLight.position.set( - 100, - 200, - 100 ); spotLight2.position.set( - 100, - 200, - 100 );
spotLight.angle = Math.PI / 6; spotLight2.angle = Math.PI / 6;
spotLight.penumbra = 0.9; scene.add( spotLight2 );
scene.add( spotLight );
// //
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
container.appendChild( renderer.domElement );
renderer.gammaInput = true;
renderer.gammaOutput = true;
stats = new Stats(); stats = new Stats();
container.appendChild( stats.dom ); container.appendChild( stats.dom );
var controls = new OrbitControls( camera, renderer.domElement ); var controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 10;
controls.maxDistance = 150;
window.addEventListener( 'resize', onWindowResize, false ); window.addEventListener( 'resize', onWindowResize, false );
//
var gui = new GUI(); var gui = new GUI();
gui.add( params, 'opacity', 0, 1 ).onChange( function () {
material1.opacity = params.opacity; gui.addColor( params, 'color' )
material2.opacity = params.opacity; .onChange( function () {
material1.color.set( params.color );
material2.color.set( params.color );
material1b.color.set( params.color );
material2b.color.set( params.color );
} );
gui.add( params, 'transparency', 0, 1 )
.onChange( function () {
material1.transparency = material2.transparency = params.transparency;
material1b.transparency = material2b.transparency = params.transparency;
} );
gui.add( params, 'envMapIntensity', 0, 1 )
.name( 'envMap intensity' )
.onChange( function () {
material1.envMapIntensity = material2.envMapIntensity = params.envMapIntensity;
material1b.envMapIntensity = material2b.envMapIntensity = params.envMapIntensity;
} );
gui.add( params, 'lightIntensity', 0, 1 )
.name( 'light intensity' )
.onChange( function () {
spotLight1.intensity = spotLight2.intensity = params.lightIntensity;
} );
gui.add( params, 'exposure', 0, 1 )
.onChange( function () {
renderer.toneMappingExposure = params.exposure;
} );
} );
gui.open(); gui.open();
} }
...@@ -151,32 +226,32 @@ ...@@ -151,32 +226,32 @@
// //
function animate() { function generateTexture() {
requestAnimationFrame( animate ); var canvas = document.createElement( 'canvas' );
canvas.width = 2;
canvas.height = 2;
stats.begin(); var context = canvas.getContext( '2d' );
render(); context.fillStyle = 'white';
stats.end(); context.fillRect( 0, 1, 2, 1 );
} return canvas;
function render() { }
for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
var object = scene.children[ i ];
if ( object.geometry instanceof THREE.SphereBufferGeometry ) { function animate() {
object.rotation.x = performance.now() * 0.0002; requestAnimationFrame( animate );
object.rotation.y = - performance.now() * 0.0002;
} var t = performance.now();
} mesh1.rotation.x = mesh2.rotation.x = t * 0.0002;
mesh1.rotation.z = mesh2.rotation.z = - t * 0.0002;
stats.begin();
renderer.render( scene, camera ); renderer.render( scene, camera );
stats.end();
} }
......
...@@ -40,6 +40,8 @@ function MeshPhysicalMaterial( parameters ) { ...@@ -40,6 +40,8 @@ function MeshPhysicalMaterial( parameters ) {
this.clearcoatNormalScale = new Vector2( 1, 1 ); this.clearcoatNormalScale = new Vector2( 1, 1 );
this.clearcoatNormalMap = null; this.clearcoatNormalMap = null;
this.transparency = 0.0;
this.setValues( parameters ); this.setValues( parameters );
} }
...@@ -71,9 +73,10 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) { ...@@ -71,9 +73,10 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) {
this.clearcoatNormalMap = source.clearcoatNormalMap; this.clearcoatNormalMap = source.clearcoatNormalMap;
this.clearcoatNormalScale.copy( source.clearcoatNormalScale ); this.clearcoatNormalScale.copy( source.clearcoatNormalScale );
this.transparency = source.transparency;
return this; return this;
}; };
export { MeshPhysicalMaterial }; export { MeshPhysicalMaterial };
...@@ -2286,6 +2286,8 @@ function WebGLRenderer( parameters ) { ...@@ -2286,6 +2286,8 @@ function WebGLRenderer( parameters ) {
} }
uniforms.transparency.value = material.transparency;
} }
function refreshUniformsMatcap( uniforms, material ) { function refreshUniformsMatcap( uniforms, material ) {
......
...@@ -273,6 +273,7 @@ ShaderLib.physical = { ...@@ -273,6 +273,7 @@ ShaderLib.physical = {
uniforms: mergeUniforms( [ uniforms: mergeUniforms( [
ShaderLib.standard.uniforms, ShaderLib.standard.uniforms,
{ {
transparency: { value: 0 },
clearcoat: { value: 0 }, clearcoat: { value: 0 },
clearcoatRoughness: { value: 0 }, clearcoatRoughness: { value: 0 },
sheen: { value: new Color( 0x000000 ) }, sheen: { value: new Color( 0x000000 ) },
......
...@@ -4,6 +4,7 @@ export default /* glsl */` ...@@ -4,6 +4,7 @@ export default /* glsl */`
#ifdef PHYSICAL #ifdef PHYSICAL
#define REFLECTIVITY #define REFLECTIVITY
#define CLEARCOAT #define CLEARCOAT
#define TRANSPARENCY
#endif #endif
uniform vec3 diffuse; uniform vec3 diffuse;
...@@ -12,13 +13,19 @@ uniform float roughness; ...@@ -12,13 +13,19 @@ uniform float roughness;
uniform float metalness; uniform float metalness;
uniform float opacity; uniform float opacity;
#ifdef TRANSPARENCY
uniform float transparency;
#endif
#ifdef REFLECTIVITY #ifdef REFLECTIVITY
uniform float reflectivity; uniform float reflectivity;
#endif #endif
#ifdef CLEARCOAT #ifdef CLEARCOAT
uniform float clearcoat; uniform float clearcoat;
uniform float clearcoatRoughness; uniform float clearcoatRoughness;
#endif #endif
#ifdef USE_SHEEN #ifdef USE_SHEEN
uniform vec3 sheen; uniform vec3 sheen;
#endif #endif
...@@ -97,6 +104,11 @@ void main() { ...@@ -97,6 +104,11 @@ void main() {
vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
// this is a stub for the transparency model
#ifdef TRANSPARENCY
diffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );
#endif
gl_FragColor = vec4( outgoingLight, diffuseColor.a ); gl_FragColor = vec4( outgoingLight, diffuseColor.a );
#include <tonemapping_fragment> #include <tonemapping_fragment>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册