@babylonjs/core
Version:
Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.
280 lines • 9.67 kB
JavaScript
import { FrameGraphTask } from "../../frameGraphTask.js";
import { ShadowGenerator } from "../../../Lights/Shadows/shadowGenerator.js";
/**
* Task used to generate shadows from a list of objects.
*/
export class FrameGraphShadowGeneratorTask extends FrameGraphTask {
/**
* The light to generate shadows from.
*/
get light() {
return this._light;
}
set light(value) {
if (value === this._light) {
return;
}
this._light = value;
this._setupShadowGenerator();
}
/**
* Gets or sets the camera used to generate the shadow generator.
*/
get camera() {
return this._camera;
}
set camera(camera) {
this._camera = camera;
this._setupShadowGenerator();
}
/**
* The size of the shadow map.
*/
get mapSize() {
return this._mapSize;
}
set mapSize(value) {
if (value === this._mapSize) {
return;
}
this._mapSize = value;
this._setupShadowGenerator();
}
/**
* If true, the shadow map will use a 32 bits float texture type (else, 16 bits float is used if supported).
*/
get useFloat32TextureType() {
return this._useFloat32TextureType;
}
set useFloat32TextureType(value) {
if (value === this._useFloat32TextureType) {
return;
}
this._useFloat32TextureType = value;
this._setupShadowGenerator();
}
/**
* If true, the shadow map will use a red texture format (else, a RGBA format is used).
*/
get useRedTextureFormat() {
return this._useRedTextureFormat;
}
set useRedTextureFormat(value) {
if (value === this._useRedTextureFormat) {
return;
}
this._useRedTextureFormat = value;
this._setupShadowGenerator();
}
/**
* The bias to apply to the shadow map.
*/
get bias() {
return this._bias;
}
set bias(value) {
if (value === this._bias) {
return;
}
this._bias = value;
if (this._shadowGenerator) {
this._shadowGenerator.bias = value;
}
}
/**
* The normal bias to apply to the shadow map.
*/
get normalBias() {
return this._normalBias;
}
set normalBias(value) {
if (value === this._normalBias) {
return;
}
this._normalBias = value;
if (this._shadowGenerator) {
this._shadowGenerator.normalBias = value;
}
}
/**
* The darkness of the shadows.
*/
get darkness() {
return this._darkness;
}
set darkness(value) {
if (value === this._darkness) {
return;
}
this._darkness = value;
if (this._shadowGenerator) {
this._shadowGenerator.darkness = value;
}
}
/**
* Gets or sets the ability to have transparent shadow
*/
get transparencyShadow() {
return this._transparencyShadow;
}
set transparencyShadow(value) {
if (value === this._transparencyShadow) {
return;
}
this._transparencyShadow = value;
if (this._shadowGenerator) {
this._shadowGenerator.transparencyShadow = value;
}
}
/**
* Enables or disables shadows with varying strength based on the transparency
*/
get enableSoftTransparentShadow() {
return this._enableSoftTransparentShadow;
}
set enableSoftTransparentShadow(value) {
if (value === this._enableSoftTransparentShadow) {
return;
}
this._enableSoftTransparentShadow = value;
if (this._shadowGenerator) {
this._shadowGenerator.enableSoftTransparentShadow = value;
}
}
/**
* If this is true, use the opacity texture's alpha channel for transparent shadows instead of the diffuse one
*/
get useOpacityTextureForTransparentShadow() {
return this._useOpacityTextureForTransparentShadow;
}
set useOpacityTextureForTransparentShadow(value) {
if (value === this._useOpacityTextureForTransparentShadow) {
return;
}
this._useOpacityTextureForTransparentShadow = value;
if (this._shadowGenerator) {
this._shadowGenerator.useOpacityTextureForTransparentShadow = value;
}
}
/**
* The filter to apply to the shadow map.
*/
get filter() {
return this._filter;
}
set filter(value) {
if (value === this._filter) {
return;
}
this._filter = value;
if (this._shadowGenerator) {
this._shadowGenerator.filter = value;
}
}
/**
* The filtering quality to apply to the filter.
*/
get filteringQuality() {
return this._filteringQuality;
}
set filteringQuality(value) {
if (value === this._filteringQuality) {
return;
}
this._filteringQuality = value;
if (this._shadowGenerator) {
this._shadowGenerator.filteringQuality = value;
}
}
_createShadowGenerator() {
this._shadowGenerator = new ShadowGenerator(this._mapSize, this._light, this._useFloat32TextureType, undefined, this._useRedTextureFormat);
}
_setupShadowGenerator() {
this._shadowGenerator?.dispose();
this._shadowGenerator = undefined;
if (this._light !== undefined) {
this._createShadowGenerator();
const shadowGenerator = this._shadowGenerator;
if (shadowGenerator === undefined) {
return;
}
shadowGenerator.bias = this._bias;
shadowGenerator.normalBias = this._normalBias;
shadowGenerator.darkness = this._darkness;
shadowGenerator.transparencyShadow = this._transparencyShadow;
shadowGenerator.enableSoftTransparentShadow = this._enableSoftTransparentShadow;
shadowGenerator.useOpacityTextureForTransparentShadow = this._useOpacityTextureForTransparentShadow;
shadowGenerator.filter = this._filter;
shadowGenerator.filteringQuality = this._filteringQuality;
const shadowMap = shadowGenerator.getShadowMap();
shadowMap._disableEngineStages = true;
shadowMap.cameraForLOD = this._camera;
this.shadowGenerator = shadowGenerator;
}
}
isReady() {
return !!this._shadowGenerator && !!this._shadowGenerator.getShadowMap()?.isReadyForRendering();
}
/**
* Creates a new shadow generator task.
* @param name The name of the task.
* @param frameGraph The frame graph the task belongs to.
* @param scene The scene to create the shadow generator for.
*/
constructor(name, frameGraph, scene) {
super(name, frameGraph);
this._mapSize = 1024;
this._useFloat32TextureType = false;
this._useRedTextureFormat = true;
this._bias = 0.01;
this._normalBias = 0;
this._darkness = 0;
this._transparencyShadow = false;
this._enableSoftTransparentShadow = false;
this._useOpacityTextureForTransparentShadow = false;
this._filter = ShadowGenerator.FILTER_PCF;
this._filteringQuality = ShadowGenerator.QUALITY_HIGH;
this._engine = scene.getEngine();
this._scene = scene;
this.outputTexture = this._frameGraph.textureManager.createDanglingHandle();
}
record() {
if (this.light === undefined || this.objectList === undefined || this.camera === undefined) {
throw new Error(`FrameGraphShadowGeneratorTask ${this.name}: light, objectList and camera are required`);
}
// Make sure the renderList / particleSystemList are set when FrameGraphShadowGeneratorTask.isReady() is called!
const shadowMap = this._shadowGenerator.getShadowMap();
shadowMap.renderList = this.objectList.meshes;
shadowMap.particleSystemList = this.objectList.particleSystems;
const shadowTextureHandle = this._frameGraph.textureManager.importTexture(`${this.name} shadowmap`, this._shadowGenerator.getShadowMap().getInternalTexture());
this._frameGraph.textureManager.resolveDanglingHandle(this.outputTexture, shadowTextureHandle);
const pass = this._frameGraph.addPass(this.name);
pass.setExecuteFunc((_context) => {
if (!this.light.isEnabled() || !this.light.shadowEnabled) {
return;
}
const shadowMap = this._shadowGenerator.getShadowMap();
shadowMap.renderList = this.objectList.meshes;
shadowMap.particleSystemList = this.objectList.particleSystems;
const currentRenderTarget = this._engine._currentRenderTarget;
this._scene.incrementRenderId();
this._scene.resetCachedMaterial();
shadowMap.render();
if (this._engine._currentRenderTarget !== currentRenderTarget) {
if (!currentRenderTarget) {
this._engine.restoreDefaultFramebuffer();
}
else {
this._engine.bindFramebuffer(currentRenderTarget);
}
}
});
const passDisabled = this._frameGraph.addPass(this.name + "_disabled", true);
passDisabled.setExecuteFunc((_context) => { });
}
dispose() {
this._shadowGenerator?.dispose();
this._shadowGenerator = undefined;
}
}
//# sourceMappingURL=shadowGeneratorTask.js.map