|
@@ -135,6 +135,12 @@ export interface IShadowGenerator {
|
|
* Documentation: https://doc.babylonjs.com/babylon101/shadows
|
|
* Documentation: https://doc.babylonjs.com/babylon101/shadows
|
|
*/
|
|
*/
|
|
export class ShadowGenerator implements IShadowGenerator {
|
|
export class ShadowGenerator implements IShadowGenerator {
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Name of the shadow generator class
|
|
|
|
+ */
|
|
|
|
+ public static CLASSNAME = "ShadowGenerator";
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Shadow generator mode None: no filtering applied.
|
|
* Shadow generator mode None: no filtering applied.
|
|
*/
|
|
*/
|
|
@@ -232,7 +238,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
*/
|
|
*/
|
|
public onAfterShadowMapRenderMeshObservable = new Observable<Mesh>();
|
|
public onAfterShadowMapRenderMeshObservable = new Observable<Mesh>();
|
|
|
|
|
|
- private _bias = 0.00005;
|
|
|
|
|
|
+ protected _bias = 0.00005;
|
|
/**
|
|
/**
|
|
* Gets the bias: offset applied on the depth preventing acnea (in light direction).
|
|
* Gets the bias: offset applied on the depth preventing acnea (in light direction).
|
|
*/
|
|
*/
|
|
@@ -246,7 +252,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._bias = bias;
|
|
this._bias = bias;
|
|
}
|
|
}
|
|
|
|
|
|
- private _normalBias = 0;
|
|
|
|
|
|
+ protected _normalBias = 0;
|
|
/**
|
|
/**
|
|
* Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
|
|
* Gets the normalBias: offset applied on the depth preventing acnea (along side the normal direction and proportinal to the light/normal angle).
|
|
*/
|
|
*/
|
|
@@ -260,7 +266,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._normalBias = normalBias;
|
|
this._normalBias = normalBias;
|
|
}
|
|
}
|
|
|
|
|
|
- private _blurBoxOffset = 1;
|
|
|
|
|
|
+ protected _blurBoxOffset = 1;
|
|
/**
|
|
/**
|
|
* Gets the blur box offset: offset applied during the blur pass.
|
|
* Gets the blur box offset: offset applied during the blur pass.
|
|
* Only useful if useKernelBlur = false
|
|
* Only useful if useKernelBlur = false
|
|
@@ -281,7 +287,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._disposeBlurPostProcesses();
|
|
this._disposeBlurPostProcesses();
|
|
}
|
|
}
|
|
|
|
|
|
- private _blurScale = 2;
|
|
|
|
|
|
+ protected _blurScale = 2;
|
|
/**
|
|
/**
|
|
* Gets the blur scale: scale of the blurred texture compared to the main shadow map.
|
|
* Gets the blur scale: scale of the blurred texture compared to the main shadow map.
|
|
* 2 means half of the size.
|
|
* 2 means half of the size.
|
|
@@ -302,7 +308,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._disposeBlurPostProcesses();
|
|
this._disposeBlurPostProcesses();
|
|
}
|
|
}
|
|
|
|
|
|
- private _blurKernel = 1;
|
|
|
|
|
|
+ protected _blurKernel = 1;
|
|
/**
|
|
/**
|
|
* Gets the blur kernel: kernel size of the blur pass.
|
|
* Gets the blur kernel: kernel size of the blur pass.
|
|
* Only useful if useKernelBlur = true
|
|
* Only useful if useKernelBlur = true
|
|
@@ -323,7 +329,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._disposeBlurPostProcesses();
|
|
this._disposeBlurPostProcesses();
|
|
}
|
|
}
|
|
|
|
|
|
- private _useKernelBlur = false;
|
|
|
|
|
|
+ protected _useKernelBlur = false;
|
|
/**
|
|
/**
|
|
* Gets whether the blur pass is a kernel blur (if true) or box blur.
|
|
* Gets whether the blur pass is a kernel blur (if true) or box blur.
|
|
* Only useful in filtered mode (useBlurExponentialShadowMap...)
|
|
* Only useful in filtered mode (useBlurExponentialShadowMap...)
|
|
@@ -344,7 +350,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._disposeBlurPostProcesses();
|
|
this._disposeBlurPostProcesses();
|
|
}
|
|
}
|
|
|
|
|
|
- private _depthScale: number;
|
|
|
|
|
|
+ protected _depthScale: number;
|
|
/**
|
|
/**
|
|
* Gets the depth scale used in ESM mode.
|
|
* Gets the depth scale used in ESM mode.
|
|
*/
|
|
*/
|
|
@@ -359,7 +365,11 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._depthScale = value;
|
|
this._depthScale = value;
|
|
}
|
|
}
|
|
|
|
|
|
- private _filter = ShadowGenerator.FILTER_NONE;
|
|
|
|
|
|
+ protected _validateFilter(filter: number): number {
|
|
|
|
+ return filter;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected _filter = ShadowGenerator.FILTER_NONE;
|
|
/**
|
|
/**
|
|
* Gets the current mode of the shadow generator (normal, PCF, ESM...).
|
|
* Gets the current mode of the shadow generator (normal, PCF, ESM...).
|
|
* The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
|
|
* The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
|
|
@@ -372,6 +382,8 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
|
|
* The returned value is a number equal to one of the available mode defined in ShadowMap.FILTER_x like _FILTER_NONE
|
|
*/
|
|
*/
|
|
public set filter(value: number) {
|
|
public set filter(value: number) {
|
|
|
|
+ value = this._validateFilter(value);
|
|
|
|
+
|
|
// Blurring the cubemap is going to be too expensive. Reverting to unblurred version
|
|
// Blurring the cubemap is going to be too expensive. Reverting to unblurred version
|
|
if (this._light.needCube()) {
|
|
if (this._light.needCube()) {
|
|
if (value === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
|
|
if (value === ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
|
|
@@ -417,11 +429,13 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Sets the current filter to Poisson Sampling.
|
|
* Sets the current filter to Poisson Sampling.
|
|
*/
|
|
*/
|
|
public set usePoissonSampling(value: boolean) {
|
|
public set usePoissonSampling(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_POISSONSAMPLING);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_POISSONSAMPLING) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_POISSONSAMPLING) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- this.filter = (value ? ShadowGenerator.FILTER_POISSONSAMPLING : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -434,10 +448,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Sets the current filter is to ESM.
|
|
* Sets the current filter is to ESM.
|
|
*/
|
|
*/
|
|
public set useExponentialShadowMap(value: boolean) {
|
|
public set useExponentialShadowMap(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_EXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -450,10 +466,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Gets if the current filter is set to filtered ESM.
|
|
* Gets if the current filter is set to filtered ESM.
|
|
*/
|
|
*/
|
|
public set useBlurExponentialShadowMap(value: boolean) {
|
|
public set useBlurExponentialShadowMap(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_BLUREXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -468,10 +486,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* exponential to prevent steep falloff artifacts).
|
|
* exponential to prevent steep falloff artifacts).
|
|
*/
|
|
*/
|
|
public set useCloseExponentialShadowMap(value: boolean) {
|
|
public set useCloseExponentialShadowMap(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_CLOSEEXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -486,10 +506,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* exponential to prevent steep falloff artifacts).
|
|
* exponential to prevent steep falloff artifacts).
|
|
*/
|
|
*/
|
|
public set useBlurCloseExponentialShadowMap(value: boolean) {
|
|
public set useBlurCloseExponentialShadowMap(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_BLURCLOSEEXPONENTIALSHADOWMAP : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -502,13 +524,15 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Sets the current filter to "PCF" (percentage closer filtering).
|
|
* Sets the current filter to "PCF" (percentage closer filtering).
|
|
*/
|
|
*/
|
|
public set usePercentageCloserFiltering(value: boolean) {
|
|
public set usePercentageCloserFiltering(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_PCF);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_PCF) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_PCF) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_PCF : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
- private _filteringQuality = ShadowGenerator.QUALITY_HIGH;
|
|
|
|
|
|
+ protected _filteringQuality = ShadowGenerator.QUALITY_HIGH;
|
|
/**
|
|
/**
|
|
* Gets the PCF or PCSS Quality.
|
|
* Gets the PCF or PCSS Quality.
|
|
* Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
|
|
* Only valid if usePercentageCloserFiltering or usePercentageCloserFiltering is true.
|
|
@@ -542,13 +566,15 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Sets the current filter to "PCSS" (contact hardening).
|
|
* Sets the current filter to "PCSS" (contact hardening).
|
|
*/
|
|
*/
|
|
public set useContactHardeningShadow(value: boolean) {
|
|
public set useContactHardeningShadow(value: boolean) {
|
|
|
|
+ let filter = this._validateFilter(ShadowGenerator.FILTER_PCSS);
|
|
|
|
+
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_PCSS) {
|
|
if (!value && this.filter !== ShadowGenerator.FILTER_PCSS) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this.filter = (value ? ShadowGenerator.FILTER_PCSS : ShadowGenerator.FILTER_NONE);
|
|
|
|
|
|
+ this.filter = (value ? filter : ShadowGenerator.FILTER_NONE);
|
|
}
|
|
}
|
|
|
|
|
|
- private _contactHardeningLightSizeUVRatio = 0.1;
|
|
|
|
|
|
+ protected _contactHardeningLightSizeUVRatio = 0.1;
|
|
/**
|
|
/**
|
|
* Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
|
|
* Gets the Light Size (in shadow map uv unit) used in PCSS to determine the blocker search area and the penumbra size.
|
|
* Using a ratio helps keeping shape stability independently of the map size.
|
|
* Using a ratio helps keeping shape stability independently of the map size.
|
|
@@ -574,7 +600,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._contactHardeningLightSizeUVRatio = contactHardeningLightSizeUVRatio;
|
|
this._contactHardeningLightSizeUVRatio = contactHardeningLightSizeUVRatio;
|
|
}
|
|
}
|
|
|
|
|
|
- private _darkness = 0;
|
|
|
|
|
|
+ protected _darkness = 0;
|
|
|
|
|
|
/** Gets or sets the actual darkness of a shadow */
|
|
/** Gets or sets the actual darkness of a shadow */
|
|
public get darkness() {
|
|
public get darkness() {
|
|
@@ -611,7 +637,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
- private _transparencyShadow = false;
|
|
|
|
|
|
+ protected _transparencyShadow = false;
|
|
|
|
|
|
/** Gets or sets the ability to have transparent shadow */
|
|
/** Gets or sets the ability to have transparent shadow */
|
|
public get transparencyShadow() {
|
|
public get transparencyShadow() {
|
|
@@ -632,8 +658,9 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
- private _shadowMap: Nullable<RenderTargetTexture>;
|
|
|
|
- private _shadowMap2: Nullable<RenderTargetTexture>;
|
|
|
|
|
|
+ protected _shadowMap: Nullable<RenderTargetTexture>;
|
|
|
|
+ protected _shadowMap2: Nullable<RenderTargetTexture>;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Gets the main RTT containing the shadow map (usually storing depth from the light point of view).
|
|
* Gets the main RTT containing the shadow map (usually storing depth from the light point of view).
|
|
* @returns The render target texture if present otherwise, null
|
|
* @returns The render target texture if present otherwise, null
|
|
@@ -641,6 +668,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
public getShadowMap(): Nullable<RenderTargetTexture> {
|
|
public getShadowMap(): Nullable<RenderTargetTexture> {
|
|
return this._shadowMap;
|
|
return this._shadowMap;
|
|
}
|
|
}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
|
|
* Gets the RTT used during rendering (can be a blurred version of the shadow map or the shadow map itself).
|
|
* @returns The render target texture if the shadow map is present otherwise, null
|
|
* @returns The render target texture if the shadow map is present otherwise, null
|
|
@@ -658,7 +686,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* @returns "ShadowGenerator"
|
|
* @returns "ShadowGenerator"
|
|
*/
|
|
*/
|
|
public getClassName(): string {
|
|
public getClassName(): string {
|
|
- return "ShadowGenerator";
|
|
|
|
|
|
+ return ShadowGenerator.CLASSNAME;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -713,11 +741,10 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
|
|
|
|
/**
|
|
/**
|
|
* Controls the extent to which the shadows fade out at the edge of the frustum
|
|
* Controls the extent to which the shadows fade out at the edge of the frustum
|
|
- * Used only by directionals and spots
|
|
|
|
*/
|
|
*/
|
|
public frustumEdgeFalloff = 0;
|
|
public frustumEdgeFalloff = 0;
|
|
|
|
|
|
- private _light: IShadowLight;
|
|
|
|
|
|
+ protected _light: IShadowLight;
|
|
/**
|
|
/**
|
|
* Returns the associated light object.
|
|
* Returns the associated light object.
|
|
* @returns the light generating the shadow
|
|
* @returns the light generating the shadow
|
|
@@ -733,28 +760,28 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
*/
|
|
*/
|
|
public forceBackFacesOnly = false;
|
|
public forceBackFacesOnly = false;
|
|
|
|
|
|
- private _scene: Scene;
|
|
|
|
- private _lightDirection = Vector3.Zero();
|
|
|
|
-
|
|
|
|
- private _effect: Effect;
|
|
|
|
-
|
|
|
|
- private _viewMatrix = Matrix.Zero();
|
|
|
|
- private _projectionMatrix = Matrix.Zero();
|
|
|
|
- private _transformMatrix = Matrix.Zero();
|
|
|
|
- private _cachedPosition: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
|
|
|
|
- private _cachedDirection: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
|
|
|
|
- private _cachedDefines: string;
|
|
|
|
- private _currentRenderID: number;
|
|
|
|
- private _boxBlurPostprocess: Nullable<PostProcess>;
|
|
|
|
- private _kernelBlurXPostprocess: Nullable<PostProcess>;
|
|
|
|
- private _kernelBlurYPostprocess: Nullable<PostProcess>;
|
|
|
|
- private _blurPostProcesses: PostProcess[];
|
|
|
|
- private _mapSize: number;
|
|
|
|
- private _currentFaceIndex = 0;
|
|
|
|
- private _currentFaceIndexCache = 0;
|
|
|
|
- private _textureType: number;
|
|
|
|
- private _defaultTextureMatrix = Matrix.Identity();
|
|
|
|
- private _storedUniqueId: Nullable<number>;
|
|
|
|
|
|
+ protected _scene: Scene;
|
|
|
|
+ protected _lightDirection = Vector3.Zero();
|
|
|
|
+
|
|
|
|
+ protected _effect: Effect;
|
|
|
|
+
|
|
|
|
+ protected _viewMatrix = Matrix.Zero();
|
|
|
|
+ protected _projectionMatrix = Matrix.Zero();
|
|
|
|
+ protected _transformMatrix = Matrix.Zero();
|
|
|
|
+ protected _cachedPosition: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
|
|
|
|
+ protected _cachedDirection: Vector3 = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
|
|
|
|
+ protected _cachedDefines: string;
|
|
|
|
+ protected _currentRenderID: number;
|
|
|
|
+ protected _boxBlurPostprocess: Nullable<PostProcess>;
|
|
|
|
+ protected _kernelBlurXPostprocess: Nullable<PostProcess>;
|
|
|
|
+ protected _kernelBlurYPostprocess: Nullable<PostProcess>;
|
|
|
|
+ protected _blurPostProcesses: PostProcess[];
|
|
|
|
+ protected _mapSize: number;
|
|
|
|
+ protected _currentFaceIndex = 0;
|
|
|
|
+ protected _currentFaceIndexCache = 0;
|
|
|
|
+ protected _textureType: number;
|
|
|
|
+ protected _defaultTextureMatrix = Matrix.Identity();
|
|
|
|
+ protected _storedUniqueId: Nullable<number>;
|
|
|
|
|
|
/** @hidden */
|
|
/** @hidden */
|
|
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
|
|
public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
|
|
@@ -807,13 +834,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._applyFilterValues();
|
|
this._applyFilterValues();
|
|
}
|
|
}
|
|
|
|
|
|
- private _initializeGenerator(): void {
|
|
|
|
|
|
+ protected _initializeGenerator(): void {
|
|
this._light._markMeshesAsLightDirty();
|
|
this._light._markMeshesAsLightDirty();
|
|
this._initializeShadowMap();
|
|
this._initializeShadowMap();
|
|
}
|
|
}
|
|
|
|
|
|
- private _initializeShadowMap(): void {
|
|
|
|
- // Render target
|
|
|
|
|
|
+ protected _createTargetRenderTexture(): void {
|
|
let engine = this._scene.getEngine();
|
|
let engine = this._scene.getEngine();
|
|
if (engine.webGLVersion > 1) {
|
|
if (engine.webGLVersion > 1) {
|
|
this._shadowMap = new RenderTargetTexture(this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube(), undefined, false, false);
|
|
this._shadowMap = new RenderTargetTexture(this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube(), undefined, false, false);
|
|
@@ -822,6 +848,15 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
else {
|
|
else {
|
|
this._shadowMap = new RenderTargetTexture(this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube());
|
|
this._shadowMap = new RenderTargetTexture(this._light.name + "_shadowMap", this._mapSize, this._scene, false, true, this._textureType, this._light.needCube());
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected _initializeShadowMap(): void {
|
|
|
|
+ this._createTargetRenderTexture();
|
|
|
|
+
|
|
|
|
+ if (this._shadowMap === null) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
this._shadowMap.wrapU = Texture.CLAMP_ADDRESSMODE;
|
|
this._shadowMap.wrapU = Texture.CLAMP_ADDRESSMODE;
|
|
this._shadowMap.wrapV = Texture.CLAMP_ADDRESSMODE;
|
|
this._shadowMap.wrapV = Texture.CLAMP_ADDRESSMODE;
|
|
this._shadowMap.anisotropicFilteringLevel = 1;
|
|
this._shadowMap.anisotropicFilteringLevel = 1;
|
|
@@ -832,6 +867,11 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._shadowMap.uniqueId = this._storedUniqueId;
|
|
this._shadowMap.uniqueId = this._storedUniqueId;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Custom render function.
|
|
|
|
+ this._shadowMap.customRenderFunction = this._renderForShadowMap.bind(this);
|
|
|
|
+
|
|
|
|
+ let engine = this._scene.getEngine();
|
|
|
|
+
|
|
// Record Face Index before render.
|
|
// Record Face Index before render.
|
|
this._shadowMap.onBeforeRenderObservable.add((faceIndex: number) => {
|
|
this._shadowMap.onBeforeRenderObservable.add((faceIndex: number) => {
|
|
this._currentFaceIndex = faceIndex;
|
|
this._currentFaceIndex = faceIndex;
|
|
@@ -840,9 +880,6 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
- // Custom render function.
|
|
|
|
- this._shadowMap.customRenderFunction = this._renderForShadowMap.bind(this);
|
|
|
|
-
|
|
|
|
// Blur if required afer render.
|
|
// Blur if required afer render.
|
|
this._shadowMap.onAfterUnbindObservable.add(() => {
|
|
this._shadowMap.onAfterUnbindObservable.add(() => {
|
|
if (this._filter === ShadowGenerator.FILTER_PCF) {
|
|
if (this._filter === ShadowGenerator.FILTER_PCF) {
|
|
@@ -873,6 +910,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+ // Recreate on resize.
|
|
this._shadowMap.onResizeObservable.add((RTT) => {
|
|
this._shadowMap.onResizeObservable.add((RTT) => {
|
|
this._storedUniqueId = this._shadowMap!.uniqueId;
|
|
this._storedUniqueId = this._shadowMap!.uniqueId;
|
|
this._mapSize = RTT.getRenderSize();
|
|
this._mapSize = RTT.getRenderSize();
|
|
@@ -881,7 +919,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- private _initializeBlurRTTAndPostProcesses(): void {
|
|
|
|
|
|
+ protected _initializeBlurRTTAndPostProcesses(): void {
|
|
var engine = this._scene.getEngine();
|
|
var engine = this._scene.getEngine();
|
|
var targetSize = this._mapSize / this.blurScale;
|
|
var targetSize = this._mapSize / this.blurScale;
|
|
|
|
|
|
@@ -925,7 +963,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private _renderForShadowMap(opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void {
|
|
|
|
|
|
+ protected _renderForShadowMap(opaqueSubMeshes: SmartArray<SubMesh>, alphaTestSubMeshes: SmartArray<SubMesh>, transparentSubMeshes: SmartArray<SubMesh>, depthOnlySubMeshes: SmartArray<SubMesh>): void {
|
|
var index: number;
|
|
var index: number;
|
|
let engine = this._scene.getEngine();
|
|
let engine = this._scene.getEngine();
|
|
|
|
|
|
@@ -953,7 +991,10 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private _renderSubMeshForShadowMap(subMesh: SubMesh): void {
|
|
|
|
|
|
+ protected _bindCustomEffectForRenderSubMeshForShadowMap(subMesh: SubMesh, effect: Effect): void {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ protected _renderSubMeshForShadowMap(subMesh: SubMesh): void {
|
|
var mesh = subMesh.getRenderingMesh();
|
|
var mesh = subMesh.getRenderingMesh();
|
|
var scene = this._scene;
|
|
var scene = this._scene;
|
|
var engine = scene.getEngine();
|
|
var engine = scene.getEngine();
|
|
@@ -1023,6 +1064,8 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
// Morph targets
|
|
// Morph targets
|
|
MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
|
|
MaterialHelper.BindMorphTargetParameters(mesh, this._effect);
|
|
|
|
|
|
|
|
+ this._bindCustomEffectForRenderSubMeshForShadowMap(subMesh, this._effect);
|
|
|
|
+
|
|
if (this.forceBackFacesOnly) {
|
|
if (this.forceBackFacesOnly) {
|
|
engine.setState(true, 0, false, true);
|
|
engine.setState(true, 0, false, true);
|
|
}
|
|
}
|
|
@@ -1051,7 +1094,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private _applyFilterValues(): void {
|
|
|
|
|
|
+ protected _applyFilterValues(): void {
|
|
if (!this._shadowMap) {
|
|
if (!this._shadowMap) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -1136,6 +1179,9 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ protected _isReadyCustomDefines(defines: any, subMesh: SubMesh, useInstances: boolean): void {
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
|
|
* Determine wheter the shadow generator is ready or not (mainly all effects and related post processes needs to be ready).
|
|
* @param subMesh The submesh we want to render in the shadow map
|
|
* @param subMesh The submesh we want to render in the shadow map
|
|
@@ -1244,6 +1290,8 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._isReadyCustomDefines(defines, subMesh, useInstances);
|
|
|
|
+
|
|
// Get correct effect
|
|
// Get correct effect
|
|
var join = defines.join("\n");
|
|
var join = defines.join("\n");
|
|
if (this._cachedDefines !== join) {
|
|
if (this._cachedDefines !== join) {
|
|
@@ -1336,7 +1384,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
}
|
|
}
|
|
// else default to high.
|
|
// else default to high.
|
|
}
|
|
}
|
|
- if (this.usePercentageCloserFiltering) {
|
|
|
|
|
|
+ else if (this.usePercentageCloserFiltering) {
|
|
defines["SHADOWPCF" + lightIndex] = true;
|
|
defines["SHADOWPCF" + lightIndex] = true;
|
|
if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {
|
|
if (this._filteringQuality === ShadowGenerator.QUALITY_LOW) {
|
|
defines["SHADOWLOWQUALITY" + lightIndex] = true;
|
|
defines["SHADOWLOWQUALITY" + lightIndex] = true;
|
|
@@ -1368,19 +1416,19 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* @param effect The effect we are binfing the information for
|
|
* @param effect The effect we are binfing the information for
|
|
*/
|
|
*/
|
|
public bindShadowLight(lightIndex: string, effect: Effect): void {
|
|
public bindShadowLight(lightIndex: string, effect: Effect): void {
|
|
- var light = this._light;
|
|
|
|
- var scene = this._scene;
|
|
|
|
|
|
+ const light = this._light;
|
|
|
|
+ const scene = this._scene;
|
|
|
|
|
|
if (!scene.shadowsEnabled || !light.shadowEnabled) {
|
|
if (!scene.shadowsEnabled || !light.shadowEnabled) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- let camera = scene.activeCamera;
|
|
|
|
|
|
+ const camera = scene.activeCamera;
|
|
if (!camera) {
|
|
if (!camera) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- let shadowMap = this.getShadowMap();
|
|
|
|
|
|
+ const shadowMap = this.getShadowMap();
|
|
|
|
|
|
if (!shadowMap) {
|
|
if (!shadowMap) {
|
|
return;
|
|
return;
|
|
@@ -1479,7 +1527,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._shadowMap!.renderList = renderList;
|
|
this._shadowMap!.renderList = renderList;
|
|
}
|
|
}
|
|
|
|
|
|
- private _disposeBlurPostProcesses(): void {
|
|
|
|
|
|
+ protected _disposeBlurPostProcesses(): void {
|
|
if (this._shadowMap2) {
|
|
if (this._shadowMap2) {
|
|
this._shadowMap2.dispose();
|
|
this._shadowMap2.dispose();
|
|
this._shadowMap2 = null;
|
|
this._shadowMap2 = null;
|
|
@@ -1503,7 +1551,7 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
this._blurPostProcesses = [];
|
|
this._blurPostProcesses = [];
|
|
}
|
|
}
|
|
|
|
|
|
- private _disposeRTTandPostProcesses(): void {
|
|
|
|
|
|
+ protected _disposeRTTandPostProcesses(): void {
|
|
if (this._shadowMap) {
|
|
if (this._shadowMap) {
|
|
this._shadowMap.dispose();
|
|
this._shadowMap.dispose();
|
|
this._shadowMap = null;
|
|
this._shadowMap = null;
|
|
@@ -1542,30 +1590,29 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
return serializationObject;
|
|
return serializationObject;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ serializationObject.className = this.getClassName();
|
|
serializationObject.lightId = this._light.id;
|
|
serializationObject.lightId = this._light.id;
|
|
serializationObject.mapSize = shadowMap.getRenderSize();
|
|
serializationObject.mapSize = shadowMap.getRenderSize();
|
|
|
|
+ serializationObject.forceBackFacesOnly = this.forceBackFacesOnly;
|
|
|
|
+ serializationObject.darkness = this.getDarkness();
|
|
|
|
+ serializationObject.transparencyShadow = this._transparencyShadow;
|
|
|
|
+ serializationObject.frustumEdgeFalloff = this.frustumEdgeFalloff;
|
|
|
|
+ serializationObject.bias = this.bias;
|
|
|
|
+ serializationObject.normalBias = this.normalBias;
|
|
|
|
+ serializationObject.usePercentageCloserFiltering = this.usePercentageCloserFiltering;
|
|
|
|
+ serializationObject.useContactHardeningShadow = this.useContactHardeningShadow;
|
|
|
|
+ serializationObject.contactHardeningLightSizeUVRatio = this.contactHardeningLightSizeUVRatio;
|
|
|
|
+ serializationObject.filteringQuality = this.filteringQuality;
|
|
serializationObject.useExponentialShadowMap = this.useExponentialShadowMap;
|
|
serializationObject.useExponentialShadowMap = this.useExponentialShadowMap;
|
|
serializationObject.useBlurExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.useBlurExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.useCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.useCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.useBlurCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.useBlurCloseExponentialShadowMap = this.useBlurExponentialShadowMap;
|
|
serializationObject.usePoissonSampling = this.usePoissonSampling;
|
|
serializationObject.usePoissonSampling = this.usePoissonSampling;
|
|
- serializationObject.forceBackFacesOnly = this.forceBackFacesOnly;
|
|
|
|
serializationObject.depthScale = this.depthScale;
|
|
serializationObject.depthScale = this.depthScale;
|
|
- serializationObject.darkness = this.getDarkness();
|
|
|
|
serializationObject.blurBoxOffset = this.blurBoxOffset;
|
|
serializationObject.blurBoxOffset = this.blurBoxOffset;
|
|
serializationObject.blurKernel = this.blurKernel;
|
|
serializationObject.blurKernel = this.blurKernel;
|
|
serializationObject.blurScale = this.blurScale;
|
|
serializationObject.blurScale = this.blurScale;
|
|
serializationObject.useKernelBlur = this.useKernelBlur;
|
|
serializationObject.useKernelBlur = this.useKernelBlur;
|
|
- serializationObject.transparencyShadow = this._transparencyShadow;
|
|
|
|
- serializationObject.frustumEdgeFalloff = this.frustumEdgeFalloff;
|
|
|
|
-
|
|
|
|
- serializationObject.bias = this.bias;
|
|
|
|
- serializationObject.normalBias = this.normalBias;
|
|
|
|
-
|
|
|
|
- serializationObject.usePercentageCloserFiltering = this.usePercentageCloserFiltering;
|
|
|
|
- serializationObject.useContactHardeningShadow = this.useContactHardeningShadow;
|
|
|
|
- serializationObject.filteringQuality = this.filteringQuality;
|
|
|
|
- serializationObject.contactHardeningLightSizeUVRatio = this.contactHardeningLightSizeUVRatio;
|
|
|
|
|
|
|
|
serializationObject.renderList = [];
|
|
serializationObject.renderList = [];
|
|
if (shadowMap.renderList) {
|
|
if (shadowMap.renderList) {
|
|
@@ -1583,11 +1630,12 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
* Parses a serialized ShadowGenerator and returns a new ShadowGenerator.
|
|
* Parses a serialized ShadowGenerator and returns a new ShadowGenerator.
|
|
* @param parsedShadowGenerator The JSON object to parse
|
|
* @param parsedShadowGenerator The JSON object to parse
|
|
* @param scene The scene to create the shadow map for
|
|
* @param scene The scene to create the shadow map for
|
|
|
|
+ * @param constr A function that builds a shadow generator or undefined to create an instance of the default shadow generator
|
|
* @returns The parsed shadow generator
|
|
* @returns The parsed shadow generator
|
|
*/
|
|
*/
|
|
- public static Parse(parsedShadowGenerator: any, scene: Scene): ShadowGenerator {
|
|
|
|
|
|
+ public static Parse(parsedShadowGenerator: any, scene: Scene, constr?: (mapSize: number, light: IShadowLight) => ShadowGenerator): ShadowGenerator {
|
|
var light = <IShadowLight>scene.getLightByID(parsedShadowGenerator.lightId);
|
|
var light = <IShadowLight>scene.getLightByID(parsedShadowGenerator.lightId);
|
|
- var shadowGenerator = new ShadowGenerator(parsedShadowGenerator.mapSize, light);
|
|
|
|
|
|
+ var shadowGenerator = constr ? constr(parsedShadowGenerator.mapSize, light) : new ShadowGenerator(parsedShadowGenerator.mapSize, light);
|
|
var shadowMap = shadowGenerator.getShadowMap();
|
|
var shadowMap = shadowGenerator.getShadowMap();
|
|
|
|
|
|
for (var meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
|
|
for (var meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
|
|
@@ -1603,42 +1651,56 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- if (parsedShadowGenerator.usePoissonSampling) {
|
|
|
|
- shadowGenerator.usePoissonSampling = true;
|
|
|
|
|
|
+ shadowGenerator.forceBackFacesOnly = !!parsedShadowGenerator.forceBackFacesOnly;
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.darkness !== undefined) {
|
|
|
|
+ shadowGenerator.setDarkness(parsedShadowGenerator.darkness);
|
|
}
|
|
}
|
|
- else if (parsedShadowGenerator.useExponentialShadowMap) {
|
|
|
|
- shadowGenerator.useExponentialShadowMap = true;
|
|
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.transparencyShadow) {
|
|
|
|
+ shadowGenerator.setTransparencyShadow(true);
|
|
}
|
|
}
|
|
- else if (parsedShadowGenerator.useBlurExponentialShadowMap) {
|
|
|
|
- shadowGenerator.useBlurExponentialShadowMap = true;
|
|
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.frustumEdgeFalloff !== undefined) {
|
|
|
|
+ shadowGenerator.frustumEdgeFalloff = parsedShadowGenerator.frustumEdgeFalloff;
|
|
}
|
|
}
|
|
- else if (parsedShadowGenerator.useCloseExponentialShadowMap) {
|
|
|
|
- shadowGenerator.useCloseExponentialShadowMap = true;
|
|
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.bias !== undefined) {
|
|
|
|
+ shadowGenerator.bias = parsedShadowGenerator.bias;
|
|
}
|
|
}
|
|
- else if (parsedShadowGenerator.useBlurCloseExponentialShadowMap) {
|
|
|
|
- shadowGenerator.useBlurCloseExponentialShadowMap = true;
|
|
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.normalBias !== undefined) {
|
|
|
|
+ shadowGenerator.normalBias = parsedShadowGenerator.normalBias;
|
|
}
|
|
}
|
|
- else if (parsedShadowGenerator.usePercentageCloserFiltering) {
|
|
|
|
|
|
+
|
|
|
|
+ if (parsedShadowGenerator.usePercentageCloserFiltering) {
|
|
shadowGenerator.usePercentageCloserFiltering = true;
|
|
shadowGenerator.usePercentageCloserFiltering = true;
|
|
- }
|
|
|
|
- else if (parsedShadowGenerator.useContactHardeningShadow) {
|
|
|
|
|
|
+ } else if (parsedShadowGenerator.useContactHardeningShadow) {
|
|
shadowGenerator.useContactHardeningShadow = true;
|
|
shadowGenerator.useContactHardeningShadow = true;
|
|
|
|
+ } else if (parsedShadowGenerator.usePoissonSampling) {
|
|
|
|
+ shadowGenerator.usePoissonSampling = true;
|
|
|
|
+ } else if (parsedShadowGenerator.useExponentialShadowMap) {
|
|
|
|
+ shadowGenerator.useExponentialShadowMap = true;
|
|
|
|
+ } else if (parsedShadowGenerator.useBlurExponentialShadowMap) {
|
|
|
|
+ shadowGenerator.useBlurExponentialShadowMap = true;
|
|
|
|
+ } else if (parsedShadowGenerator.useCloseExponentialShadowMap) {
|
|
|
|
+ shadowGenerator.useCloseExponentialShadowMap = true;
|
|
|
|
+ } else if (parsedShadowGenerator.useBlurCloseExponentialShadowMap) {
|
|
|
|
+ shadowGenerator.useBlurCloseExponentialShadowMap = true;
|
|
|
|
+ } else
|
|
|
|
+ // Backward compat
|
|
|
|
+ if (parsedShadowGenerator.useVarianceShadowMap) {
|
|
|
|
+ shadowGenerator.useExponentialShadowMap = true;
|
|
|
|
+ } else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
|
|
|
|
+ shadowGenerator.useBlurExponentialShadowMap = true;
|
|
}
|
|
}
|
|
|
|
|
|
- if (parsedShadowGenerator.filteringQuality) {
|
|
|
|
- shadowGenerator.filteringQuality = parsedShadowGenerator.filteringQuality;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (parsedShadowGenerator.contactHardeningLightSizeUVRatio) {
|
|
|
|
|
|
+ if (parsedShadowGenerator.contactHardeningLightSizeUVRatio !== undefined) {
|
|
shadowGenerator.contactHardeningLightSizeUVRatio = parsedShadowGenerator.contactHardeningLightSizeUVRatio;
|
|
shadowGenerator.contactHardeningLightSizeUVRatio = parsedShadowGenerator.contactHardeningLightSizeUVRatio;
|
|
}
|
|
}
|
|
|
|
|
|
- // Backward compat
|
|
|
|
- else if (parsedShadowGenerator.useVarianceShadowMap) {
|
|
|
|
- shadowGenerator.useExponentialShadowMap = true;
|
|
|
|
- }
|
|
|
|
- else if (parsedShadowGenerator.useBlurVarianceShadowMap) {
|
|
|
|
- shadowGenerator.useBlurExponentialShadowMap = true;
|
|
|
|
|
|
+ if (parsedShadowGenerator.filteringQuality !== undefined) {
|
|
|
|
+ shadowGenerator.filteringQuality = parsedShadowGenerator.filteringQuality;
|
|
}
|
|
}
|
|
|
|
|
|
if (parsedShadowGenerator.depthScale) {
|
|
if (parsedShadowGenerator.depthScale) {
|
|
@@ -1661,28 +1723,6 @@ export class ShadowGenerator implements IShadowGenerator {
|
|
shadowGenerator.blurKernel = parsedShadowGenerator.blurKernel;
|
|
shadowGenerator.blurKernel = parsedShadowGenerator.blurKernel;
|
|
}
|
|
}
|
|
|
|
|
|
- if (parsedShadowGenerator.bias !== undefined) {
|
|
|
|
- shadowGenerator.bias = parsedShadowGenerator.bias;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (parsedShadowGenerator.normalBias !== undefined) {
|
|
|
|
- shadowGenerator.normalBias = parsedShadowGenerator.normalBias;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (parsedShadowGenerator.frustumEdgeFalloff !== undefined) {
|
|
|
|
- shadowGenerator.frustumEdgeFalloff = parsedShadowGenerator.frustumEdgeFalloff;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (parsedShadowGenerator.darkness) {
|
|
|
|
- shadowGenerator.setDarkness(parsedShadowGenerator.darkness);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (parsedShadowGenerator.transparencyShadow) {
|
|
|
|
- shadowGenerator.setTransparencyShadow(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- shadowGenerator.forceBackFacesOnly = parsedShadowGenerator.forceBackFacesOnly;
|
|
|
|
-
|
|
|
|
return shadowGenerator;
|
|
return shadowGenerator;
|
|
}
|
|
}
|
|
}
|
|
}
|