|
@@ -9,595 +9,597 @@ import { ColorNode } from '../../inputs/ColorNode.js';
|
|
|
import { FloatNode } from '../../inputs/FloatNode.js';
|
|
|
import { SpecularMIPLevelNode } from '../../utils/SpecularMIPLevelNode.js';
|
|
|
|
|
|
-function StandardNode() {
|
|
|
+class StandardNode extends Node {
|
|
|
|
|
|
- Node.call( this );
|
|
|
+ constructor() {
|
|
|
|
|
|
- this.color = new ColorNode( 0xFFFFFF );
|
|
|
- this.roughness = new FloatNode( 1 );
|
|
|
- this.metalness = new FloatNode( 0 );
|
|
|
+ super();
|
|
|
|
|
|
-}
|
|
|
+ this.color = new ColorNode( 0xFFFFFF );
|
|
|
+ this.roughness = new FloatNode( 1 );
|
|
|
+ this.metalness = new FloatNode( 0 );
|
|
|
|
|
|
-StandardNode.prototype = Object.create( Node.prototype );
|
|
|
-StandardNode.prototype.constructor = StandardNode;
|
|
|
-StandardNode.prototype.nodeType = 'Standard';
|
|
|
+ }
|
|
|
|
|
|
-StandardNode.prototype.build = function ( builder ) {
|
|
|
+ build( builder ) {
|
|
|
|
|
|
- var code;
|
|
|
+ let code;
|
|
|
|
|
|
- builder.define( 'STANDARD' );
|
|
|
+ builder.define( 'STANDARD' );
|
|
|
|
|
|
- var useClearcoat = this.clearcoat || this.clearcoatRoughness || this.clearCoatNormal;
|
|
|
+ const useClearcoat = this.clearcoat || this.clearcoatRoughness || this.clearCoatNormal;
|
|
|
|
|
|
- if ( useClearcoat ) {
|
|
|
+ if ( useClearcoat ) {
|
|
|
|
|
|
- builder.define( 'CLEARCOAT' );
|
|
|
+ builder.define( 'CLEARCOAT' );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- builder.requires.lights = true;
|
|
|
+ builder.requires.lights = true;
|
|
|
|
|
|
- builder.extensions.derivatives = true;
|
|
|
- builder.extensions.shaderTextureLOD = true;
|
|
|
+ builder.extensions.derivatives = true;
|
|
|
+ builder.extensions.shaderTextureLOD = true;
|
|
|
|
|
|
- if ( builder.isShader( 'vertex' ) ) {
|
|
|
+ if ( builder.isShader( 'vertex' ) ) {
|
|
|
|
|
|
- var position = this.position ? this.position.analyzeAndFlow( builder, 'v3', { cache: 'position' } ) : undefined;
|
|
|
+ const position = this.position ? this.position.analyzeAndFlow( builder, 'v3', { cache: 'position' } ) : undefined;
|
|
|
|
|
|
- builder.mergeUniform( UniformsUtils.merge( [
|
|
|
+ builder.mergeUniform( UniformsUtils.merge( [
|
|
|
|
|
|
- UniformsLib.fog,
|
|
|
- UniformsLib.lights
|
|
|
+ UniformsLib.fog,
|
|
|
+ UniformsLib.lights
|
|
|
|
|
|
- ] ) );
|
|
|
+ ] ) );
|
|
|
|
|
|
- if ( UniformsLib.LTC_1 ) {
|
|
|
+ if ( UniformsLib.LTC_1 ) {
|
|
|
|
|
|
- // add ltc data textures to material uniforms
|
|
|
+ // add ltc data textures to material uniforms
|
|
|
|
|
|
- builder.uniforms.ltc_1 = { value: undefined };
|
|
|
- builder.uniforms.ltc_2 = { value: undefined };
|
|
|
+ builder.uniforms.ltc_1 = { value: undefined };
|
|
|
+ builder.uniforms.ltc_2 = { value: undefined };
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- builder.addParsCode( [
|
|
|
- 'varying vec3 vViewPosition;',
|
|
|
+ builder.addParsCode( [
|
|
|
+ 'varying vec3 vViewPosition;',
|
|
|
|
|
|
- '#ifndef FLAT_SHADED',
|
|
|
+ '#ifndef FLAT_SHADED',
|
|
|
|
|
|
- ' varying vec3 vNormal;',
|
|
|
+ ' varying vec3 vNormal;',
|
|
|
|
|
|
- '#endif',
|
|
|
+ '#endif',
|
|
|
|
|
|
- //"#include <encodings_pars_fragment>", // encoding functions
|
|
|
- '#include <fog_pars_vertex>',
|
|
|
- '#include <morphtarget_pars_vertex>',
|
|
|
- '#include <skinning_pars_vertex>',
|
|
|
- '#include <shadowmap_pars_vertex>',
|
|
|
- '#include <logdepthbuf_pars_vertex>',
|
|
|
- '#include <clipping_planes_pars_vertex>'
|
|
|
+ //"#include <encodings_pars_fragment>", // encoding functions
|
|
|
+ '#include <fog_pars_vertex>',
|
|
|
+ '#include <morphtarget_pars_vertex>',
|
|
|
+ '#include <skinning_pars_vertex>',
|
|
|
+ '#include <shadowmap_pars_vertex>',
|
|
|
+ '#include <logdepthbuf_pars_vertex>',
|
|
|
+ '#include <clipping_planes_pars_vertex>'
|
|
|
|
|
|
- ].join( '\n' ) );
|
|
|
+ ].join( '\n' ) );
|
|
|
|
|
|
- var output = [
|
|
|
- '#include <beginnormal_vertex>',
|
|
|
- '#include <morphnormal_vertex>',
|
|
|
- '#include <skinbase_vertex>',
|
|
|
- '#include <skinnormal_vertex>',
|
|
|
- '#include <defaultnormal_vertex>',
|
|
|
+ const output = [
|
|
|
+ '#include <beginnormal_vertex>',
|
|
|
+ '#include <morphnormal_vertex>',
|
|
|
+ '#include <skinbase_vertex>',
|
|
|
+ '#include <skinnormal_vertex>',
|
|
|
+ '#include <defaultnormal_vertex>',
|
|
|
|
|
|
- '#ifndef FLAT_SHADED', // Normal computed with derivatives when FLAT_SHADED
|
|
|
+ '#ifndef FLAT_SHADED', // Normal computed with derivatives when FLAT_SHADED
|
|
|
|
|
|
- ' vNormal = normalize( transformedNormal );',
|
|
|
+ ' vNormal = normalize( transformedNormal );',
|
|
|
|
|
|
- '#endif',
|
|
|
+ '#endif',
|
|
|
|
|
|
- '#include <begin_vertex>'
|
|
|
- ];
|
|
|
+ '#include <begin_vertex>'
|
|
|
+ ];
|
|
|
|
|
|
- if ( position ) {
|
|
|
+ if ( position ) {
|
|
|
|
|
|
- output.push(
|
|
|
- position.code,
|
|
|
- position.result ? 'transformed = ' + position.result + ';' : ''
|
|
|
- );
|
|
|
+ output.push(
|
|
|
+ position.code,
|
|
|
+ position.result ? 'transformed = ' + position.result + ';' : ''
|
|
|
+ );
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- output.push(
|
|
|
- '#include <morphtarget_vertex>',
|
|
|
- '#include <skinning_vertex>',
|
|
|
- '#include <project_vertex>',
|
|
|
- '#include <fog_vertex>',
|
|
|
- '#include <logdepthbuf_vertex>',
|
|
|
- '#include <clipping_planes_vertex>',
|
|
|
+ output.push(
|
|
|
+ '#include <morphtarget_vertex>',
|
|
|
+ '#include <skinning_vertex>',
|
|
|
+ '#include <project_vertex>',
|
|
|
+ '#include <fog_vertex>',
|
|
|
+ '#include <logdepthbuf_vertex>',
|
|
|
+ '#include <clipping_planes_vertex>',
|
|
|
|
|
|
- ' vViewPosition = - mvPosition.xyz;',
|
|
|
+ ' vViewPosition = - mvPosition.xyz;',
|
|
|
|
|
|
- '#include <worldpos_vertex>',
|
|
|
- '#include <shadowmap_vertex>'
|
|
|
- );
|
|
|
+ '#include <worldpos_vertex>',
|
|
|
+ '#include <shadowmap_vertex>'
|
|
|
+ );
|
|
|
|
|
|
- code = output.join( '\n' );
|
|
|
+ code = output.join( '\n' );
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
|
|
|
- var specularRoughness = new ExpressionNode( 'material.specularRoughness', 'f' );
|
|
|
- var clearcoatRoughness = new ExpressionNode( 'material.clearcoatRoughness', 'f' );
|
|
|
+ const specularRoughnessNode = new ExpressionNode( 'material.specularRoughness', 'f' );
|
|
|
+ const clearcoatRoughnessNode = new ExpressionNode( 'material.clearcoatRoughness', 'f' );
|
|
|
|
|
|
- var contextEnvironment = {
|
|
|
- roughness: specularRoughness,
|
|
|
- bias: new SpecularMIPLevelNode( specularRoughness ),
|
|
|
- viewNormal: new ExpressionNode( 'normal', 'v3' ),
|
|
|
- worldNormal: new ExpressionNode( 'inverseTransformDirection( geometry.normal, viewMatrix )', 'v3' ),
|
|
|
- gamma: true
|
|
|
- };
|
|
|
+ const contextEnvironment = {
|
|
|
+ roughness: specularRoughnessNode,
|
|
|
+ bias: new SpecularMIPLevelNode( specularRoughnessNode ),
|
|
|
+ viewNormal: new ExpressionNode( 'normal', 'v3' ),
|
|
|
+ worldNormal: new ExpressionNode( 'inverseTransformDirection( geometry.normal, viewMatrix )', 'v3' ),
|
|
|
+ gamma: true
|
|
|
+ };
|
|
|
|
|
|
- var contextGammaOnly = {
|
|
|
- gamma: true
|
|
|
- };
|
|
|
+ const contextGammaOnly = {
|
|
|
+ gamma: true
|
|
|
+ };
|
|
|
+
|
|
|
+ const contextClearcoatEnvironment = {
|
|
|
+ roughness: clearcoatRoughnessNode,
|
|
|
+ bias: new SpecularMIPLevelNode( clearcoatRoughnessNode ),
|
|
|
+ viewNormal: new ExpressionNode( 'clearcoatNormal', 'v3' ),
|
|
|
+ worldNormal: new ExpressionNode( 'inverseTransformDirection( geometry.clearcoatNormal, viewMatrix )', 'v3' ),
|
|
|
+ gamma: true
|
|
|
+ };
|
|
|
|
|
|
- var contextClearcoatEnvironment = {
|
|
|
- roughness: clearcoatRoughness,
|
|
|
- bias: new SpecularMIPLevelNode( clearcoatRoughness ),
|
|
|
- viewNormal: new ExpressionNode( 'clearcoatNormal', 'v3' ),
|
|
|
- worldNormal: new ExpressionNode( 'inverseTransformDirection( geometry.clearcoatNormal, viewMatrix )', 'v3' ),
|
|
|
- gamma: true
|
|
|
- };
|
|
|
+ // analyze all nodes to reuse generate codes
|
|
|
|
|
|
- // analyze all nodes to reuse generate codes
|
|
|
+ if ( this.mask ) this.mask.analyze( builder );
|
|
|
|
|
|
- if ( this.mask ) this.mask.analyze( builder );
|
|
|
+ this.color.analyze( builder, { slot: 'color', context: contextGammaOnly } );
|
|
|
+ this.roughness.analyze( builder );
|
|
|
+ this.metalness.analyze( builder );
|
|
|
|
|
|
- this.color.analyze( builder, { slot: 'color', context: contextGammaOnly } );
|
|
|
- this.roughness.analyze( builder );
|
|
|
- this.metalness.analyze( builder );
|
|
|
+ if ( this.alpha ) this.alpha.analyze( builder );
|
|
|
|
|
|
- if ( this.alpha ) this.alpha.analyze( builder );
|
|
|
+ if ( this.normal ) this.normal.analyze( builder );
|
|
|
|
|
|
- if ( this.normal ) this.normal.analyze( builder );
|
|
|
+ if ( this.clearcoat ) this.clearcoat.analyze( builder );
|
|
|
+ if ( this.clearcoatRoughness ) this.clearcoatRoughness.analyze( builder );
|
|
|
+ if ( this.clearcoatNormal ) this.clearcoatNormal.analyze( builder );
|
|
|
|
|
|
- if ( this.clearcoat ) this.clearcoat.analyze( builder );
|
|
|
- if ( this.clearcoatRoughness ) this.clearcoatRoughness.analyze( builder );
|
|
|
- if ( this.clearcoatNormal ) this.clearcoatNormal.analyze( builder );
|
|
|
+ if ( this.reflectivity ) this.reflectivity.analyze( builder );
|
|
|
|
|
|
- if ( this.reflectivity ) this.reflectivity.analyze( builder );
|
|
|
+ if ( this.light ) this.light.analyze( builder, { cache: 'light' } );
|
|
|
|
|
|
- if ( this.light ) this.light.analyze( builder, { cache: 'light' } );
|
|
|
+ if ( this.ao ) this.ao.analyze( builder );
|
|
|
+ if ( this.ambient ) this.ambient.analyze( builder );
|
|
|
+ if ( this.shadow ) this.shadow.analyze( builder );
|
|
|
+ if ( this.emissive ) this.emissive.analyze( builder, { slot: 'emissive' } );
|
|
|
|
|
|
- if ( this.ao ) this.ao.analyze( builder );
|
|
|
- if ( this.ambient ) this.ambient.analyze( builder );
|
|
|
- if ( this.shadow ) this.shadow.analyze( builder );
|
|
|
- if ( this.emissive ) this.emissive.analyze( builder, { slot: 'emissive' } );
|
|
|
+ if ( this.environment ) {
|
|
|
|
|
|
- if ( this.environment ) {
|
|
|
+ // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
|
|
|
+ // environment.analyze will detect if there is a need of calculate irradiance
|
|
|
|
|
|
- // isolate environment from others inputs ( see TextureNode, CubeTextureNode )
|
|
|
- // environment.analyze will detect if there is a need of calculate irradiance
|
|
|
+ this.environment.analyze( builder, { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } );
|
|
|
|
|
|
- this.environment.analyze( builder, { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } );
|
|
|
+ if ( builder.requires.irradiance ) {
|
|
|
|
|
|
- if ( builder.requires.irradiance ) {
|
|
|
+ this.environment.analyze( builder, { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } );
|
|
|
|
|
|
- this.environment.analyze( builder, { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ if ( this.sheen ) this.sheen.analyze( builder );
|
|
|
|
|
|
- if ( this.sheen ) this.sheen.analyze( builder );
|
|
|
+ // build code
|
|
|
|
|
|
- // build code
|
|
|
+ const mask = this.mask ? this.mask.flow( builder, 'b' ) : undefined;
|
|
|
|
|
|
- var mask = this.mask ? this.mask.flow( builder, 'b' ) : undefined;
|
|
|
+ const color = this.color.flow( builder, 'c', { slot: 'color', context: contextGammaOnly } );
|
|
|
+ const roughness = this.roughness.flow( builder, 'f' );
|
|
|
+ const metalness = this.metalness.flow( builder, 'f' );
|
|
|
|
|
|
- var color = this.color.flow( builder, 'c', { slot: 'color', context: contextGammaOnly } );
|
|
|
- var roughness = this.roughness.flow( builder, 'f' );
|
|
|
- var metalness = this.metalness.flow( builder, 'f' );
|
|
|
+ const alpha = this.alpha ? this.alpha.flow( builder, 'f' ) : undefined;
|
|
|
|
|
|
- var alpha = this.alpha ? this.alpha.flow( builder, 'f' ) : undefined;
|
|
|
+ const normal = this.normal ? this.normal.flow( builder, 'v3' ) : undefined;
|
|
|
|
|
|
- var normal = this.normal ? this.normal.flow( builder, 'v3' ) : undefined;
|
|
|
+ const clearcoat = this.clearcoat ? this.clearcoat.flow( builder, 'f' ) : undefined;
|
|
|
+ const clearcoatRoughness = this.clearcoatRoughness ? this.clearcoatRoughness.flow( builder, 'f' ) : undefined;
|
|
|
+ const clearcoatNormal = this.clearcoatNormal ? this.clearcoatNormal.flow( builder, 'v3' ) : undefined;
|
|
|
|
|
|
- var clearcoat = this.clearcoat ? this.clearcoat.flow( builder, 'f' ) : undefined;
|
|
|
- var clearcoatRoughness = this.clearcoatRoughness ? this.clearcoatRoughness.flow( builder, 'f' ) : undefined;
|
|
|
- var clearcoatNormal = this.clearcoatNormal ? this.clearcoatNormal.flow( builder, 'v3' ) : undefined;
|
|
|
+ const reflectivity = this.reflectivity ? this.reflectivity.flow( builder, 'f' ) : undefined;
|
|
|
|
|
|
- var reflectivity = this.reflectivity ? this.reflectivity.flow( builder, 'f' ) : undefined;
|
|
|
+ const light = this.light ? this.light.flow( builder, 'v3', { cache: 'light' } ) : undefined;
|
|
|
|
|
|
- var light = this.light ? this.light.flow( builder, 'v3', { cache: 'light' } ) : undefined;
|
|
|
+ const ao = this.ao ? this.ao.flow( builder, 'f' ) : undefined;
|
|
|
+ const ambient = this.ambient ? this.ambient.flow( builder, 'c' ) : undefined;
|
|
|
+ const shadow = this.shadow ? this.shadow.flow( builder, 'c' ) : undefined;
|
|
|
+ const emissive = this.emissive ? this.emissive.flow( builder, 'c', { slot: 'emissive' } ) : undefined;
|
|
|
|
|
|
- var ao = this.ao ? this.ao.flow( builder, 'f' ) : undefined;
|
|
|
- var ambient = this.ambient ? this.ambient.flow( builder, 'c' ) : undefined;
|
|
|
- var shadow = this.shadow ? this.shadow.flow( builder, 'c' ) : undefined;
|
|
|
- var emissive = this.emissive ? this.emissive.flow( builder, 'c', { slot: 'emissive' } ) : undefined;
|
|
|
+ let environment;
|
|
|
|
|
|
- var environment;
|
|
|
+ if ( this.environment ) {
|
|
|
|
|
|
- if ( this.environment ) {
|
|
|
+ environment = {
|
|
|
+ radiance: this.environment.flow( builder, 'c', { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } )
|
|
|
+ };
|
|
|
|
|
|
- environment = {
|
|
|
- radiance: this.environment.flow( builder, 'c', { cache: 'radiance', context: contextEnvironment, slot: 'radiance' } )
|
|
|
- };
|
|
|
+ if ( builder.requires.irradiance ) {
|
|
|
|
|
|
- if ( builder.requires.irradiance ) {
|
|
|
+ environment.irradiance = this.environment.flow( builder, 'c', { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } );
|
|
|
|
|
|
- environment.irradiance = this.environment.flow( builder, 'c', { cache: 'irradiance', context: contextEnvironment, slot: 'irradiance' } );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ const clearcoatEnv = useClearcoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearcoat', context: contextClearcoatEnvironment, slot: 'environment' } ) : undefined;
|
|
|
|
|
|
- var clearcoatEnv = useClearcoat && environment ? this.environment.flow( builder, 'c', { cache: 'clearcoat', context: contextClearcoatEnvironment, slot: 'environment' } ) : undefined;
|
|
|
+ const sheen = this.sheen ? this.sheen.flow( builder, 'c' ) : undefined;
|
|
|
|
|
|
- var sheen = this.sheen ? this.sheen.flow( builder, 'c' ) : undefined;
|
|
|
+ builder.requires.transparent = alpha !== undefined;
|
|
|
|
|
|
- builder.requires.transparent = alpha !== undefined;
|
|
|
+ builder.addParsCode( [
|
|
|
+ 'varying vec3 vViewPosition;',
|
|
|
|
|
|
- builder.addParsCode( [
|
|
|
- 'varying vec3 vViewPosition;',
|
|
|
+ '#ifndef FLAT_SHADED',
|
|
|
|
|
|
- '#ifndef FLAT_SHADED',
|
|
|
+ ' varying vec3 vNormal;',
|
|
|
|
|
|
- ' varying vec3 vNormal;',
|
|
|
+ '#endif',
|
|
|
|
|
|
- '#endif',
|
|
|
+ '#include <dithering_pars_fragment>',
|
|
|
+ '#include <fog_pars_fragment>',
|
|
|
+ '#include <bsdfs>',
|
|
|
+ '#include <lights_pars_begin>',
|
|
|
+ '#include <lights_physical_pars_fragment>',
|
|
|
+ '#include <shadowmap_pars_fragment>',
|
|
|
+ '#include <logdepthbuf_pars_fragment>'
|
|
|
+ ].join( '\n' ) );
|
|
|
|
|
|
- '#include <dithering_pars_fragment>',
|
|
|
- '#include <fog_pars_fragment>',
|
|
|
- '#include <bsdfs>',
|
|
|
- '#include <lights_pars_begin>',
|
|
|
- '#include <lights_physical_pars_fragment>',
|
|
|
- '#include <shadowmap_pars_fragment>',
|
|
|
- '#include <logdepthbuf_pars_fragment>'
|
|
|
- ].join( '\n' ) );
|
|
|
+ const output = [
|
|
|
+ '#include <clipping_planes_fragment>',
|
|
|
|
|
|
- var output = [
|
|
|
- '#include <clipping_planes_fragment>',
|
|
|
+ // add before: prevent undeclared normal
|
|
|
+ ' #include <normal_fragment_begin>',
|
|
|
+ ' #include <clearcoat_normal_fragment_begin>',
|
|
|
|
|
|
- // add before: prevent undeclared normal
|
|
|
- ' #include <normal_fragment_begin>',
|
|
|
- ' #include <clearcoat_normal_fragment_begin>',
|
|
|
+ // add before: prevent undeclared material
|
|
|
+ ' PhysicalMaterial material;',
|
|
|
+ ' material.diffuseColor = vec3( 1.0 );'
|
|
|
+ ];
|
|
|
|
|
|
- // add before: prevent undeclared material
|
|
|
- ' PhysicalMaterial material;',
|
|
|
- ' material.diffuseColor = vec3( 1.0 );'
|
|
|
- ];
|
|
|
+ if ( mask ) {
|
|
|
+
|
|
|
+ output.push(
|
|
|
+ mask.code,
|
|
|
+ 'if ( ! ' + mask.result + ' ) discard;'
|
|
|
+ );
|
|
|
|
|
|
- if ( mask ) {
|
|
|
+ }
|
|
|
|
|
|
output.push(
|
|
|
- mask.code,
|
|
|
- 'if ( ! ' + mask.result + ' ) discard;'
|
|
|
- );
|
|
|
+ color.code,
|
|
|
+ ' vec3 diffuseColor = ' + color.result + ';',
|
|
|
+ ' ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );',
|
|
|
|
|
|
- }
|
|
|
+ '#include <logdepthbuf_fragment>',
|
|
|
|
|
|
- output.push(
|
|
|
- color.code,
|
|
|
- ' vec3 diffuseColor = ' + color.result + ';',
|
|
|
- ' ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );',
|
|
|
+ roughness.code,
|
|
|
+ ' float roughnessFactor = ' + roughness.result + ';',
|
|
|
|
|
|
- '#include <logdepthbuf_fragment>',
|
|
|
+ metalness.code,
|
|
|
+ ' float metalnessFactor = ' + metalness.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- roughness.code,
|
|
|
- ' float roughnessFactor = ' + roughness.result + ';',
|
|
|
+ if ( alpha ) {
|
|
|
|
|
|
- metalness.code,
|
|
|
- ' float metalnessFactor = ' + metalness.result + ';'
|
|
|
- );
|
|
|
+ output.push(
|
|
|
+ alpha.code,
|
|
|
+ '#ifdef ALPHATEST',
|
|
|
|
|
|
- if ( alpha ) {
|
|
|
+ ' if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
|
|
|
|
|
|
- output.push(
|
|
|
- alpha.code,
|
|
|
- '#ifdef ALPHATEST',
|
|
|
+ '#endif'
|
|
|
+ );
|
|
|
|
|
|
- ' if ( ' + alpha.result + ' <= ALPHATEST ) discard;',
|
|
|
+ }
|
|
|
|
|
|
- '#endif'
|
|
|
- );
|
|
|
+ if ( normal ) {
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ normal.code,
|
|
|
+ 'normal = ' + normal.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- if ( normal ) {
|
|
|
+ }
|
|
|
|
|
|
- output.push(
|
|
|
- normal.code,
|
|
|
- 'normal = ' + normal.result + ';'
|
|
|
- );
|
|
|
+ if ( clearcoatNormal ) {
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ clearcoatNormal.code,
|
|
|
+ 'clearcoatNormal = ' + clearcoatNormal.result + ';'
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- if ( clearcoatNormal ) {
|
|
|
+ // anti-aliasing code by @elalish
|
|
|
|
|
|
output.push(
|
|
|
- clearcoatNormal.code,
|
|
|
- 'clearcoatNormal = ' + clearcoatNormal.result + ';'
|
|
|
+ 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
|
|
|
+ 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',
|
|
|
);
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- // anti-aliasing code by @elalish
|
|
|
+ // optimization for now
|
|
|
|
|
|
- output.push(
|
|
|
- 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
|
|
|
- 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',
|
|
|
- );
|
|
|
+ output.push(
|
|
|
+ 'material.diffuseColor = ' + ( light ? 'vec3( 1.0 )' : 'diffuseColor * ( 1.0 - metalnessFactor )' ) + ';',
|
|
|
|
|
|
- // optimization for now
|
|
|
+ 'material.specularRoughness = max( roughnessFactor, 0.0525 );',
|
|
|
+ 'material.specularRoughness += geometryRoughness;',
|
|
|
+ 'material.specularRoughness = min( material.specularRoughness, 1.0 );',
|
|
|
|
|
|
- output.push(
|
|
|
- 'material.diffuseColor = ' + ( light ? 'vec3( 1.0 )' : 'diffuseColor * ( 1.0 - metalnessFactor )' ) + ';',
|
|
|
+ 'material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );'
|
|
|
+ );
|
|
|
|
|
|
- 'material.specularRoughness = max( roughnessFactor, 0.0525 );',
|
|
|
- 'material.specularRoughness += geometryRoughness;',
|
|
|
- 'material.specularRoughness = min( material.specularRoughness, 1.0 );',
|
|
|
+ if ( clearcoat ) {
|
|
|
|
|
|
- 'material.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );'
|
|
|
- );
|
|
|
+ output.push(
|
|
|
+ clearcoat.code,
|
|
|
+ 'material.clearcoat = saturate( ' + clearcoat.result + ' );' // Burley clearcoat model
|
|
|
+ );
|
|
|
|
|
|
- if ( clearcoat ) {
|
|
|
+ } else if ( useClearcoat ) {
|
|
|
|
|
|
- output.push(
|
|
|
- clearcoat.code,
|
|
|
- 'material.clearcoat = saturate( ' + clearcoat.result + ' );' // Burley clearcoat model
|
|
|
- );
|
|
|
+ output.push( 'material.clearcoat = 0.0;' );
|
|
|
|
|
|
- } else if ( useClearcoat ) {
|
|
|
+ }
|
|
|
|
|
|
- output.push( 'material.clearcoat = 0.0;' );
|
|
|
+ if ( clearcoatRoughness ) {
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ clearcoatRoughness.code,
|
|
|
+ 'material.clearcoatRoughness = max( ' + clearcoatRoughness.result + ', 0.0525 );',
|
|
|
+ 'material.clearcoatRoughness += geometryRoughness;',
|
|
|
+ 'material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );'
|
|
|
+ );
|
|
|
|
|
|
- if ( clearcoatRoughness ) {
|
|
|
+ } else if ( useClearcoat ) {
|
|
|
|
|
|
- output.push(
|
|
|
- clearcoatRoughness.code,
|
|
|
- 'material.clearcoatRoughness = max( ' + clearcoatRoughness.result + ', 0.0525 );',
|
|
|
- 'material.clearcoatRoughness += geometryRoughness;',
|
|
|
- 'material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );'
|
|
|
- );
|
|
|
+ output.push( 'material.clearcoatRoughness = 0.0;' );
|
|
|
|
|
|
- } else if ( useClearcoat ) {
|
|
|
+ }
|
|
|
|
|
|
- output.push( 'material.clearcoatRoughness = 0.0;' );
|
|
|
+ if ( sheen ) {
|
|
|
|
|
|
- }
|
|
|
+ output.push( 'material.sheenColor = ' + sheen.result + ';' );
|
|
|
|
|
|
- if ( sheen ) {
|
|
|
+ }
|
|
|
|
|
|
- output.push( 'material.sheenColor = ' + sheen.result + ';' );
|
|
|
+ if ( reflectivity ) {
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ reflectivity.code,
|
|
|
+ 'material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( ' + reflectivity.result + ' ) ), diffuseColor, metalnessFactor );'
|
|
|
+ );
|
|
|
|
|
|
- if ( reflectivity ) {
|
|
|
+ } else {
|
|
|
|
|
|
- output.push(
|
|
|
- reflectivity.code,
|
|
|
- 'material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( ' + reflectivity.result + ' ) ), diffuseColor, metalnessFactor );'
|
|
|
- );
|
|
|
+ output.push(
|
|
|
+ 'material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor, metalnessFactor );'
|
|
|
+ );
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
output.push(
|
|
|
- 'material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor, metalnessFactor );'
|
|
|
+ '#include <lights_fragment_begin>'
|
|
|
);
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- output.push(
|
|
|
- '#include <lights_fragment_begin>'
|
|
|
- );
|
|
|
+ if ( light ) {
|
|
|
|
|
|
- if ( light ) {
|
|
|
+ output.push(
|
|
|
+ light.code,
|
|
|
+ 'reflectedLight.directDiffuse = ' + light.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- light.code,
|
|
|
- 'reflectedLight.directDiffuse = ' + light.result + ';'
|
|
|
- );
|
|
|
+ // apply color
|
|
|
|
|
|
- // apply color
|
|
|
+ output.push(
|
|
|
+ 'diffuseColor *= 1.0 - metalnessFactor;',
|
|
|
|
|
|
- output.push(
|
|
|
- 'diffuseColor *= 1.0 - metalnessFactor;',
|
|
|
+ 'reflectedLight.directDiffuse *= diffuseColor;',
|
|
|
+ 'reflectedLight.indirectDiffuse *= diffuseColor;'
|
|
|
+ );
|
|
|
|
|
|
- 'reflectedLight.directDiffuse *= diffuseColor;',
|
|
|
- 'reflectedLight.indirectDiffuse *= diffuseColor;'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( ao ) {
|
|
|
|
|
|
- if ( ao ) {
|
|
|
+ output.push(
|
|
|
+ ao.code,
|
|
|
+ 'reflectedLight.indirectDiffuse *= ' + ao.result + ';',
|
|
|
+ 'float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );',
|
|
|
+ 'reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ' + ao.result + ', material.specularRoughness );'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- ao.code,
|
|
|
- 'reflectedLight.indirectDiffuse *= ' + ao.result + ';',
|
|
|
- 'float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );',
|
|
|
- 'reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ' + ao.result + ', material.specularRoughness );'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( ambient ) {
|
|
|
|
|
|
- if ( ambient ) {
|
|
|
+ output.push(
|
|
|
+ ambient.code,
|
|
|
+ 'reflectedLight.indirectDiffuse += ' + ambient.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- ambient.code,
|
|
|
- 'reflectedLight.indirectDiffuse += ' + ambient.result + ';'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( shadow ) {
|
|
|
|
|
|
- if ( shadow ) {
|
|
|
+ output.push(
|
|
|
+ shadow.code,
|
|
|
+ 'reflectedLight.directDiffuse *= ' + shadow.result + ';',
|
|
|
+ 'reflectedLight.directSpecular *= ' + shadow.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- shadow.code,
|
|
|
- 'reflectedLight.directDiffuse *= ' + shadow.result + ';',
|
|
|
- 'reflectedLight.directSpecular *= ' + shadow.result + ';'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( emissive ) {
|
|
|
|
|
|
- if ( emissive ) {
|
|
|
+ output.push(
|
|
|
+ emissive.code,
|
|
|
+ 'reflectedLight.directDiffuse += ' + emissive.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- emissive.code,
|
|
|
- 'reflectedLight.directDiffuse += ' + emissive.result + ';'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( environment ) {
|
|
|
|
|
|
- if ( environment ) {
|
|
|
+ output.push( environment.radiance.code );
|
|
|
|
|
|
- output.push( environment.radiance.code );
|
|
|
+ if ( builder.requires.irradiance ) {
|
|
|
|
|
|
- if ( builder.requires.irradiance ) {
|
|
|
+ output.push( environment.irradiance.code );
|
|
|
|
|
|
- output.push( environment.irradiance.code );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ if ( clearcoatEnv ) {
|
|
|
|
|
|
- if ( clearcoatEnv ) {
|
|
|
+ output.push(
|
|
|
+ clearcoatEnv.code,
|
|
|
+ 'clearcoatRadiance += ' + clearcoatEnv.result + ';'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- clearcoatEnv.code,
|
|
|
- 'clearcoatRadiance += ' + clearcoatEnv.result + ';'
|
|
|
- );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ output.push( 'radiance += ' + environment.radiance.result + ';' );
|
|
|
|
|
|
- output.push( 'radiance += ' + environment.radiance.result + ';' );
|
|
|
+ if ( builder.requires.irradiance ) {
|
|
|
|
|
|
- if ( builder.requires.irradiance ) {
|
|
|
+ output.push( 'iblIrradiance += PI * ' + environment.irradiance.result + ';' );
|
|
|
|
|
|
- output.push( 'iblIrradiance += PI * ' + environment.irradiance.result + ';' );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ '#include <lights_fragment_end>'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- '#include <lights_fragment_end>'
|
|
|
- );
|
|
|
+ output.push( 'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;' );
|
|
|
|
|
|
- output.push( 'vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular;' );
|
|
|
+ if ( alpha ) {
|
|
|
|
|
|
- if ( alpha ) {
|
|
|
+ output.push( 'gl_FragColor = vec4( outgoingLight, ' + alpha.result + ' );' );
|
|
|
|
|
|
- output.push( 'gl_FragColor = vec4( outgoingLight, ' + alpha.result + ' );' );
|
|
|
+ } else {
|
|
|
|
|
|
- } else {
|
|
|
+ output.push( 'gl_FragColor = vec4( outgoingLight, 1.0 );' );
|
|
|
|
|
|
- output.push( 'gl_FragColor = vec4( outgoingLight, 1.0 );' );
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ output.push(
|
|
|
+ '#include <tonemapping_fragment>',
|
|
|
+ '#include <encodings_fragment>',
|
|
|
+ '#include <fog_fragment>',
|
|
|
+ '#include <premultiplied_alpha_fragment>',
|
|
|
+ '#include <dithering_fragment>'
|
|
|
+ );
|
|
|
|
|
|
- output.push(
|
|
|
- '#include <tonemapping_fragment>',
|
|
|
- '#include <encodings_fragment>',
|
|
|
- '#include <fog_fragment>',
|
|
|
- '#include <premultiplied_alpha_fragment>',
|
|
|
- '#include <dithering_fragment>'
|
|
|
- );
|
|
|
+ code = output.join( '\n' );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- code = output.join( '\n' );
|
|
|
+ return code;
|
|
|
|
|
|
}
|
|
|
|
|
|
- return code;
|
|
|
+ copy( source ) {
|
|
|
|
|
|
-};
|
|
|
+ super.copy( source );
|
|
|
|
|
|
-StandardNode.prototype.copy = function ( source ) {
|
|
|
+ // vertex
|
|
|
|
|
|
- Node.prototype.copy.call( this, source );
|
|
|
+ if ( source.position ) this.position = source.position;
|
|
|
|
|
|
- // vertex
|
|
|
+ // fragment
|
|
|
|
|
|
- if ( source.position ) this.position = source.position;
|
|
|
+ this.color = source.color;
|
|
|
+ this.roughness = source.roughness;
|
|
|
+ this.metalness = source.metalness;
|
|
|
|
|
|
- // fragment
|
|
|
+ if ( source.mask ) this.mask = source.mask;
|
|
|
|
|
|
- this.color = source.color;
|
|
|
- this.roughness = source.roughness;
|
|
|
- this.metalness = source.metalness;
|
|
|
+ if ( source.alpha ) this.alpha = source.alpha;
|
|
|
|
|
|
- if ( source.mask ) this.mask = source.mask;
|
|
|
+ if ( source.normal ) this.normal = source.normal;
|
|
|
|
|
|
- if ( source.alpha ) this.alpha = source.alpha;
|
|
|
+ if ( source.clearcoat ) this.clearcoat = source.clearcoat;
|
|
|
+ if ( source.clearcoatRoughness ) this.clearcoatRoughness = source.clearcoatRoughness;
|
|
|
+ if ( source.clearcoatNormal ) this.clearcoatNormal = source.clearcoatNormal;
|
|
|
|
|
|
- if ( source.normal ) this.normal = source.normal;
|
|
|
+ if ( source.reflectivity ) this.reflectivity = source.reflectivity;
|
|
|
|
|
|
- if ( source.clearcoat ) this.clearcoat = source.clearcoat;
|
|
|
- if ( source.clearcoatRoughness ) this.clearcoatRoughness = source.clearcoatRoughness;
|
|
|
- if ( source.clearcoatNormal ) this.clearcoatNormal = source.clearcoatNormal;
|
|
|
+ if ( source.light ) this.light = source.light;
|
|
|
+ if ( source.shadow ) this.shadow = source.shadow;
|
|
|
|
|
|
- if ( source.reflectivity ) this.reflectivity = source.reflectivity;
|
|
|
+ if ( source.ao ) this.ao = source.ao;
|
|
|
|
|
|
- if ( source.light ) this.light = source.light;
|
|
|
- if ( source.shadow ) this.shadow = source.shadow;
|
|
|
+ if ( source.emissive ) this.emissive = source.emissive;
|
|
|
+ if ( source.ambient ) this.ambient = source.ambient;
|
|
|
|
|
|
- if ( source.ao ) this.ao = source.ao;
|
|
|
+ if ( source.environment ) this.environment = source.environment;
|
|
|
|
|
|
- if ( source.emissive ) this.emissive = source.emissive;
|
|
|
- if ( source.ambient ) this.ambient = source.ambient;
|
|
|
+ if ( source.sheen ) this.sheen = source.sheen;
|
|
|
|
|
|
- if ( source.environment ) this.environment = source.environment;
|
|
|
+ return this;
|
|
|
|
|
|
- if ( source.sheen ) this.sheen = source.sheen;
|
|
|
+ }
|
|
|
|
|
|
- return this;
|
|
|
+ toJSON( meta ) {
|
|
|
|
|
|
-};
|
|
|
+ let data = this.getJSONNode( meta );
|
|
|
|
|
|
-StandardNode.prototype.toJSON = function ( meta ) {
|
|
|
+ if ( ! data ) {
|
|
|
|
|
|
- var data = this.getJSONNode( meta );
|
|
|
+ data = this.createJSONNode( meta );
|
|
|
|
|
|
- if ( ! data ) {
|
|
|
+ // vertex
|
|
|
|
|
|
- data = this.createJSONNode( meta );
|
|
|
+ if ( this.position ) data.position = this.position.toJSON( meta ).uuid;
|
|
|
|
|
|
- // vertex
|
|
|
+ // fragment
|
|
|
|
|
|
- if ( this.position ) data.position = this.position.toJSON( meta ).uuid;
|
|
|
+ data.color = this.color.toJSON( meta ).uuid;
|
|
|
+ data.roughness = this.roughness.toJSON( meta ).uuid;
|
|
|
+ data.metalness = this.metalness.toJSON( meta ).uuid;
|
|
|
|
|
|
- // fragment
|
|
|
+ if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
|
|
|
|
|
|
- data.color = this.color.toJSON( meta ).uuid;
|
|
|
- data.roughness = this.roughness.toJSON( meta ).uuid;
|
|
|
- data.metalness = this.metalness.toJSON( meta ).uuid;
|
|
|
+ if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.mask ) data.mask = this.mask.toJSON( meta ).uuid;
|
|
|
+ if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.alpha ) data.alpha = this.alpha.toJSON( meta ).uuid;
|
|
|
+ if ( this.clearcoat ) data.clearcoat = this.clearcoat.toJSON( meta ).uuid;
|
|
|
+ if ( this.clearcoatRoughness ) data.clearcoatRoughness = this.clearcoatRoughness.toJSON( meta ).uuid;
|
|
|
+ if ( this.clearcoatNormal ) data.clearcoatNormal = this.clearcoatNormal.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.normal ) data.normal = this.normal.toJSON( meta ).uuid;
|
|
|
+ if ( this.reflectivity ) data.reflectivity = this.reflectivity.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.clearcoat ) data.clearcoat = this.clearcoat.toJSON( meta ).uuid;
|
|
|
- if ( this.clearcoatRoughness ) data.clearcoatRoughness = this.clearcoatRoughness.toJSON( meta ).uuid;
|
|
|
- if ( this.clearcoatNormal ) data.clearcoatNormal = this.clearcoatNormal.toJSON( meta ).uuid;
|
|
|
+ if ( this.light ) data.light = this.light.toJSON( meta ).uuid;
|
|
|
+ if ( this.shadow ) data.shadow = this.shadow.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.reflectivity ) data.reflectivity = this.reflectivity.toJSON( meta ).uuid;
|
|
|
+ if ( this.ao ) data.ao = this.ao.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.light ) data.light = this.light.toJSON( meta ).uuid;
|
|
|
- if ( this.shadow ) data.shadow = this.shadow.toJSON( meta ).uuid;
|
|
|
+ if ( this.emissive ) data.emissive = this.emissive.toJSON( meta ).uuid;
|
|
|
+ if ( this.ambient ) data.ambient = this.ambient.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.ao ) data.ao = this.ao.toJSON( meta ).uuid;
|
|
|
+ if ( this.environment ) data.environment = this.environment.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.emissive ) data.emissive = this.emissive.toJSON( meta ).uuid;
|
|
|
- if ( this.ambient ) data.ambient = this.ambient.toJSON( meta ).uuid;
|
|
|
+ if ( this.sheen ) data.sheen = this.sheen.toJSON( meta ).uuid;
|
|
|
|
|
|
- if ( this.environment ) data.environment = this.environment.toJSON( meta ).uuid;
|
|
|
+ }
|
|
|
|
|
|
- if ( this.sheen ) data.sheen = this.sheen.toJSON( meta ).uuid;
|
|
|
+ return data;
|
|
|
|
|
|
}
|
|
|
|
|
|
- return data;
|
|
|
+}
|
|
|
|
|
|
-};
|
|
|
+StandardNode.prototype.nodeType = 'Standard';
|
|
|
|
|
|
export { StandardNode };
|