添加关照、全局等高线、修改图层问题
This commit is contained in:
		
							
								
								
									
										27
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AONode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AONode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
import LightingNode from './LightingNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
class AONode extends LightingNode {
 | 
			
		||||
 | 
			
		||||
	constructor( aoNode = null ) {
 | 
			
		||||
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this.aoNode = aoNode;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		const aoIntensity = 1;
 | 
			
		||||
		const aoNode = this.aoNode.x.sub( 1.0 ).mul( aoIntensity ).add( 1.0 );
 | 
			
		||||
 | 
			
		||||
		builder.context.ambientOcclusion.mulAssign( aoNode );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AONode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'AONode', AONode );
 | 
			
		||||
							
								
								
									
										27
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AmbientLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AmbientLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import { AmbientLight } from 'three';
 | 
			
		||||
 | 
			
		||||
class AmbientLightNode extends AnalyticLightNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super( light );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( { context } ) {
 | 
			
		||||
 | 
			
		||||
		context.irradiance.addAssign( this.colorNode );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AmbientLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'AmbientLightNode', AmbientLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( AmbientLight, AmbientLightNode );
 | 
			
		||||
							
								
								
									
										255
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AnalyticLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/AnalyticLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,255 @@
 | 
			
		||||
import LightingNode from './LightingNode.js';
 | 
			
		||||
import { NodeUpdateType } from '../core/constants.js';
 | 
			
		||||
import { uniform } from '../core/UniformNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
import { /*vec2,*/ vec3, vec4 } from '../shadernode/ShaderNode.js';
 | 
			
		||||
import { reference } from '../accessors/ReferenceNode.js';
 | 
			
		||||
import { texture } from '../accessors/TextureNode.js';
 | 
			
		||||
import { positionWorld } from '../accessors/PositionNode.js';
 | 
			
		||||
import { normalWorld } from '../accessors/NormalNode.js';
 | 
			
		||||
import { WebGPUCoordinateSystem } from 'three';
 | 
			
		||||
//import { add } from '../math/OperatorNode.js';
 | 
			
		||||
 | 
			
		||||
import { Color, DepthTexture, NearestFilter, LessCompare, NoToneMapping } from 'three';
 | 
			
		||||
 | 
			
		||||
let overrideMaterial = null;
 | 
			
		||||
 | 
			
		||||
class AnalyticLightNode extends LightingNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this.updateType = NodeUpdateType.FRAME;
 | 
			
		||||
 | 
			
		||||
		this.light = light;
 | 
			
		||||
 | 
			
		||||
		this.rtt = null;
 | 
			
		||||
		this.shadowNode = null;
 | 
			
		||||
		this.shadowMaskNode = null;
 | 
			
		||||
 | 
			
		||||
		this.color = new Color();
 | 
			
		||||
		this._defaultColorNode = uniform( this.color );
 | 
			
		||||
 | 
			
		||||
		this.colorNode = this._defaultColorNode;
 | 
			
		||||
 | 
			
