Skip to content
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

Added transparency to StandardNodeMaterial #16996

Closed
wants to merge 10 commits into from
1 change: 1 addition & 0 deletions examples/jsm/nodes/materials/StandardNodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ StandardNodeMaterial.prototype.constructor = StandardNodeMaterial;
NodeUtils.addShortcuts( StandardNodeMaterial.prototype, 'fragment', [
'color',
'alpha',
'transparency',
'roughness',
'metalness',
'reflectivity',
Expand Down
35 changes: 23 additions & 12 deletions examples/jsm/nodes/materials/nodes/StandardNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ StandardNode.prototype.build = function ( builder ) {

if ( this.alpha ) this.alpha.analyze( builder );

if ( this.transparency ) this.transparency.analyze( builder );

if ( this.normal ) this.normal.analyze( builder );

if ( this.clearCoat ) this.clearCoat.analyze( builder );
Expand All @@ -164,6 +166,7 @@ StandardNode.prototype.build = function ( builder ) {
var metalness = this.metalness.flow( builder, 'f' );

var alpha = this.alpha ? this.alpha.flow( builder, 'f' ) : undefined;
var transparency = this.transparency ? this.transparency.flow( builder, 'f' ) : undefined;

var normal = this.normal ? this.normal.flow( builder, 'v3' ) : undefined;

Expand All @@ -183,7 +186,7 @@ StandardNode.prototype.build = function ( builder ) {

var clearCoatEnv = useClearCoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearCoat', context: contextEnvironment, slot: 'environment' } ) : undefined;

builder.requires.transparent = alpha !== undefined;
builder.requires.transparent = alpha !== undefined || transparency !== undefined;

builder.addParsCode( [

Expand All @@ -201,6 +204,7 @@ StandardNode.prototype.build = function ( builder ) {
"#include <lights_pars_begin>",
"#include <lights_physical_pars_fragment>",
"#include <shadowmap_pars_fragment>",
"#include <transparency_pars_fragment>",
"#include <logdepthbuf_pars_fragment>"
].join( "\n" ) );

Expand Down Expand Up @@ -396,17 +400,20 @@ StandardNode.prototype.build = function ( builder ) {
"#include <lights_fragment_end>"
);

output.push( "vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;" );

if ( alpha ) {

output.push( "gl_FragColor = vec4( outgoingLight, " + alpha.result + " );" );

} else {

output.push( "gl_FragColor = vec4( outgoingLight, 1.0 );" );

}
output.push(
'float alpha = ' + ( alpha ? alpha.result : '1.') + ';',
'float transparency = ' + ( transparency ? transparency.result : '0.') + ';',

'gl_FragColor = combineLight(',
' reflectedLight.directDiffuse + reflectedLight.indirectDiffuse,',
' reflectedLight.directSpecular + reflectedLight.indirectSpecular,',
' geometry,',
' material,',
' transparency',
');',

'gl_FragColor.a *= alpha;'
);

output.push(
"#include <tonemapping_fragment>",
Expand Down Expand Up @@ -442,6 +449,8 @@ StandardNode.prototype.copy = function ( source ) {

if ( source.alpha ) this.alpha = source.alpha;

if ( source.transparency ) this.transparency = source.transparency;

if ( source.normal ) this.normal = source.normal;

if ( source.clearCoat ) this.clearCoat = source.clearCoat;
Expand Down Expand Up @@ -485,6 +494,8 @@ StandardNode.prototype.toJSON = function ( meta ) {

if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;

if ( this.transparency ) data.transparency = this.transparency.toJSON( meta ).uuid;

if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;

if ( this.clearCoat ) data.clearCoat = this.clearCoat.toJSON( meta ).uuid;
Expand Down
216 changes: 184 additions & 32 deletions examples/webgl_materials_transparency.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,41 @@
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';

import * as Nodes from './jsm/nodes/Nodes.js';

var params = {
opacity: 1,
transparency: 0,
roughness: 0,
metalness: 0,
colorSaturation: 0,
colorBrightness: 1,
showbox: false,
spotLight: 5,
};

var container, stats;
var camera, scene, renderer;
var material, material1, material2, material1n, material2n;
var hdrCubeRenderTarget;
var hdrCubeMap;
var spotLight;

init();
animate();
var alpha, transparency, metalness, roughness, color;

function init() {
var fontLoader = new THREE.FontLoader();
fontLoader.load( 'fonts/gentilis_regular.typeface.json', function ( font ) {

init( font );
animate();

} );

function init( font ) {

container = document.createElement( 'div' );
document.body.appendChild( container );
Expand All @@ -40,76 +66,114 @@

//

var geometry = new THREE.SphereBufferGeometry( 18, 30, 30 );
var geometry = new THREE.SphereBufferGeometry( 18, 100, 100 );

//

material1 = new THREE.MeshPhysicalMaterial( {

var material1 = new THREE.MeshStandardMaterial( {
opacity: params.opacity,
transparent: true

} );

var material2 = new THREE.MeshStandardMaterial( {
opacity: params.opacity,
premultipliedAlpha: true,
material2 = new THREE.MeshPhysicalMaterial( {

transparent: true

} );

var textureLoader = new THREE.TextureLoader();
textureLoader.load( "textures/hardwood2_diffuse.jpg", function ( map ) {
material2.premultipliedAlpha = true;

map.anisotropy = 8;
//

material1.map = map;
material1.needsUpdate = true;
material2.map = map;
material2.needsUpdate = true;
material1n = new Nodes.StandardNodeMaterial();
material2n = new Nodes.StandardNodeMaterial();
material2n.premultipliedAlpha = true;

} );
alpha = new Nodes.FloatNode( params.opacity );
transparency = new Nodes.FloatNode( params.transparency );
metalness = new Nodes.FloatNode( params.metalness );
roughness = new Nodes.FloatNode( params.roughness );
color = new Nodes.ColorNode( 0xffffff );

material1n.alpha = material2n.alpha = alpha;
material1n.transparency = material2n.transparency = transparency;
material1n.metalness = material2n.metalness = metalness;
material1n.roughness = material2n.roughness = roughness;
material1n.color = material2n.color = color;

var textureLoader = new THREE.TextureLoader();
textureLoader.load( "textures/hardwood2_roughness.jpg", function ( map ) {

map.anisotropy = 8;

material1n.roughness = material2n.roughness = new Nodes.OperatorNode(
roughness,
new Nodes.SwitchNode(
new Nodes.TextureNode( map ),
'g'
),
Nodes.OperatorNode.MUL
);

material1.roughnessMap = map;
material1.needsUpdate = true;
material2.roughnessMap = map;

material1.needsUpdate = true;
material2.needsUpdate = true;
material1n.needsUpdate = true;
material2n.needsUpdate = true;

} );

var mesh = new THREE.Mesh( geometry, material1 );
var mesh;

mesh = new THREE.Mesh( geometry, material1 );
mesh.position.x = - 25.0;
mesh.position.y = 25.0;
scene.add( mesh );

mesh = new THREE.Mesh( geometry, material2 );
mesh.position.x = 25.0;
mesh.position.y = 25.0;
scene.add( mesh );

mesh = new THREE.Mesh( geometry, material1n );
mesh.position.x = - 25.0;
mesh.position.y = - 25.0;
scene.add( mesh );

var mesh = new THREE.Mesh( geometry, material2 );
mesh = new THREE.Mesh( geometry, material2n );
mesh.position.x = 25.0;
mesh.position.y = - 25.0;
scene.add( mesh );

//

var geometry = new THREE.PlaneBufferGeometry( 800, 800 );
var material = new THREE.MeshStandardMaterial( { color: 0x333333 } );
var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
material = new THREE.MeshStandardMaterial( { color: 0x333333, side: THREE.BackSide } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 50;
mesh.rotation.x = - Math.PI * 0.5;
scene.add( mesh );
mesh.visible = false;

// Lights

var spotLight = new THREE.SpotLight( 0xff8888 );
spotLight = new THREE.SpotLight( 0xff0000, .1 );
spotLight.position.set( 100, 200, 100 );
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.9;
scene.add( spotLight );
// scene.add( spotLight );

var spotLight = new THREE.SpotLight( 0x8888ff );
spotLight = new THREE.SpotLight( 0xffffff, params.spotlight );
spotLight.position.set( - 100, - 200, - 100 );
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.9;
scene.add( spotLight );

//

//

renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
Expand All @@ -119,22 +183,102 @@
renderer.gammaInput = true;
renderer.gammaOutput = true;

var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
hdrCubeMap = new HDRCubeTextureLoader()
.setPath( './textures/cube/pisaHDR/' )
.setType( THREE.UnsignedByteType )
.load( hdrUrls, function () {

var pmremGenerator = new PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );

var pmremCubeUVPacker = new PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );

hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;

hdrCubeMap.magFilter = THREE.LinearFilter;
hdrCubeMap.needsUpdate = true;

pmremGenerator.dispose();
pmremCubeUVPacker.dispose();

} );

scene.background = hdrCubeMap;

stats = new Stats();
container.appendChild( stats.dom );

var controls = new OrbitControls( camera, renderer.domElement );

window.addEventListener( 'resize', onWindowResize, false );

function updateParams() {

spotLight.intensity = params.spotLight;
mesh.visible = params.showbox;

alpha.value = params.opacity;
transparency.value = params.transparency;
metalness.value = params.metalness;
roughness.value = params.roughness;

color.value.setHSL(0, params.colorSaturation, params.colorBrightness * .5);

material1.opacity = material2.opacity = params.opacity;
material1.transparency = material2.transparency = params.transparency;
material1.metalness = material2.metalness = params.metalness;
material1.roughness = material2.roughness = params.roughness;
material1.roughness = material2.roughness = params.roughness;
material1.color = material2.color = color.value;

}

updateParams();

var gui = new GUI();
gui.add( params, 'opacity', 0, 1 ).onChange( function () {

material1.opacity = params.opacity;
material2.opacity = params.opacity;
gui.add( params, 'opacity', 0, 1 ).onChange( updateParams );
gui.add( params, 'transparency', 0, 1 ).onChange( updateParams );
gui.add( params, 'roughness', 0, 1 ).onChange( updateParams );
gui.add( params, 'metalness', 0, 1 ).onChange( updateParams );
gui.add( params, 'colorSaturation', 0, 1 ).onChange( updateParams );
gui.add( params, 'colorBrightness', 0, 1 ).onChange( updateParams );
gui.add( params, 'showbox' ).onChange( updateParams );
gui.add( params, 'spotLight', 0, 100 ).onChange( updateParams );

} );
gui.open();

//

function addLabel( name, location ) {

var textGeo = new THREE.TextBufferGeometry( name, {

font: font,

size: 3,
height: 0,
curveSegments: 1

} );

var textMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff } );
var textMesh = new THREE.Mesh( textGeo, textMaterial );
textMesh.position.copy( location );
scene.add( textMesh );

}

addLabel( "premultiplied alpha", new THREE.Vector3( 7, 45, 0 ) );

addLabel( "regular alpha", new THREE.Vector3( -37, 45, 0 ) );

addLabel( "MeshPhysicalMaterial", new THREE.Vector3( 45, 25, 0 ) );

addLabel( "StandardNodeMaterial", new THREE.Vector3( 45, - 25, 0 ) );

}

function onWindowResize() {
Expand Down Expand Up @@ -163,6 +307,14 @@

function render() {

if( hdrCubeRenderTarget && material1.map != hdrCubeRenderTarget.texture ) {
material1.envMap = hdrCubeRenderTarget.texture;
material2.envMap = hdrCubeRenderTarget.texture;
material.envMap = hdrCubeRenderTarget.texture;
material1n.environment = material2n.environment = new Nodes.TextureCubeNode(new Nodes.TextureNode(hdrCubeRenderTarget.texture));
scene.background = hdrCubeMap;
}

for ( var i = 0, l = scene.children.length; i < l; i ++ ) {

var object = scene.children[ i ];
Expand Down
Loading