123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732 |
- import { PrePassRenderTarget } from "../Materials/Textures/prePassRenderTarget";
- import { Scene } from "../scene";
- import { Engine } from "../Engines/engine";
- import { Constants } from "../Engines/constants";
- import { PostProcess } from "../PostProcesses/postProcess";
- import { Effect } from "../Materials/effect";
- import { _DevTools } from '../Misc/devTools';
- import { Color4 } from "../Maths/math.color";
- import { Nullable } from "../types";
- import { AbstractMesh } from '../Meshes/abstractMesh';
- import { Camera } from '../Cameras/camera';
- import { Material } from '../Materials/material';
- import { SubMesh } from '../Meshes/subMesh';
- import { PrePassEffectConfiguration } from "./prePassEffectConfiguration";
- import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture";
- import { GeometryBufferRenderer } from '../Rendering/geometryBufferRenderer';
- /**
- * Renders a pre pass of the scene
- * This means every mesh in the scene will be rendered to a render target texture
- * And then this texture will be composited to the rendering canvas with post processes
- * It is necessary for effects like subsurface scattering or deferred shading
- */
- export class PrePassRenderer {
- /** @hidden */
- public static _SceneComponentInitialization: (scene: Scene) => void = (_) => {
- throw _DevTools.WarnImport("PrePassRendererSceneComponent");
- }
- /**
- * To save performance, we can excluded skinned meshes from the prepass
- */
- public excludedSkinnedMesh: AbstractMesh[] = [];
- /**
- * Force material to be excluded from the prepass
- * Can be useful when `useGeometryBufferFallback` is set to `true`
- * and you don't want a material to show in the effect.
- */
- public excludedMaterials: Material[] = [];
- private _scene: Scene;
- private _engine: Engine;
- /**
- * Number of textures in the multi render target texture where the scene is directly rendered
- */
- public mrtCount: number = 0;
- private _mrtFormats: number[] = [];
- private _mrtLayout: number[] = [];
- private _textureIndices: number[] = [];
- private _multiRenderAttachments: number[];
- private _defaultAttachments: number[];
- private _clearAttachments: number[];
- /**
- * Returns the index of a texture in the multi render target texture array.
- * @param type Texture type
- * @return The index
- */
- public getIndex(type: number) : number {
- return this._textureIndices[type];
- }
- /**
- * How many samples are used for MSAA of the scene render target
- */
- public get samples() {
- return this.defaultRT.samples;
- }
- public set samples(n: number) {
- this.defaultRT.samples = n;
- }
- private static _textureFormats = [
- {
- type: Constants.PREPASS_IRRADIANCE_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_POSITION_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_UNSIGNED_INT,
- },
- {
- type: Constants.PREPASS_COLOR_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_DEPTH_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_NORMAL_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_HALF_FLOAT,
- },
- {
- type: Constants.PREPASS_ALBEDO_TEXTURE_TYPE,
- format: Constants.TEXTURETYPE_UNSIGNED_INT,
- },
- ];
- private _isDirty: boolean = true;
- /**
- * The render target where the scene is directly rendered
- */
- public defaultRT: PrePassRenderTarget;
- /**
- * Configuration for prepass effects
- */
- private _effectConfigurations: PrePassEffectConfiguration[] = [];
- /**
- * @return the prepass render target for the rendering pass.
- * If we are currently rendering a render target, it returns the PrePassRenderTarget
- * associated with that render target. Otherwise, it returns the scene default PrePassRenderTarget
- */
- public getRenderTarget(): PrePassRenderTarget {
- return this._currentTarget;
- }
- /**
- * @hidden
- * Managed by the scene component
- * @param prePassRenderTarget
- */
- public _setRenderTarget(prePassRenderTarget: Nullable<PrePassRenderTarget>): void {
- if (prePassRenderTarget) {
- this._currentTarget = prePassRenderTarget;
- } else {
- this._currentTarget = this.defaultRT;
- }
- }
- /**
- * Returns true if the currently rendered prePassRenderTarget is the one
- * associated with the scene.
- */
- public get currentRTisSceneRT(): boolean {
- return this._currentTarget === this.defaultRT;
- }
- private _geometryBuffer: Nullable<GeometryBufferRenderer>;
- /**
- * Prevents the PrePassRenderer from using the GeometryBufferRenderer as a fallback
- */
- public doNotUseGeometryRendererFallback = true;
- private _refreshGeometryBufferRendererLink() {
- if (!this.doNotUseGeometryRendererFallback) {
- this._geometryBuffer = this._scene.enableGeometryBufferRenderer();
- if (!this._geometryBuffer) {
- // Not supported
- this.doNotUseGeometryRendererFallback = true;
- return;
- }
- this._geometryBuffer._linkPrePassRenderer(this);
- } else {
- if (this._geometryBuffer) {
- this._geometryBuffer._unlinkPrePassRenderer();
- }
- this._geometryBuffer = null;
- this._scene.disableGeometryBufferRenderer();
- }
- }
- private _currentTarget: PrePassRenderTarget;
- /**
- * All the render targets generated by prepass
- */
- public renderTargets: PrePassRenderTarget[] = [];
- private readonly _clearColor = new Color4(0, 0, 0, 0);
- private _enabled: boolean = false;
- private _needsCompositionForThisPass = false;
- private _postProcessesSourceForThisPass: Nullable<PostProcess>[];
- /**
- * Indicates if the prepass is enabled
- */
- public get enabled() {
- return this._enabled;
- }
- /**
- * Set to true to disable gamma transform in PrePass.
- * Can be useful in case you already proceed to gamma transform on a material level
- * and your post processes don't need to be in linear color space.
- */
- public disableGammaTransform = false;
- /**
- * Instanciates a prepass renderer
- * @param scene The scene
- */
- constructor(scene: Scene) {
- this._scene = scene;
- this._engine = scene.getEngine();
- PrePassRenderer._SceneComponentInitialization(this._scene);
- this.defaultRT = this._createRenderTarget("sceneprePassRT", null);
- this._setRenderTarget(null);
- }
- /**
- * Creates a new PrePassRenderTarget
- * This should be the only way to instanciate a `PrePassRenderTarget`
- * @param name Name of the `PrePassRenderTarget`
- * @param renderTargetTexture RenderTarget the `PrePassRenderTarget` will be attached to.
- * Can be `null` if the created `PrePassRenderTarget` is attached to the scene (default framebuffer).
- * @hidden
- */
- public _createRenderTarget(name: string, renderTargetTexture: Nullable<RenderTargetTexture>) : PrePassRenderTarget {
- const rt = new PrePassRenderTarget(name, renderTargetTexture, { width: this._engine.getRenderWidth(), height: this._engine.getRenderHeight() }, 0, this._scene,
- { generateMipMaps: false, generateStencilBuffer: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: [], drawOnlyOnFirstAttachmentByDefault: true });
- this.renderTargets.push(rt);
- return rt;
- }
- /**
- * Indicates if rendering a prepass is supported
- */
- public get isSupported() {
- return this._engine.webGLVersion > 1 || this._scene.getEngine().getCaps().drawBuffersExtension;
- }
- /**
- * Sets the proper output textures to draw in the engine.
- * @param effect The effect that is drawn. It can be or not be compatible with drawing to several output textures.
- * @param subMesh Submesh on which the effect is applied
- */
- public bindAttachmentsForEffect(effect: Effect, subMesh: SubMesh) {
- if (this.enabled && this._currentTarget.enabled) {
- if (effect._multiTarget) {
- this._engine.bindAttachments(this._multiRenderAttachments);
- } else {
- this._engine.bindAttachments(this._defaultAttachments);
- if (this._geometryBuffer && this.currentRTisSceneRT) {
- const material = subMesh.getMaterial();
- if (material && this.excludedMaterials.indexOf(material) === -1) {
- this._geometryBuffer.renderList!.push(subMesh.getRenderingMesh());
- }
- }
- }
- }
- }
- private _reinitializeAttachments() {
- const multiRenderLayout = [];
- const clearLayout = [false];
- const defaultLayout = [true];
- for (let i = 0; i < this.mrtCount; i++) {
- multiRenderLayout.push(true);
- if (i > 0) {
- clearLayout.push(true);
- defaultLayout.push(false);
- }
- }
- this._multiRenderAttachments = this._engine.buildTextureLayout(multiRenderLayout);
- this._clearAttachments = this._engine.buildTextureLayout(clearLayout);
- this._defaultAttachments = this._engine.buildTextureLayout(defaultLayout);
- }
- private _resetLayout() {
- for (let i = 0 ; i < PrePassRenderer._textureFormats.length; i++) {
- this._textureIndices[PrePassRenderer._textureFormats[i].type] = -1;
- }
- this._textureIndices[Constants.PREPASS_COLOR_TEXTURE_TYPE] = 0;
- this._mrtLayout = [Constants.PREPASS_COLOR_TEXTURE_TYPE];
- this._mrtFormats = [Constants.TEXTURETYPE_HALF_FLOAT];
- this.mrtCount = 1;
- }
- private _updateGeometryBufferLayout() {
- this._refreshGeometryBufferRendererLink();
- if (this._geometryBuffer) {
- this._geometryBuffer._resetLayout();
- const texturesActivated = [];
- for (let i = 0; i < this._mrtLayout.length; i++) {
- texturesActivated.push(false);
- }
- this._geometryBuffer._linkInternalTexture(this.defaultRT.getInternalTexture()!);
- const matches = [
- {
- prePassConstant: Constants.PREPASS_DEPTH_TEXTURE_TYPE,
- geometryBufferConstant: GeometryBufferRenderer.DEPTH_TEXTURE_TYPE,
- },
- {
- prePassConstant: Constants.PREPASS_NORMAL_TEXTURE_TYPE,
- geometryBufferConstant: GeometryBufferRenderer.NORMAL_TEXTURE_TYPE,
- },
- {
- prePassConstant: Constants.PREPASS_POSITION_TEXTURE_TYPE,
- geometryBufferConstant: GeometryBufferRenderer.POSITION_TEXTURE_TYPE,
- },
- {
- prePassConstant: Constants.PREPASS_REFLECTIVITY_TEXTURE_TYPE,
- geometryBufferConstant: GeometryBufferRenderer.REFLECTIVITY_TEXTURE_TYPE,
- },
- {
- prePassConstant: Constants.PREPASS_VELOCITY_TEXTURE_TYPE,
- geometryBufferConstant: GeometryBufferRenderer.VELOCITY_TEXTURE_TYPE,
- }
- ];
- // replace textures in the geometryBuffer RT
- for (let i = 0; i < matches.length; i++) {
- const index = this._mrtLayout.indexOf(matches[i].prePassConstant);
- if (index !== -1) {
- this._geometryBuffer._forceTextureType(matches[i].geometryBufferConstant, index);
- texturesActivated[index] = true;
- }
- }
- this._geometryBuffer._setAttachments(this._engine.buildTextureLayout(texturesActivated));
- }
- }
- /**
- * Restores attachments for single texture draw.
- */
- public restoreAttachments() {
- if (this.enabled && this._currentTarget.enabled && this._defaultAttachments) {
- this._engine.bindAttachments(this._defaultAttachments);
- }
- }
- /**
- * @hidden
- */
- public _beforeDraw(camera?: Camera, faceIndex?: number, layer?: number) {
- // const previousEnabled = this._enabled && this._currentTarget.enabled;
- if (this._isDirty) {
- this._update();
- }
- if (!this._enabled || !this._currentTarget.enabled) {
- return;
- }
- if (this._geometryBuffer) {
- this._geometryBuffer.renderList = [];
- }
- this._setupOutputForThisPass(this._currentTarget, camera);
- }
- private _prepareFrame(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number, layer?: number) {
- if (prePassRenderTarget.renderTargetTexture) {
- prePassRenderTarget.renderTargetTexture._prepareFrame(this._scene, faceIndex, layer, prePassRenderTarget.renderTargetTexture.useCameraPostProcesses);
- } else if (this._postProcessesSourceForThisPass.length) {
- this._scene.postProcessManager._prepareFrame();
- } else {
- this._engine.restoreDefaultFramebuffer();
- }
- }
- private _renderPostProcesses(prePassRenderTarget: PrePassRenderTarget, faceIndex?: number) {
- const firstPP = this._postProcessesSourceForThisPass[0];
- let outputTexture = firstPP ? firstPP.inputTexture : (prePassRenderTarget.renderTargetTexture ? prePassRenderTarget.renderTargetTexture.getInternalTexture() : null);
- // Build post process chain for this prepass post draw
- let postProcessChain = this._currentTarget._beforeCompositionPostProcesses;
- if (this._needsCompositionForThisPass) {
- postProcessChain = postProcessChain.concat([this._currentTarget.imageProcessingPostProcess]);
- }
- // Activates and renders the chain
- if (postProcessChain.length) {
- this._scene.postProcessManager._prepareFrame(this._currentTarget.getInternalTexture()!, postProcessChain);
- this._scene.postProcessManager.directRender(postProcessChain, outputTexture, false, faceIndex);
- }
- }
- /**
- * @hidden
- */
- public _afterDraw(faceIndex?: number, layer?: number) {
- if (this._enabled && this._currentTarget.enabled) {
- this._prepareFrame(this._currentTarget, faceIndex, layer);
- this._renderPostProcesses(this._currentTarget, faceIndex);
- }
- }
- /**
- * Clears the current prepass render target (in the sense of settings pixels to the scene clear color value)
- * @hidden
- */
- public _clear() {
- if (this._enabled && this._currentTarget.enabled) {
- this._bindFrameBuffer(this._currentTarget);
- // Clearing other attachment with 0 on all other attachments
- this._engine.bindAttachments(this._clearAttachments);
- this._engine.clear(this._clearColor, true, false, false);
- // Regular clear color with the scene clear color of the 1st attachment
- this._engine.bindAttachments(this._defaultAttachments);
- }
- }
- private _bindFrameBuffer(prePassRenderTarget: PrePassRenderTarget) {
- if (this._enabled && this._currentTarget.enabled) {
- this._currentTarget._checkSize();
- var internalTexture = this._currentTarget.getInternalTexture();
- if (internalTexture) {
- this._engine.bindFramebuffer(internalTexture);
- }
- }
- }
- private _setState(enabled: boolean) {
- this._enabled = enabled;
- }
- private _setRenderTargetState(prePassRenderTarget: PrePassRenderTarget, enabled: boolean) {
- prePassRenderTarget.enabled = enabled;
- }
- /**
- * Adds an effect configuration to the prepass render target.
- * If an effect has already been added, it won't add it twice and will return the configuration
- * already present.
- * @param cfg the effect configuration
- * @return the effect configuration now used by the prepass
- */
- public addEffectConfiguration(cfg: PrePassEffectConfiguration) : PrePassEffectConfiguration {
- // Do not add twice
- for (let i = 0; i < this._effectConfigurations.length; i++) {
- if (this._effectConfigurations[i].name === cfg.name) {
- return this._effectConfigurations[i];
- }
- }
- this._effectConfigurations.push(cfg);
- return cfg;
- }
- private _enable() {
- const previousMrtCount = this.mrtCount;
- for (let i = 0; i < this._effectConfigurations.length; i++) {
- if (this._effectConfigurations[i].enabled) {
- this._enableTextures(this._effectConfigurations[i].texturesRequired);
- }
- }
- for (let i = 0; i < this.renderTargets.length; i++) {
- if (this.mrtCount !== previousMrtCount) {
- this.renderTargets[i].updateCount(this.mrtCount, { types: this._mrtFormats });
- }
- this.renderTargets[i]._resetPostProcessChain();
- for (let j = 0; j < this._effectConfigurations.length; j++) {
- if (this._effectConfigurations[j].enabled) {
- // TODO : subsurface scattering has 1 scene-wide effect configuration
- // solution : do not stock postProcess on effectConfiguration, but in the prepassRenderTarget (hashmap configuration => postProcess)
- // And call createPostProcess whenever the post process does not exist in the RT
- if (!this._effectConfigurations[j].postProcess && this._effectConfigurations[j].createPostProcess) {
- this._effectConfigurations[j].createPostProcess!();
- }
- if (this._effectConfigurations[j].postProcess) {
- this.renderTargets[i]._beforeCompositionPostProcesses.push(this._effectConfigurations[j].postProcess!);
- }
- }
- }
- }
- this._reinitializeAttachments();
- this._setState(true);
- this._updateGeometryBufferLayout();
- }
- private _disable() {
- this._setState(false);
- for (let i = 0; i < this.renderTargets.length; i++) {
- this._setRenderTargetState(this.renderTargets[i], false);
- }
- this._resetLayout();
- for (let i = 0; i < this._effectConfigurations.length; i++) {
- this._effectConfigurations[i].enabled = false;
- }
- }
- private _getPostProcessesSource(prePassRenderTarget: PrePassRenderTarget, camera?: Camera) : Nullable<PostProcess>[] {
- if (camera) {
- return camera._postProcesses;
- } else if (prePassRenderTarget.renderTargetTexture) {
- if (prePassRenderTarget.renderTargetTexture.useCameraPostProcesses) {
- const camera = prePassRenderTarget.renderTargetTexture.activeCamera ? prePassRenderTarget.renderTargetTexture.activeCamera : this._scene.activeCamera;
- return camera ? camera._postProcesses : [];
- } else if (prePassRenderTarget.renderTargetTexture.postProcesses) {
- return prePassRenderTarget.renderTargetTexture.postProcesses;
- } else {
- return [];
- }
- } else {
- return this._scene.activeCamera ? this._scene.activeCamera._postProcesses : [];
- }
- }
- private _setupOutputForThisPass(prePassRenderTarget: PrePassRenderTarget, camera?: Camera) {
- // Order is : draw ===> prePassRenderTarget._postProcesses ==> ipp ==> camera._postProcesses
- const secondaryCamera = camera && this._scene.activeCameras && !!this._scene.activeCameras.length && this._scene.activeCameras.indexOf(camera) !== 0;
- this._postProcessesSourceForThisPass = this._getPostProcessesSource(prePassRenderTarget, camera);
- this._postProcessesSourceForThisPass = (this._postProcessesSourceForThisPass.filter((pp) => { return pp != null; }));
- const cameraHasImageProcessing = this._hasImageProcessing(this._postProcessesSourceForThisPass);
- this._needsCompositionForThisPass = !cameraHasImageProcessing &&
- !this.disableGammaTransform &&
- this._needsImageProcessing() &&
- !secondaryCamera;
- const firstCameraPP = this._getFirstPostProcess(this._postProcessesSourceForThisPass);
- const firstPrePassPP = prePassRenderTarget._beforeCompositionPostProcesses && prePassRenderTarget._beforeCompositionPostProcesses[0];
- let firstPP = null;
- // Setting the scene-wide post process configuration
- this._scene.imageProcessingConfiguration.applyByPostProcess = this._needsCompositionForThisPass || cameraHasImageProcessing;
- // Create composition effect if needed
- if (this._needsCompositionForThisPass && !prePassRenderTarget.imageProcessingPostProcess) {
- prePassRenderTarget._createCompositionEffect();
- }
- // Setting the prePassRenderTarget as input texture of the first PP
- if (firstPrePassPP) {
- firstPP = firstPrePassPP;
- } else if (this._needsCompositionForThisPass) {
- firstPP = prePassRenderTarget.imageProcessingPostProcess;
- } else if (firstCameraPP) {
- firstPP = firstCameraPP;
- }
- this._bindFrameBuffer(prePassRenderTarget);
- this._linkInternalTexture(prePassRenderTarget, firstPP);
- }
- private _linkInternalTexture(prePassRenderTarget: PrePassRenderTarget, postProcess: Nullable<PostProcess>) {
- if (postProcess) {
- postProcess.autoClear = false;
- postProcess.inputTexture = prePassRenderTarget.getInternalTexture()!;
- }
- if (prePassRenderTarget._outputPostProcess !== postProcess) {
- if (prePassRenderTarget._outputPostProcess) {
- prePassRenderTarget._outputPostProcess.restoreDefaultInputTexture();
- }
- prePassRenderTarget._outputPostProcess = postProcess;
- }
- if (prePassRenderTarget._internalTextureDirty) {
- this._updateGeometryBufferLayout();
- prePassRenderTarget._internalTextureDirty = false;
- }
- }
- private _needsImageProcessing(): boolean {
- for (let i = 0; i < this._effectConfigurations.length; i++) {
- if (this._effectConfigurations[i].enabled && this._effectConfigurations[i].needsImageProcessing) {
- return true;
- }
- }
- return false;
- }
- private _hasImageProcessing(postProcesses: Nullable<PostProcess>[]): boolean {
- let isIPPAlreadyPresent = false;
- if (postProcesses) {
- for (let i = 0; i < postProcesses.length; i++) {
- if (postProcesses[i]?.getClassName() === "ImageProcessingPostProcess") {
- isIPPAlreadyPresent = true;
- }
- }
- }
- return isIPPAlreadyPresent;
- }
- /**
- * Internal, gets the first post proces.
- * @returns the first post process to be run on this camera.
- */
- private _getFirstPostProcess(postProcesses: Nullable<PostProcess>[]): Nullable<PostProcess> {
- for (var ppIndex = 0; ppIndex < postProcesses.length; ppIndex++) {
- if (postProcesses[ppIndex] !== null) {
- return postProcesses[ppIndex];
- }
- }
- return null;
- }
- /**
- * Marks the prepass renderer as dirty, triggering a check if the prepass is necessary for the next rendering.
- */
- public markAsDirty() {
- this._isDirty = true;
- }
- /**
- * Enables a texture on the MultiRenderTarget for prepass
- */
- private _enableTextures(types: number[]) {
- for (let i = 0; i < types.length; i++) {
- let type = types[i];
- if (this._textureIndices[type] === -1) {
- this._textureIndices[type] = this._mrtLayout.length;
- this._mrtLayout.push(type);
- this._mrtFormats.push(PrePassRenderer._textureFormats[type].format);
- this.mrtCount++;
- }
- }
- }
- private _update() {
- this._disable();
- let enablePrePass = false;
- this._scene.imageProcessingConfiguration.applyByPostProcess = false;
- for (let i = 0; i < this._scene.materials.length; i++) {
- if (this._scene.materials[i].setPrePassRenderer(this)) {
- enablePrePass = true;
- this._setRenderTargetState(this.defaultRT, true);
- }
- }
- let postProcesses;
- for (let i = 0; i < this.renderTargets.length; i++) {
- if (this.renderTargets[i].renderTargetTexture) {
- postProcesses = this._getPostProcessesSource(this.renderTargets[i]);
- } else {
- const camera = this._scene.activeCamera;
- if (!camera) {
- continue;
- }
- postProcesses = camera._postProcesses;
- }
- if (!postProcesses) {
- continue;
- }
- postProcesses = (<Nullable<PostProcess[]>>postProcesses.filter((pp) => { return pp != null; }));
- if (postProcesses) {
- for (let j = 0; j < postProcesses.length; j++) {
- if (postProcesses[j].setPrePassRenderer(this)) {
- this._setRenderTargetState(this.renderTargets[i], true);
- enablePrePass = true;
- }
- }
- if (this._hasImageProcessing(postProcesses)) {
- this._scene.imageProcessingConfiguration.applyByPostProcess = true;
- }
- }
- }
- this._markAllMaterialsAsPrePassDirty();
- this._isDirty = false;
- if (enablePrePass) {
- this._enable();
- }
- }
- private _markAllMaterialsAsPrePassDirty() {
- const materials = this._scene.materials;
- for (let i = 0; i < materials.length; i++) {
- materials[i].markAsDirty(Material.PrePassDirtyFlag);
- }
- }
- /**
- * Disposes the prepass renderer.
- */
- public dispose() {
- for (let i = this.renderTargets.length - 1; i >= 0; i--) {
- this.renderTargets[i].dispose();
- }
- for (let i = 0; i < this._effectConfigurations.length; i++) {
- if (this._effectConfigurations[i].dispose) {
- this._effectConfigurations[i].dispose!();
- }
- }
- }
- }
|