		||||
		this.isAnalyticLightNode = true;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getCacheKey() {
 | 
			
		||||
 | 
			
		||||
		return super.getCacheKey() + '-' + ( this.light.id + '-' + ( this.light.castShadow ? '1' : '0' ) );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getHash() {
 | 
			
		||||
 | 
			
		||||
		return this.light.uuid;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setupShadow( builder ) {
 | 
			
		||||
 | 
			
		||||
		const { object } = builder;
 | 
			
		||||
 | 
			
		||||
		if ( object.receiveShadow === false ) return;
 | 
			
		||||
 | 
			
		||||
		let shadowNode = this.shadowNode;
 | 
			
		||||
 | 
			
		||||
		if ( shadowNode === null ) {
 | 
			
		||||
 | 
			
		||||
			if ( overrideMaterial === null ) {
 | 
			
		||||
 | 
			
		||||
				overrideMaterial = builder.createNodeMaterial();
 | 
			
		||||
				overrideMaterial.fragmentNode = vec4( 0, 0, 0, 1 );
 | 
			
		||||
				overrideMaterial.isShadowNodeMaterial = true; // Use to avoid other overrideMaterial override material.fragmentNode unintentionally when using material.shadowNode
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			const shadow = this.light.shadow;
 | 
			
		||||
			const rtt = builder.createRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
 | 
			
		||||
 | 
			
		||||
			const depthTexture = new DepthTexture();
 | 
			
		||||
			depthTexture.minFilter = NearestFilter;
 | 
			
		||||
			depthTexture.magFilter = NearestFilter;
 | 
			
		||||
			depthTexture.image.width = shadow.mapSize.width;
 | 
			
		||||
			depthTexture.image.height = shadow.mapSize.height;
 | 
			
		||||
			depthTexture.compareFunction = LessCompare;
 | 
			
		||||
 | 
			
		||||
			rtt.depthTexture = depthTexture;
 | 
			
		||||
 | 
			
		||||
			shadow.camera.updateProjectionMatrix();
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			const bias = reference( 'bias', 'float', shadow );
 | 
			
		||||
			const normalBias = reference( 'normalBias', 'float', shadow );
 | 
			
		||||
 | 
			
		||||
			const position = object.material.shadowPositionNode || positionWorld;
 | 
			
		||||
 | 
			
		||||
			let shadowCoord = uniform( shadow.matrix ).mul( position.add( normalWorld.mul( normalBias ) ) );
 | 
			
		||||
			shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
 | 
			
		||||
 | 
			
		||||
			const frustumTest = shadowCoord.x.greaterThanEqual( 0 )
 | 
			
		||||
				.and( shadowCoord.x.lessThanEqual( 1 ) )
 | 
			
		||||
				.and( shadowCoord.y.greaterThanEqual( 0 ) )
 | 
			
		||||
				.and( shadowCoord.y.lessThanEqual( 1 ) )
 | 
			
		||||
				.and( shadowCoord.z.lessThanEqual( 1 ) );
 | 
			
		||||
 | 
			
		||||
			let coordZ = shadowCoord.z.add( bias );
 | 
			
		||||
 | 
			
		||||
			if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem ) {
 | 
			
		||||
 | 
			
		||||
				coordZ = coordZ.mul( 2 ).sub( 1 ); // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			shadowCoord = vec3(
 | 
			
		||||
				shadowCoord.x,
 | 
			
		||||
				shadowCoord.y.oneMinus(), // follow webgpu standards
 | 
			
		||||
				coordZ
 | 
			
		||||
			);
 | 
			
		||||
 | 
			
		||||
			const textureCompare = ( depthTexture, shadowCoord, compare ) => texture( depthTexture, shadowCoord ).compare( compare );
 | 
			
		||||
			//const textureCompare = ( depthTexture, shadowCoord, compare ) => compare.step( texture( depthTexture, shadowCoord ) );
 | 
			
		||||
 | 
			
		||||
			// BasicShadowMap
 | 
			
		||||
 | 
			
		||||
			shadowNode = textureCompare( depthTexture, shadowCoord.xy, shadowCoord.z );
 | 
			
		||||
 | 
			
		||||
			// PCFShadowMap
 | 
			
		||||
			/*
 | 
			
		||||
			const mapSize = reference( 'mapSize', 'vec2', shadow );
 | 
			
		||||
			const radius = reference( 'radius', 'float', shadow );
 | 
			
		||||
 | 
			
		||||
			const texelSize = vec2( 1 ).div( mapSize );
 | 
			
		||||
			const dx0 = texelSize.x.negate().mul( radius );
 | 
			
		||||
			const dy0 = texelSize.y.negate().mul( radius );
 | 
			
		||||
			const dx1 = texelSize.x.mul( radius );
 | 
			
		||||
			const dy1 = texelSize.y.mul( radius );
 | 
			
		||||
			const dx2 = dx0.mul( 2 );
 | 
			
		||||
			const dy2 = dy0.mul( 2 );
 | 
			
		||||
			const dx3 = dx1.mul( 2 );
 | 
			
		||||
			const dy3 = dy1.mul( 2 );
 | 
			
		||||
 | 
			
		||||
			shadowNode = add(
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, dy0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, dy2 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy2 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, dy2 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, 0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, 0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy, shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, 0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, 0 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx2, dy3 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy3 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx3, dy3 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx0, dy1 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( 0, dy1 ) ), shadowCoord.z ),
 | 
			
		||||
				textureCompare( depthTexture, shadowCoord.xy.add( vec2( dx1, dy1 ) ), shadowCoord.z )
 | 
			
		||||
			).mul( 1 / 17 );
 | 
			
		||||
			 */
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			const shadowColor = texture( rtt.texture, shadowCoord );
 | 
			
		||||
			const shadowMaskNode = frustumTest.mix( 1, shadowNode.mix( shadowColor.a.mix( 1, shadowColor ), 1 ) );
 | 
			
		||||
 | 
			
		||||
			this.rtt = rtt;
 | 
			
		||||
			this.colorNode = this.colorNode.mul( shadowMaskNode );
 | 
			
		||||
 | 
			
		||||
			this.shadowNode = shadowNode;
 | 
			
		||||
			this.shadowMaskNode = shadowMaskNode;
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			this.updateBeforeType = NodeUpdateType.RENDER;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		if ( this.light.castShadow ) this.setupShadow( builder );
 | 
			
		||||
		else if ( this.shadowNode !== null ) this.disposeShadow();
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	updateShadow( frame ) {
 | 
			
		||||
 | 
			
		||||
		const { rtt, light } = this;
 | 
			
		||||
		const { renderer, scene } = frame;
 | 
			
		||||
 | 
			
		||||
		const currentOverrideMaterial = scene.overrideMaterial;
 | 
			
		||||
 | 
			
		||||
		scene.overrideMaterial = overrideMaterial;
 | 
			
		||||
 | 
			
		||||
		rtt.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
 | 
			
		||||
 | 
			
		||||
		light.shadow.updateMatrices( light );
 | 
			
		||||
 | 
			
		||||
		const currentToneMapping = renderer.toneMapping;
 | 
			
		||||
		const currentRenderTarget = renderer.getRenderTarget();
 | 
			
		||||
		const currentRenderObjectFunction = renderer.getRenderObjectFunction();
 | 
			
		||||
 | 
			
		||||
		renderer.setRenderObjectFunction( ( object, ...params ) => {
 | 
			
		||||
 | 
			
		||||
			if ( object.castShadow === true ) {
 | 
			
		||||
 | 
			
		||||
				renderer.renderObject( object, ...params );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
		renderer.setRenderTarget( rtt );
 | 
			
		||||
		renderer.toneMapping = NoToneMapping;
 | 
			
		||||
 | 
			
		||||
		renderer.render( scene, light.shadow.camera );
 | 
			
		||||
 | 
			
		||||
		renderer.setRenderTarget( currentRenderTarget );
 | 
			
		||||
		renderer.setRenderObjectFunction( currentRenderObjectFunction );
 | 
			
		||||
 | 
			
		||||
		renderer.toneMapping = currentToneMapping;
 | 
			
		||||
 | 
			
		||||
		scene.overrideMaterial = currentOverrideMaterial;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	disposeShadow() {
 | 
			
		||||
 | 
			
		||||
		this.rtt.dispose();
 | 
			
		||||
 | 
			
		||||
		this.shadowNode = null;
 | 
			
		||||
		this.shadowMaskNode = null;
 | 
			
		||||
		this.rtt = null;
 | 
			
		||||
 | 
			
		||||
		this.colorNode = this._defaultColorNode;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	updateBefore( frame ) {
 | 
			
		||||
 | 
			
		||||
		const { light } = this;
 | 
			
		||||
 | 
			
		||||
		if ( light.castShadow ) this.updateShadow( frame );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	update( /*frame*/ ) {
 | 
			
		||||
 | 
			
		||||
		const { light } = this;
 | 
			
		||||
 | 
			
		||||
		this.color.copy( light.color ).multiplyScalar( light.intensity );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AnalyticLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'AnalyticLightNode', AnalyticLightNode );
 | 
			
		||||
							
								
								
									
										41
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/DirectionalLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/DirectionalLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { lightTargetDirection } from './LightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import { DirectionalLight } from 'three';
 | 
			
		||||
 | 
			
		||||
class DirectionalLightNode extends AnalyticLightNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super( light );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		super.setup( builder );
 | 
			
		||||
 | 
			
		||||
		const lightingModel = builder.context.lightingModel;
 | 
			
		||||
 | 
			
		||||
		const lightColor = this.colorNode;
 | 
			
		||||
		const lightDirection = lightTargetDirection( this.light );
 | 
			
		||||
		const reflectedLight = builder.context.reflectedLight;
 | 
			
		||||
 | 
			
		||||
		lightingModel.direct( {
 | 
			
		||||
			lightDirection,
 | 
			
		||||
			lightColor,
 | 
			
		||||
			reflectedLight,
 | 
			
		||||
			shadowMask: this.shadowMaskNode
 | 
			
		||||
		}, builder.stack, builder );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default DirectionalLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'DirectionalLightNode', DirectionalLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( DirectionalLight, DirectionalLightNode );
 | 
			
		||||
							
								
								
									
										133
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/EnvironmentNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/EnvironmentNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,133 @@
 | 
			
		||||
import LightingNode from './LightingNode.js';
 | 
			
		||||
import { cache } from '../core/CacheNode.js';
 | 
			
		||||
import { context } from '../core/ContextNode.js';
 | 
			
		||||
import { roughness, clearcoatRoughness } from '../core/PropertyNode.js';
 | 
			
		||||
import { cameraViewMatrix } from '../accessors/CameraNode.js';
 | 
			
		||||
import { transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld } from '../accessors/NormalNode.js';
 | 
			
		||||
import { positionViewDirection } from '../accessors/PositionNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
import { float } from '../shadernode/ShaderNode.js';
 | 
			
		||||
import { reference } from '../accessors/ReferenceNode.js';
 | 
			
		||||
import { transformedBentNormalView } from '../accessors/AccessorsUtils.js';
 | 
			
		||||
import { pmremTexture } from '../pmrem/PMREMNode.js';
 | 
			
		||||
 | 
			
		||||
const envNodeCache = new WeakMap();
 | 
			
		||||
 | 
			
		||||
class EnvironmentNode extends LightingNode {
 | 
			
		||||
 | 
			
		||||
	constructor( envNode = null ) {
 | 
			
		||||
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this.envNode = envNode;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		let envNode = this.envNode;
 | 
			
		||||
 | 
			
		||||
		if ( envNode.isTextureNode ) {
 | 
			
		||||
 | 
			
		||||
			let cacheEnvNode = envNodeCache.get( envNode.value );
 | 
			
		||||
 | 
			
		||||
			if ( cacheEnvNode === undefined ) {
 | 
			
		||||
 | 
			
		||||
				cacheEnvNode = pmremTexture( envNode.value );
 | 
			
		||||
 | 
			
		||||
				envNodeCache.set( envNode.value, cacheEnvNode );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			envNode	= cacheEnvNode;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		const { material } = builder;
 | 
			
		||||
 | 
			
		||||
		const envMap = material.envMap;
 | 
			
		||||
		const intensity = envMap ? reference( 'envMapIntensity', 'float', builder.material ) : reference( 'environmentIntensity', 'float', builder.scene ); // @TODO: Add materialEnvIntensity in MaterialNode
 | 
			
		||||
 | 
			
		||||
		const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0;
 | 
			
		||||
		const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView;
 | 
			
		||||
 | 
			
		||||
		const radiance = context( envNode, createRadianceContext( roughness, radianceNormalView ) ).mul( intensity );
 | 
			
		||||
		const irradiance = context( envNode, createIrradianceContext( transformedNormalWorld ) ).mul( Math.PI ).mul( intensity );
 | 
			
		||||
 | 
			
		||||
		const isolateRadiance = cache( radiance );
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		builder.context.radiance.addAssign( isolateRadiance );
 | 
			
		||||
 | 
			
		||||
		builder.context.iblIrradiance.addAssign( irradiance );
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance;
 | 
			
		||||
 | 
			
		||||
		if ( clearcoatRadiance ) {
 | 
			
		||||
 | 
			
		||||
			const clearcoatRadianceContext = context( envNode, createRadianceContext( clearcoatRoughness, transformedClearcoatNormalView ) ).mul( intensity );
 | 
			
		||||
			const isolateClearcoatRadiance = cache( clearcoatRadianceContext );
 | 
			
		||||
 | 
			
		||||
			clearcoatRadiance.addAssign( isolateClearcoatRadiance );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const createRadianceContext = ( roughnessNode, normalViewNode ) => {
 | 
			
		||||
 | 
			
		||||
	let reflectVec = null;
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		getUV: () => {
 | 
			
		||||
 | 
			
		||||
			if ( reflectVec === null ) {
 | 
			
		||||
 | 
			
		||||
				reflectVec = positionViewDirection.negate().reflect( normalViewNode );
 | 
			
		||||
 | 
			
		||||
				// Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane.
 | 
			
		||||
				reflectVec = roughnessNode.mul( roughnessNode ).mix( reflectVec, normalViewNode ).normalize();
 | 
			
		||||
 | 
			
		||||
				reflectVec = reflectVec.transformDirection( cameraViewMatrix );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return reflectVec;
 | 
			
		||||
 | 
			
		||||
		},
 | 
			
		||||
		getTextureLevel: () => {
 | 
			
		||||
 | 
			
		||||
			return roughnessNode;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const createIrradianceContext = ( normalWorldNode ) => {
 | 
			
		||||
 | 
			
		||||
	return {
 | 
			
		||||
		getUV: () => {
 | 
			
		||||
 | 
			
		||||
			return normalWorldNode;
 | 
			
		||||
 | 
			
		||||
		},
 | 
			
		||||
		getTextureLevel: () => {
 | 
			
		||||
 | 
			
		||||
			return float( 1.0 );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default EnvironmentNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'EnvironmentNode', EnvironmentNode );
 | 
			
		||||
							
								
								
									
										55
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/HemisphereLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/HemisphereLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { uniform } from '../core/UniformNode.js';
 | 
			
		||||
import { mix } from '../math/MathNode.js';
 | 
			
		||||
import { normalView } from '../accessors/NormalNode.js';
 | 
			
		||||
import { objectPosition } from '../accessors/Object3DNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import { Color, HemisphereLight } from 'three';
 | 
			
		||||
 | 
			
		||||
class HemisphereLightNode extends AnalyticLightNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super( light );
 | 
			
		||||
 | 
			
		||||
		this.lightPositionNode = objectPosition( light );
 | 
			
		||||
		this.lightDirectionNode = this.lightPositionNode.normalize();
 | 
			
		||||
 | 
			
		||||
		this.groundColorNode = uniform( new Color() );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	update( frame ) {
 | 
			
		||||
 | 
			
		||||
		const { light } = this;
 | 
			
		||||
 | 
			
		||||
		super.update( frame );
 | 
			
		||||
 | 
			
		||||
		this.lightPositionNode.object3d = light;
 | 
			
		||||
 | 
			
		||||
		this.groundColorNode.value.copy( light.groundColor ).multiplyScalar( light.intensity );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		const { colorNode, groundColorNode, lightDirectionNode } = this;
 | 
			
		||||
 | 
			
		||||
		const dotNL = normalView.dot( lightDirectionNode );
 | 
			
		||||
		const hemiDiffuseWeight = dotNL.mul( 0.5 ).add( 0.5 );
 | 
			
		||||
 | 
			
		||||
		const irradiance = mix( groundColorNode, colorNode, hemiDiffuseWeight );
 | 
			
		||||
 | 
			
		||||
		builder.context.irradiance.addAssign( irradiance );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default HemisphereLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'HemisphereLightNode', HemisphereLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( HemisphereLight, HemisphereLightNode );
 | 
			
		||||
							
								
								
									
										39
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/IESSpotLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/IESSpotLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
import SpotLightNode from './SpotLightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { texture } from '../accessors/TextureNode.js';
 | 
			
		||||
import { vec2 } from '../shadernode/ShaderNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import IESSpotLight from '../../lights/IESSpotLight.js';
 | 
			
		||||
 | 
			
		||||
class IESSpotLightNode extends SpotLightNode {
 | 
			
		||||
 | 
			
		||||
	getSpotAttenuation( angleCosine ) {
 | 
			
		||||
 | 
			
		||||
		const iesMap = this.light.iesMap;
 | 
			
		||||
 | 
			
		||||
		let spotAttenuation = null;
 | 
			
		||||
 | 
			
		||||
		if ( iesMap && iesMap.isTexture === true ) {
 | 
			
		||||
 | 
			
		||||
			const angle = angleCosine.acos().mul( 1.0 / Math.PI );
 | 
			
		||||
 | 
			
		||||
			spotAttenuation = texture( iesMap, vec2( angle, 0 ), 0 ).r;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			spotAttenuation = super.getSpotAttenuation( angleCosine );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return spotAttenuation;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default IESSpotLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'IESSpotLightNode', IESSpotLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( IESSpotLight, IESSpotLightNode );
 | 
			
		||||
							
								
								
									
										24
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/IrradianceNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/IrradianceNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
import LightingNode from './LightingNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
class IrradianceNode extends LightingNode {
 | 
			
		||||
 | 
			
		||||
	constructor( node ) {
 | 
			
		||||
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this.node = node;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		builder.context.irradiance.addAssign( this.node );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default IrradianceNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'IrradianceNode', IrradianceNode );
 | 
			
		||||
							
								
								
									
										57
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
			
		||||
import Node, { addNodeClass } from '../core/Node.js';
 | 
			
		||||
import { nodeProxy } from '../shadernode/ShaderNode.js';
 | 
			
		||||
import { objectPosition } from '../accessors/Object3DNode.js';
 | 
			
		||||
import { cameraViewMatrix } from '../accessors/CameraNode.js';
 | 
			
		||||
 | 
			
		||||
class LightNode extends Node {
 | 
			
		||||
 | 
			
		||||
	constructor( scope = LightNode.TARGET_DIRECTION, light = null ) {
 | 
			
		||||
 | 
			
		||||
		super();
 | 
			
		||||
 | 
			
		||||
		this.scope = scope;
 | 
			
		||||
		this.light = light;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup() {
 | 
			
		||||
 | 
			
		||||
		const { scope, light } = this;
 | 
			
		||||
 | 
			
		||||
		let output = null;
 | 
			
		||||
 | 
			
		||||
		if ( scope === LightNode.TARGET_DIRECTION ) {
 | 
			
		||||
 | 
			
		||||
			output = cameraViewMatrix.transformDirection( objectPosition( light ).sub( objectPosition( light.target ) ) );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return output;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	serialize( data ) {
 | 
			
		||||
 | 
			
		||||
		super.serialize( data );
 | 
			
		||||
 | 
			
		||||
		data.scope = this.scope;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deserialize( data ) {
 | 
			
		||||
 | 
			
		||||
		super.deserialize( data );
 | 
			
		||||
 | 
			
		||||
		this.scope = data.scope;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LightNode.TARGET_DIRECTION = 'targetDirection';
 | 
			
		||||
 | 
			
		||||
export default LightNode;
 | 
			
		||||
 | 
			
		||||
export const lightTargetDirection = nodeProxy( LightNode, LightNode.TARGET_DIRECTION );
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'LightNode', LightNode );
 | 
			
		||||
							
								
								
									
										17
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightUtils.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
import { tslFn } from '../shadernode/ShaderNode.js';
 | 
			
		||||
 | 
			
		||||
export const getDistanceAttenuation = tslFn( ( inputs ) => {
 | 
			
		||||
 | 
			
		||||
	const { lightDistance, cutoffDistance, decayExponent } = inputs;
 | 
			
		||||
 | 
			
		||||
	// based upon Frostbite 3 Moving to Physically-based Rendering
 | 
			
		||||
	// page 32, equation 26: E[window1]
 | 
			
		||||
	// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf
 | 
			
		||||
	const distanceFalloff = lightDistance.pow( decayExponent ).max( 0.01 ).reciprocal();
 | 
			
		||||
 | 
			
		||||
	return cutoffDistance.greaterThan( 0 ).cond(
 | 
			
		||||
		distanceFalloff.mul( lightDistance.div( cutoffDistance ).pow4().oneMinus().clamp().pow2() ),
 | 
			
		||||
		distanceFalloff
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
} ); // validated
 | 
			
		||||
							
								
								
									
										66
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightingContextNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightingContextNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,66 @@
 | 
			
		||||
import ContextNode from '../core/ContextNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
import { addNodeElement, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js';
 | 
			
		||||
 | 
			
		||||
class LightingContextNode extends ContextNode {
 | 
			
		||||
 | 
			
		||||
	constructor( node, lightingModel = null, backdropNode = null, backdropAlphaNode = null ) {
 | 
			
		||||
 | 
			
		||||
		super( node );
 | 
			
		||||
 | 
			
		||||
		this.lightingModel = lightingModel;
 | 
			
		||||
		this.backdropNode = backdropNode;
 | 
			
		||||
		this.backdropAlphaNode = backdropAlphaNode;
 | 
			
		||||
 | 
			
		||||
		this._context = null;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getContext() {
 | 
			
		||||
 | 
			
		||||
		const { backdropNode, backdropAlphaNode } = this;
 | 
			
		||||
 | 
			
		||||
		const directDiffuse = vec3().temp( 'directDiffuse' ),
 | 
			
		||||
			directSpecular = vec3().temp( 'directSpecular' ),
 | 
			
		||||
			indirectDiffuse = vec3().temp( 'indirectDiffuse' ),
 | 
			
		||||
			indirectSpecular = vec3().temp( 'indirectSpecular' );
 | 
			
		||||
 | 
			
		||||
		const reflectedLight = {
 | 
			
		||||
			directDiffuse,
 | 
			
		||||
			directSpecular,
 | 
			
		||||
			indirectDiffuse,
 | 
			
		||||
			indirectSpecular
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		const context = {
 | 
			
		||||
			radiance: vec3().temp( 'radiance' ),
 | 
			
		||||
			irradiance: vec3().temp( 'irradiance' ),
 | 
			
		||||
			iblIrradiance: vec3().temp( 'iblIrradiance' ),
 | 
			
		||||
			ambientOcclusion: float( 1 ).temp( 'ambientOcclusion' ),
 | 
			
		||||
			reflectedLight,
 | 
			
		||||
			backdrop: backdropNode,
 | 
			
		||||
			backdropAlpha: backdropAlphaNode
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		return context;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		this.context = this._context || ( this._context = this.getContext() );
 | 
			
		||||
		this.context.lightingModel = this.lightingModel || builder.context.lightingModel;
 | 
			
		||||
 | 
			
		||||
		return super.setup( builder );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default LightingContextNode;
 | 
			
		||||
 | 
			
		||||
export const lightingContext = nodeProxy( LightingContextNode );
 | 
			
		||||
 | 
			
		||||
addNodeElement( 'lightingContext', lightingContext );
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'LightingContextNode', LightingContextNode );
 | 
			
		||||
							
								
								
									
										21
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightingNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightingNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
import Node, { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
class LightingNode extends Node {
 | 
			
		||||
 | 
			
		||||
	constructor() {
 | 
			
		||||
 | 
			
		||||
		super( 'vec3' );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	generate( /*builder*/ ) {
 | 
			
		||||
 | 
			
		||||
		console.warn( 'Abstract function.' );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default LightingNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'LightingNode', LightingNode );
 | 
			
		||||
							
								
								
									
										198
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightsNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/LightsNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,198 @@
 | 
			
		||||
import Node from '../core/Node.js';
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { nodeObject, nodeProxy, vec3 } from '../shadernode/ShaderNode.js';
 | 
			
		||||
 | 
			
		||||
const LightNodes = new WeakMap();
 | 
			
		||||
 | 
			
		||||
const sortLights = ( lights ) => {
 | 
			
		||||
 | 
			
		||||
	return lights.sort( ( a, b ) => a.id - b.id );
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LightsNode extends Node {
 | 
			
		||||
 | 
			
		||||
	constructor( lightNodes = [] ) {
 | 
			
		||||
 | 
			
		||||
		super( 'vec3' );
 | 
			
		||||
 | 
			
		||||
		this.totalDiffuseNode = vec3().temp( 'totalDiffuse' );
 | 
			
		||||
		this.totalSpecularNode = vec3().temp( 'totalSpecular' );
 | 
			
		||||
 | 
			
		||||
		this.outgoingLightNode = vec3().temp( 'outgoingLight' );
 | 
			
		||||
 | 
			
		||||
		this.lightNodes = lightNodes;
 | 
			
		||||
 | 
			
		||||
		this._hash = null;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	get hasLight() {
 | 
			
		||||
 | 
			
		||||
		return this.lightNodes.length > 0;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getHash() {
 | 
			
		||||
 | 
			
		||||
		if ( this._hash === null ) {
 | 
			
		||||
 | 
			
		||||
			const hash = [];
 | 
			
		||||
 | 
			
		||||
			for ( const lightNode of this.lightNodes ) {
 | 
			
		||||
 | 
			
		||||
				hash.push( lightNode.getHash() );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this._hash = 'lights-' + hash.join( ',' );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return this._hash;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		const context = builder.context;
 | 
			
		||||
		const lightingModel = context.lightingModel;
 | 
			
		||||
 | 
			
		||||
		let outgoingLightNode = this.outgoingLightNode;
 | 
			
		||||
 | 
			
		||||
		if ( lightingModel ) {
 | 
			
		||||
 | 
			
		||||
			const { lightNodes, totalDiffuseNode, totalSpecularNode } = this;
 | 
			
		||||
 | 
			
		||||
			context.outgoingLight = outgoingLightNode;
 | 
			
		||||
 | 
			
		||||
			const stack = builder.addStack();
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			lightingModel.start( context, stack, builder );
 | 
			
		||||
 | 
			
		||||
			// lights
 | 
			
		||||
 | 
			
		||||
			for ( const lightNode of lightNodes ) {
 | 
			
		||||
 | 
			
		||||
				lightNode.build( builder );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			lightingModel.indirectDiffuse( context, stack, builder );
 | 
			
		||||
			lightingModel.indirectSpecular( context, stack, builder );
 | 
			
		||||
			lightingModel.ambientOcclusion( context, stack, builder );
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			const { backdrop, backdropAlpha } = context;
 | 
			
		||||
			const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight;
 | 
			
		||||
 | 
			
		||||
			let totalDiffuse = directDiffuse.add( indirectDiffuse );
 | 
			
		||||
 | 
			
		||||
			if ( backdrop !== null ) {
 | 
			
		||||
 | 
			
		||||
				if ( backdropAlpha !== null ) {
 | 
			
		||||
 | 
			
		||||
					totalDiffuse = vec3( backdropAlpha.mix( totalDiffuse, backdrop ) );
 | 
			
		||||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					totalDiffuse = vec3( backdrop );
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				context.material.transparent = true;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			totalDiffuseNode.assign( totalDiffuse );
 | 
			
		||||
			totalSpecularNode.assign( directSpecular.add( indirectSpecular ) );
 | 
			
		||||
 | 
			
		||||
			outgoingLightNode.assign( totalDiffuseNode.add( totalSpecularNode ) );
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			lightingModel.finish( context, stack, builder );
 | 
			
		||||
 | 
			
		||||
			//
 | 
			
		||||
 | 
			
		||||
			outgoingLightNode = outgoingLightNode.bypass( builder.removeStack() );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return outgoingLightNode;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_getLightNodeById( id ) {
 | 
			
		||||
 | 
			
		||||
		for ( const lightNode of this.lightNodes ) {
 | 
			
		||||
 | 
			
		||||
			if ( lightNode.isAnalyticLightNode && lightNode.light.id === id ) {
 | 
			
		||||
 | 
			
		||||
				return lightNode;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return null;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fromLights( lights = [] ) {
 | 
			
		||||
 | 
			
		||||
		const lightNodes = [];
 | 
			
		||||
 | 
			
		||||
		lights = sortLights( lights );
 | 
			
		||||
 | 
			
		||||
		for ( const light of lights ) {
 | 
			
		||||
 | 
			
		||||
			let lightNode = this._getLightNodeById( light.id );
 | 
			
		||||
 | 
			
		||||
			if ( lightNode === null ) {
 | 
			
		||||
 | 
			
		||||
				const lightClass = light.constructor;
 | 
			
		||||
				const lightNodeClass = LightNodes.has( lightClass ) ? LightNodes.get( lightClass ) : AnalyticLightNode;
 | 
			
		||||
 | 
			
		||||
				lightNode = nodeObject( new lightNodeClass( light ) );
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			lightNodes.push( lightNode );
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.lightNodes = lightNodes;
 | 
			
		||||
		this._hash = null;
 | 
			
		||||
 | 
			
		||||
		return this;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default LightsNode;
 | 
			
		||||
 | 
			
		||||
export const lights = ( lights ) => nodeObject( new LightsNode().fromLights( lights ) );
 | 
			
		||||
export const lightsNode = nodeProxy( LightsNode );
 | 
			
		||||
 | 
			
		||||
export function addLightNode( lightClass, lightNodeClass ) {
 | 
			
		||||
 | 
			
		||||
	if ( LightNodes.has( lightClass ) ) {
 | 
			
		||||
 | 
			
		||||
		console.warn( `Redefinition of light node ${ lightNodeClass.type }` );
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ( typeof lightClass !== 'function' ) throw new Error( `Light ${ lightClass.name } is not a class` );
 | 
			
		||||
	if ( typeof lightNodeClass !== 'function' || ! lightNodeClass.type ) throw new Error( `Light node ${ lightNodeClass.type } is not a class` );
 | 
			
		||||
 | 
			
		||||
	LightNodes.set( lightClass, lightNodeClass );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/PointLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/PointLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { getDistanceAttenuation } from './LightUtils.js';
 | 
			
		||||
import { uniform } from '../core/UniformNode.js';
 | 
			
		||||
import { objectViewPosition } from '../accessors/Object3DNode.js';
 | 
			
		||||
import { positionView } from '../accessors/PositionNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import { PointLight } from 'three';
 | 
			
		||||
 | 
			
		||||
class PointLightNode extends AnalyticLightNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super( light );
 | 
			
		||||
 | 
			
		||||
		this.cutoffDistanceNode = uniform( 0 );
 | 
			
		||||
		this.decayExponentNode = uniform( 0 );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	update( frame ) {
 | 
			
		||||
 | 
			
		||||
		const { light } = this;
 | 
			
		||||
 | 
			
		||||
		super.update( frame );
 | 
			
		||||
 | 
			
		||||
		this.cutoffDistanceNode.value = light.distance;
 | 
			
		||||
		this.decayExponentNode.value = light.decay;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		const { colorNode, cutoffDistanceNode, decayExponentNode, light } = this;
 | 
			
		||||
 | 
			
		||||
		const lightingModel = builder.context.lightingModel;
 | 
			
		||||
 | 
			
		||||
		const lVector = objectViewPosition( light ).sub( positionView ); // @TODO: Add it into LightNode
 | 
			
		||||
 | 
			
		||||
		const lightDirection = lVector.normalize();
 | 
			
		||||
		const lightDistance = lVector.length();
 | 
			
		||||
 | 
			
		||||
		const lightAttenuation = getDistanceAttenuation( {
 | 
			
		||||
			lightDistance,
 | 
			
		||||
			cutoffDistance: cutoffDistanceNode,
 | 
			
		||||
			decayExponent: decayExponentNode
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
		const lightColor = colorNode.mul( lightAttenuation );
 | 
			
		||||
 | 
			
		||||
		const reflectedLight = builder.context.reflectedLight;
 | 
			
		||||
 | 
			
		||||
		lightingModel.direct( {
 | 
			
		||||
			lightDirection,
 | 
			
		||||
			lightColor,
 | 
			
		||||
			reflectedLight,
 | 
			
		||||
			shadowMask: this.shadowMaskNode
 | 
			
		||||
		}, builder.stack, builder );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default PointLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'PointLightNode', PointLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( PointLight, PointLightNode );
 | 
			
		||||
							
								
								
									
										90
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/SpotLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								dist/electron/static/sdk/three/jsm/nodes/lighting/SpotLightNode.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,90 @@
 | 
			
		||||
import AnalyticLightNode from './AnalyticLightNode.js';
 | 
			
		||||
import { lightTargetDirection } from './LightNode.js';
 | 
			
		||||
import { addLightNode } from './LightsNode.js';
 | 
			
		||||
import { getDistanceAttenuation } from './LightUtils.js';
 | 
			
		||||
import { uniform } from '../core/UniformNode.js';
 | 
			
		||||
import { smoothstep } from '../math/MathNode.js';
 | 
			
		||||
import { objectViewPosition } from '../accessors/Object3DNode.js';
 | 
			
		||||
import { positionView } from '../accessors/PositionNode.js';
 | 
			
		||||
import { addNodeClass } from '../core/Node.js';
 | 
			
		||||
 | 
			
		||||
import { SpotLight } from 'three';
 | 
			
		||||
 | 
			
		||||
class SpotLightNode extends AnalyticLightNode {
 | 
			
		||||
 | 
			
		||||
	constructor( light = null ) {
 | 
			
		||||
 | 
			
		||||
		super( light );
 | 
			
		||||
 | 
			
		||||
		this.coneCosNode = uniform( 0 );
 | 
			
		||||
		this.penumbraCosNode = uniform( 0 );
 | 
			
		||||
 | 
			
		||||
		this.cutoffDistanceNode = uniform( 0 );
 | 
			
		||||
		this.decayExponentNode = uniform( 0 );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	update( frame ) {
 | 
			
		||||
 | 
			
		||||
		super.update( frame );
 | 
			
		||||
 | 
			
		||||
		const { light } = this;
 | 
			
		||||
 | 
			
		||||
		this.coneCosNode.value = Math.cos( light.angle );
 | 
			
		||||
		this.penumbraCosNode.value = Math.cos( light.angle * ( 1 - light.penumbra ) );
 | 
			
		||||
 | 
			
		||||
		this.cutoffDistanceNode.value = light.distance;
 | 
			
		||||
		this.decayExponentNode.value = light.decay;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	getSpotAttenuation( angleCosine ) {
 | 
			
		||||
 | 
			
		||||
		const { coneCosNode, penumbraCosNode } = this;
 | 
			
		||||
 | 
			
		||||
		return smoothstep( coneCosNode, penumbraCosNode, angleCosine );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	setup( builder ) {
 | 
			
		||||
 | 
			
		||||
		super.setup( builder );
 | 
			
		||||
 | 
			
		||||
		const lightingModel = builder.context.lightingModel;
 | 
			
		||||
 | 
			
		||||
		const { colorNode, cutoffDistanceNode, decayExponentNode, light } = this;
 | 
			
		||||
 | 
			
		||||
		const lVector = objectViewPosition( light ).sub( positionView ); // @TODO: Add it into LightNode
 | 
			
		||||
 | 
			
		||||
		const lightDirection = lVector.normalize();
 | 
			
		||||
		const angleCos = lightDirection.dot( lightTargetDirection( light ) );
 | 
			
		||||
		const spotAttenuation = this.getSpotAttenuation( angleCos );
 | 
			
		||||
 | 
			
		||||
		const lightDistance = lVector.length();
 | 
			
		||||
 | 
			
		||||
		const lightAttenuation = getDistanceAttenuation( {
 | 
			
		||||
			lightDistance,
 | 
			
		||||
			cutoffDistance: cutoffDistanceNode,
 | 
			
		||||
			decayExponent: decayExponentNode
 | 
			
		||||
		} );
 | 
			
		||||
 | 
			
		||||
		const lightColor = colorNode.mul( spotAttenuation ).mul( lightAttenuation );
 | 
			
		||||
 | 
			
		||||
		const reflectedLight = builder.context.reflectedLight;
 | 
			
		||||
 | 
			
		||||
		lightingModel.direct( {
 | 
			
		||||
			lightDirection,
 | 
			
		||||
			lightColor,
 | 
			
		||||
			reflectedLight,
 | 
			
		||||
			shadowMask: this.shadowMaskNode
 | 
			
		||||
		}, builder.stack, builder );
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default SpotLightNode;
 | 
			
		||||
 | 
			
		||||
addNodeClass( 'SpotLightNode', SpotLightNode );
 | 
			
		||||
 | 
			
		||||
addLightNode( SpotLight, SpotLightNode );
 | 
			
		||||
		Reference in New Issue
	
	Block a user