import * as React from "react"; import { Observable } from "babylonjs/Misc/observable"; import { IShadowLight } from "babylonjs/Lights/shadowLight"; import { PropertyChangedEvent } from "../../../../propertyChangedEvent"; import { LineContainerComponent } from "../../../lineContainerComponent"; import { CheckBoxLineComponent } from "../../../../../sharedUiComponents/lines/checkBoxLineComponent"; import { FloatLineComponent } from "../../../../../sharedUiComponents/lines/floatLineComponent"; import { LockObject } from "../../../../../sharedUiComponents/tabs/propertyGrids/lockObject"; import { GlobalState } from '../../../../globalState'; import { OptionsLineComponent } from '../../../../../sharedUiComponents/lines/optionsLineComponent'; import { ShadowGenerator } from 'babylonjs/Lights/Shadows/shadowGenerator'; import { CascadedShadowGenerator } from 'babylonjs/Lights/Shadows/cascadedShadowGenerator'; import { SliderLineComponent } from '../../../../../sharedUiComponents/lines/sliderLineComponent'; import { ButtonLineComponent } from '../../../../../sharedUiComponents/lines/buttonLineComponent'; import { DirectionalLight } from 'babylonjs/Lights/directionalLight'; interface ICommonShadowLightPropertyGridComponentProps { globalState: GlobalState; light: IShadowLight; lockObject: LockObject; onPropertyChangedObservable?: Observable; } export class CommonShadowLightPropertyGridComponent extends React.Component { private _internals : { generatorType: number, mapSize: number }; constructor(props: ICommonShadowLightPropertyGridComponentProps) { super(props); this._internals = { generatorType: 0, mapSize: 1024, }; } createShadowGenerator() { const light = this.props.light; const scene = light.getScene(); const internals = this._internals; let generator = internals.generatorType === 0 ? new ShadowGenerator(internals.mapSize, light) : new CascadedShadowGenerator(internals.mapSize, light as DirectionalLight); scene.meshes.forEach((m) => { if (m.infiniteDistance) { return; } generator.addShadowCaster(m); if (!m.isAnInstance) { m.receiveShadows = true; } }); this.forceUpdate(); } disposeShadowGenerator() { const light = this.props.light; light.getShadowGenerator()?.dispose(); this.forceUpdate(); } render() { const light = this.props.light; const internals = this._internals; const generator = light.getShadowGenerator() as (ShadowGenerator | CascadedShadowGenerator) || null; const csmGenerator = generator instanceof CascadedShadowGenerator; const camera = light.getScene().activeCamera; var typeGeneratorOptions = [ { label: "Shadow Generator", value: 0 } ]; if (light instanceof DirectionalLight) { typeGeneratorOptions.push({ label: "Cascaded Shadow Generator", value: 1 }); } var mapSizeOptions = [ { label: "2048x2048", value: 2048 }, { label: "1024x1024", value: 1024 }, { label: "512x512", value: 512 }, { label: "256x256", value: 256 }, ]; var blurModeOptions; if (generator instanceof CascadedShadowGenerator) { blurModeOptions = [ { label: "None", value: ShadowGenerator.FILTER_NONE }, { label: "PCF", value: ShadowGenerator.FILTER_PCF }, { label: "PCSS", value: ShadowGenerator.FILTER_PCSS }, ]; } else { blurModeOptions = [ { label: "None", value: ShadowGenerator.FILTER_NONE }, { label: "PCF", value: ShadowGenerator.FILTER_PCF }, { label: "PCSS", value: ShadowGenerator.FILTER_PCSS }, { label: "Poisson", value: ShadowGenerator.FILTER_POISSONSAMPLING }, { label: "Exponential", value: ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP }, { label: "Blurred exponential", value: ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP }, { label: "Close exponential", value: ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP }, { label: "Blurred close exponential", value: ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP }, ]; } var filteringQualityOptions = [ { label: "Low", value: ShadowGenerator.QUALITY_LOW }, { label: "Medium", value: ShadowGenerator.QUALITY_MEDIUM }, { label: "High", value: ShadowGenerator.QUALITY_HIGH }, ]; var numCascadesOptions = [ { label: "2", value: 2 }, { label: "3", value: 3 }, { label: "4", value: 4 }, ]; const near = camera ? camera.minZ : 0, far = camera ? camera.maxZ : 0; let filter = generator ? generator.filter : 0; return (
{ !csmGenerator && <> } { generator == null && this.createShadowGenerator()} /> } { generator !== null && this.disposeShadowGenerator()} /> { csmGenerator && <> } { this.forceUpdate(); }} target={generator} propertyName="filter" onPropertyChangedObservable={this.props.onPropertyChangedObservable} /> { (filter === ShadowGenerator.FILTER_PCF || filter === ShadowGenerator.FILTER_PCSS) && { this.forceUpdate(); }} target={generator} propertyName="filteringQuality" onPropertyChangedObservable={this.props.onPropertyChangedObservable} /> } { (filter === ShadowGenerator.FILTER_PCSS) && } { !csmGenerator && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) && this.forceUpdate()} onPropertyChangedObservable={this.props.onPropertyChangedObservable} /> } { (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) && !generator.useKernelBlur && } { (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) && generator.useKernelBlur && } { (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) && } { (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) && } { csmGenerator && (filter === ShadowGenerator.FILTER_PCSS) && } }
); } }