提交 e09031ca 编写于 作者: W WestLangley

Added transparency to MeshPhysicalMaterial

上级 436b25e2
......@@ -9,7 +9,7 @@
<body>
<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">
......@@ -19,120 +19,195 @@
import { GUI } from './jsm/libs/dat.gui.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
var params = { opacity: 0.25 };
import { HDRCubeTextureLoader } from './jsm/loaders/HDRCubeTextureLoader.js';
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 camera, scene, renderer;
init();
animate();
var hdrCubeRenderTarget;
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() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 0.0, 40, 40 * 3.5 );
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.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = params.exposure;
renderer.gammaOutput = true;
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( {
opacity: params.opacity,
transparent: true
} );
var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
var material2 = new THREE.MeshStandardMaterial( {
opacity: params.opacity,
premultipliedAlpha: true,
transparent: true
} );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
var textureLoader = new THREE.TextureLoader();
textureLoader.load( "textures/hardwood2_diffuse.jpg", function ( map ) {
hdrCubeMap.magFilter = THREE.LinearFilter;
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();
textureLoader.load( "textures/hardwood2_roughness.jpg", function ( map ) {
var material1 = new THREE.MeshPhysicalMaterial().copy( material );
map.anisotropy = 8;
var material1b = new THREE.MeshPhysicalMaterial().copy( material );
material1b.side = THREE.BackSide;
material1.roughnessMap = map;
material1.needsUpdate = true;
material2.roughnessMap = map;
material2.needsUpdate = true;
var material2 = new THREE.MeshPhysicalMaterial().copy( material );
material2.premultipliedAlpha = true;
} );
var material2b = new THREE.MeshPhysicalMaterial().copy( material );
material2b.premultipliedAlpha = true;
material2b.side = THREE.BackSide;
var mesh = new THREE.Mesh( geometry, material1 );
mesh.position.x = - 25.0;
scene.add( mesh );
mesh1 = new THREE.Mesh( geometry, material1 );
mesh1.position.x = - 30.0;
scene.add( mesh1 );
var mesh = new THREE.Mesh( geometry, material2 );
mesh.position.x = 25.0;
scene.add( mesh );
var mesh = new THREE.Mesh( geometry, material1b );
mesh.renderOrder = - 1;
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 material = new THREE.MeshStandardMaterial( { color: 0x333333 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 50;
mesh.rotation.x = - Math.PI * 0.5;
scene.add( mesh );
var mesh = new THREE.Mesh( geometry, material2b );
mesh.renderOrder = - 1;
mesh2.add( mesh );
// Lights
//
var spotLight = new THREE.SpotLight( 0xff8888 );
spotLight.position.set( 100, 200, 100 );
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.9;
scene.add( spotLight );
spotLight1 = new THREE.SpotLight( 0xffffff, params.lightIntensity );
spotLight1.position.set( 100, 200, 100 );
spotLight1.angle = Math.PI / 6;
scene.add( spotLight1 );
var spotLight = new THREE.SpotLight( 0x8888ff );
spotLight.position.set( - 100, - 200, - 100 );
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.9;
scene.add( spotLight );
spotLight2 = new THREE.SpotLight( 0xffffff, params.lightIntensity );
spotLight2.position.set( - 100, - 200, - 100 );
spotLight2.angle = Math.PI / 6;
scene.add( spotLight2 );
//
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();
container.appendChild( stats.dom );
var controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 10;
controls.maxDistance = 150;
window.addEventListener( 'resize', onWindowResize, false );
//
var gui = new GUI();
gui.add( params, 'opacity', 0, 1 ).onChange( function () {
material1.opacity = params.opacity;
material2.opacity = params.opacity;
gui.addColor( params, 'color' )
.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();
}
......@@ -151,32 +226,32 @@
//
function animate() {
function generateTexture() {
requestAnimationFrame( animate );
var canvas = document.createElement( 'canvas' );
canvas.width = 2;
canvas.height = 2;
stats.begin();
render();
stats.end();
var context = canvas.getContext( '2d' );
context.fillStyle = 'white';
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;
object.rotation.y = - performance.now() * 0.0002;
requestAnimationFrame( animate );
}
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 );
stats.end();
}
......
......@@ -23,6 +23,8 @@ function MeshPhysicalMaterial( parameters ) {
this.clearCoat = 0.0;
this.clearCoatRoughness = 0.0;
this.transparency = 0.0;
this.setValues( parameters );
}
......@@ -43,9 +45,10 @@ MeshPhysicalMaterial.prototype.copy = function ( source ) {
this.clearCoat = source.clearCoat;
this.clearCoatRoughness = source.clearCoatRoughness;
this.transparency = source.transparency;
return this;
};
export { MeshPhysicalMaterial };
......@@ -2275,6 +2275,8 @@ function WebGLRenderer( parameters ) {
uniforms.clearCoat.value = material.clearCoat;
uniforms.clearCoatRoughness.value = material.clearCoatRoughness;
uniforms.transparency.value = material.transparency;
}
function refreshUniformsMatcap( uniforms, material ) {
......
......@@ -273,7 +273,8 @@ ShaderLib.physical = {
ShaderLib.standard.uniforms,
{
clearCoat: { value: 0 },
clearCoatRoughness: { value: 0 }
clearCoatRoughness: { value: 0 },
transparency: { value: 0 }
}
] ),
......
......@@ -10,6 +10,7 @@ uniform float opacity;
#ifndef STANDARD
uniform float clearCoat;
uniform float clearCoatRoughness;
uniform float transparency;
#endif
varying vec3 vViewPosition;
......@@ -83,6 +84,9 @@ void main() {
vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;
// this is a stub for the transparency model
diffuseColor.a *= saturate( 1. - transparency + linearToRelativeLuminance( reflectedLight.directSpecular + reflectedLight.indirectSpecular ) );
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
#include <tonemapping_fragment>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册