123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import LightingNode from './LightingNode.js';
- import { NodeUpdateType } from '../core/constants.js';
- import { uniform } from '../core/UniformNode.js';
- import { addNodeClass } from '../core/Node.js';
- import { vec3 } from '../shadernode/ShaderNode.js';
- import { reference } from '../accessors/ReferenceNode.js';
- import { texture } from '../accessors/TextureNode.js';
- import { positionWorld } from '../accessors/PositionNode.js';
- import { cond } from '../math/CondNode.js';
- import MeshBasicNodeMaterial from '../materials/MeshBasicNodeMaterial.js';
- import { Color, DepthTexture, NearestFilter } from 'three';
- let depthMaterial = null;
- class AnalyticLightNode extends LightingNode {
- constructor( light = null ) {
- super();
- this.updateType = NodeUpdateType.FRAME;
- this.light = light;
- this.rtt = null;
- this.shadowNode = null;
- this.color = new Color();
- this.colorNode = uniform( this.color );
- }
- getHash( /*builder*/ ) {
- return this.light.uuid;
- }
- constructShadow( builder ) {
- let shadowNode = this.shadowNode;
- if ( shadowNode === null ) {
- if ( depthMaterial === null ) depthMaterial = new MeshBasicNodeMaterial();
- const shadow = this.light.shadow;
- const rtt = builder.getRenderTarget( shadow.mapSize.width, shadow.mapSize.height );
- const depthTexture = new DepthTexture();
- depthTexture.minFilter = NearestFilter;
- depthTexture.magFilter = NearestFilter;
- rtt.depthTexture = depthTexture;
- shadow.camera.updateProjectionMatrix();
- //
- const bias = reference( 'bias', 'float', shadow );
- //const diffuseFactor = normalView.dot( objectViewPosition( this.light ).sub( positionView ).normalize().negate() );
- //bias = mix( bias, 0, diffuseFactor );
- let shadowCoord = uniform( shadow.matrix ).mul( positionWorld );
- shadowCoord = shadowCoord.xyz.div( shadowCoord.w );
- shadowCoord = vec3(
- shadowCoord.x,
- shadowCoord.y.oneMinus(),
- shadowCoord.z
- );
- // @TODO: Optimize using WebGPU compare-sampler
- let depth = texture( depthTexture, shadowCoord.xy );
- depth = depth.mul( .5 ).add( .5 ).add( bias );
- shadowNode = cond( shadowCoord.z.lessThan( depth ).or( shadowCoord.y.lessThan( .000001 ) /*@TODO: find the cause and remove it soon */ ), 1, 0 );
- //shadowNode = step( shadowCoord.z, depth );
- //
- this.rtt = rtt;
- this.colorNode = this.colorNode.mul( shadowNode );
- this.shadowNode = shadowNode;
- //
- this.updateBeforeType = NodeUpdateType.RENDER;
- }
- }
- construct( builder ) {
- if ( this.light.castShadow ) this.constructShadow( builder );
- }
- updateShadow( frame ) {
- const { rtt, light } = this;
- const { renderer, scene } = frame;
- scene.overrideMaterial = depthMaterial;
- rtt.setSize( light.shadow.mapSize.width, light.shadow.mapSize.height );
- light.shadow.updateMatrices( light );
- renderer.setRenderTarget( rtt );
- renderer.render( scene, light.shadow.camera );
- renderer.setRenderTarget( null );
- scene.overrideMaterial = null;
- }
- 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 );
|