commonShadowLightPropertyGridComponent.tsx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { IShadowLight } from "babylonjs/Lights/shadowLight";
  4. import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
  5. import { LineContainerComponent } from "../../../lineContainerComponent";
  6. import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
  7. import { FloatLineComponent } from "../../../lines/floatLineComponent";
  8. import { LockObject } from "../lockObject";
  9. import { GlobalState } from '../../../../globalState';
  10. import { OptionsLineComponent } from '../../../lines/optionsLineComponent';
  11. import { ShadowGenerator } from 'babylonjs/Lights/Shadows/shadowGenerator';
  12. import { CascadedShadowGenerator } from 'babylonjs/Lights/Shadows/cascadedShadowGenerator';
  13. import { SliderLineComponent } from '../../../lines/sliderLineComponent';
  14. import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
  15. import { DirectionalLight } from 'babylonjs/Lights/directionalLight';
  16. interface ICommonShadowLightPropertyGridComponentProps {
  17. globalState: GlobalState;
  18. light: IShadowLight;
  19. lockObject: LockObject;
  20. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  21. }
  22. export class CommonShadowLightPropertyGridComponent extends React.Component<ICommonShadowLightPropertyGridComponentProps> {
  23. private _internals : { generatorType: number, mapSize: number };
  24. constructor(props: ICommonShadowLightPropertyGridComponentProps) {
  25. super(props);
  26. this._internals = {
  27. generatorType: 0,
  28. mapSize: 1024,
  29. };
  30. }
  31. createShadowGenerator() {
  32. const light = this.props.light;
  33. const scene = light.getScene();
  34. const internals = this._internals;
  35. let generator = internals.generatorType === 0 ? new ShadowGenerator(internals.mapSize, light) : new CascadedShadowGenerator(internals.mapSize, light as DirectionalLight);
  36. scene.meshes.forEach((m) => {
  37. generator.addShadowCaster(m);
  38. if (!m.isAnInstance) {
  39. m.receiveShadows = true;
  40. }
  41. });
  42. this.forceUpdate();
  43. }
  44. disposeShadowGenerator() {
  45. const light = this.props.light;
  46. light.getShadowGenerator()?.dispose();
  47. this.forceUpdate();
  48. }
  49. render() {
  50. const light = this.props.light;
  51. const internals = this._internals;
  52. const generator = light.getShadowGenerator() as (ShadowGenerator | CascadedShadowGenerator) || null;
  53. const csmGenerator = generator instanceof CascadedShadowGenerator;
  54. const camera = light.getScene().activeCamera;
  55. var typeGeneratorOptions = [
  56. { label: "Shadow Generator", value: 0 }
  57. ];
  58. if (light instanceof DirectionalLight) {
  59. typeGeneratorOptions.push({ label: "Cascaded Shadow Generator", value: 1 });
  60. }
  61. var mapSizeOptions = [
  62. { label: "2048x2048", value: 2048 },
  63. { label: "1024x1024", value: 1024 },
  64. { label: "512x512", value: 512 },
  65. { label: "256x256", value: 256 },
  66. ];
  67. var blurModeOptions;
  68. if (generator instanceof CascadedShadowGenerator) {
  69. blurModeOptions = [
  70. { label: "None", value: ShadowGenerator.FILTER_NONE },
  71. { label: "PCF", value: ShadowGenerator.FILTER_PCF },
  72. { label: "PCSS", value: ShadowGenerator.FILTER_PCSS },
  73. ];
  74. } else {
  75. blurModeOptions = [
  76. { label: "None", value: ShadowGenerator.FILTER_NONE },
  77. { label: "PCF", value: ShadowGenerator.FILTER_PCF },
  78. { label: "PCSS", value: ShadowGenerator.FILTER_PCSS },
  79. { label: "Poisson", value: ShadowGenerator.FILTER_POISSONSAMPLING },
  80. { label: "Exponential", value: ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP },
  81. { label: "Blurred exponential", value: ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP },
  82. { label: "Close exponential", value: ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP },
  83. { label: "Blurred close exponential", value: ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP },
  84. ];
  85. }
  86. var filteringQualityOptions = [
  87. { label: "Low", value: ShadowGenerator.QUALITY_LOW },
  88. { label: "Medium", value: ShadowGenerator.QUALITY_MEDIUM },
  89. { label: "High", value: ShadowGenerator.QUALITY_HIGH },
  90. ];
  91. var numCascadesOptions = [
  92. { label: "2", value: 2 },
  93. { label: "3", value: 3 },
  94. { label: "4", value: 4 },
  95. ];
  96. const near = camera ? camera.minZ : 0, far = camera ? camera.maxZ : 0;
  97. let filter = generator ? generator.filter : 0;
  98. return (
  99. <div>
  100. <LineContainerComponent globalState={this.props.globalState} title="SHADOWS">
  101. <CheckBoxLineComponent label="Shadows enabled" target={light} propertyName="shadowEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  102. { !csmGenerator && <>
  103. <FloatLineComponent lockObject={this.props.lockObject} label="Shadows near plane" target={light} propertyName="shadowMinZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  104. <FloatLineComponent lockObject={this.props.lockObject} label="Shadows far plane" target={light} propertyName="shadowMaxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  105. </> }
  106. </LineContainerComponent>
  107. {
  108. generator == null &&
  109. <LineContainerComponent globalState={this.props.globalState} title="SHADOW GENERATOR">
  110. <OptionsLineComponent label="Type" options={typeGeneratorOptions} target={internals} propertyName="generatorType" />
  111. <OptionsLineComponent label="Map size" options={mapSizeOptions} target={internals} propertyName="mapSize" />
  112. <ButtonLineComponent label="Create generator" onClick={() => this.createShadowGenerator()} />
  113. </LineContainerComponent>
  114. }
  115. {
  116. generator !== null &&
  117. <LineContainerComponent globalState={this.props.globalState} title="SHADOW GENERATOR">
  118. <ButtonLineComponent label="Dispose generator" onClick={() => this.disposeShadowGenerator()} />
  119. { csmGenerator && <>
  120. <OptionsLineComponent label="Num cascades" options={numCascadesOptions} target={generator} propertyName="numCascades" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  121. <CheckBoxLineComponent label="Debug mode" target={generator} propertyName="debug" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  122. <CheckBoxLineComponent label="Stabilize cascades" target={generator} propertyName="stabilizeCascades" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  123. <SliderLineComponent label="Lambda" minimum={0} maximum={1.0} step={0.01} target={generator} propertyName="lambda" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  124. <SliderLineComponent label="Cascade blend" minimum={0} maximum={1.0} step={0.01} target={generator} propertyName="cascadeBlendPercentage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  125. <CheckBoxLineComponent label="Depth clamp" target={generator} propertyName="depthClamp" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  126. <CheckBoxLineComponent label="Auto-Calc depth bounds" target={generator} propertyName="autoCalcDepthBounds" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  127. <SliderLineComponent label="Shadow MaxZ" minimum={near} maximum={far} step={0.5} target={generator} propertyName="shadowMaxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  128. </> }
  129. <FloatLineComponent lockObject={this.props.lockObject} digits={4} step="0.0001" label="Bias" target={generator} propertyName="bias" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  130. <FloatLineComponent lockObject={this.props.lockObject} label="Normal bias" target={generator} propertyName="normalBias" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  131. <SliderLineComponent label="Darkness" target={generator} minimum={0} maximum={1} step={0.01} propertyName="darkness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  132. <CheckBoxLineComponent label="Allow transparent shadows" target={generator} propertyName="transparencyShadow" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  133. <OptionsLineComponent label="Filter" options={blurModeOptions}
  134. onSelect={() => {
  135. this.forceUpdate();
  136. }}
  137. target={generator} propertyName="filter" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  138. {
  139. (filter === ShadowGenerator.FILTER_PCF || filter === ShadowGenerator.FILTER_PCSS) &&
  140. <OptionsLineComponent label="Filtering quality" options={filteringQualityOptions}
  141. onSelect={() => {
  142. this.forceUpdate();
  143. }}
  144. target={generator} propertyName="filteringQuality" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  145. }
  146. {
  147. (filter === ShadowGenerator.FILTER_PCSS) &&
  148. <SliderLineComponent label="Penumbra ratio" minimum={0} maximum={0.5} step={0.001} target={generator} propertyName="contactHardeningLightSizeUVRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  149. }
  150. {
  151. !csmGenerator && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
  152. <CheckBoxLineComponent label="Use kernel blur" target={generator} propertyName="useKernelBlur"
  153. onValueChanged={() => this.forceUpdate()}
  154. onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  155. }
  156. {
  157. (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
  158. !generator.useKernelBlur &&
  159. <SliderLineComponent label="Blur box offset" target={generator} propertyName="blurBoxOffset" minimum={1} maximum={64} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />}
  160. {
  161. (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) &&
  162. generator.useKernelBlur &&
  163. <SliderLineComponent label="Blur kernel" target={generator} propertyName="blurKernel" minimum={1} maximum={64} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  164. }
  165. {
  166. (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) &&
  167. <FloatLineComponent lockObject={this.props.lockObject} label="Depth scale" target={generator} propertyName="depthScale" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  168. }
  169. {
  170. (generator instanceof ShadowGenerator) && (filter === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP || filter === ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) &&
  171. <SliderLineComponent label="Blur scale" target={generator} propertyName="blurScale" minimum={1} maximum={4} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  172. }
  173. {
  174. csmGenerator && (filter === ShadowGenerator.FILTER_PCSS) &&
  175. <SliderLineComponent label="Penumbra darkness" minimum={0} maximum={1.0} step={0.01} target={generator} propertyName="penumbraDarkness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
  176. }
  177. </LineContainerComponent>
  178. }
  179. </div>
  180. );
  181. }
  182. }