|
@@ -40,7 +40,6 @@ export class PrePassRenderer {
|
|
|
|
|
|
private _scene: Scene;
|
|
|
private _engine: Engine;
|
|
|
- private _isDirty: boolean = false;
|
|
|
|
|
|
/**
|
|
|
* The render target where the scene is directly rendered
|
|
@@ -65,7 +64,11 @@ export class PrePassRenderer {
|
|
|
}
|
|
|
|
|
|
private _currentTarget: PrePassRenderTarget;
|
|
|
- private _renderTargets: PrePassRenderTarget[] = [];
|
|
|
+
|
|
|
+ /**
|
|
|
+ * All the render targets generated by prepass
|
|
|
+ */
|
|
|
+ public renderTargets: PrePassRenderTarget[] = [];
|
|
|
|
|
|
private readonly _clearColor = new Color4(0, 0, 0, 0);
|
|
|
|
|
@@ -105,7 +108,7 @@ export class PrePassRenderer {
|
|
|
{ generateMipMaps: false, generateDepthTexture: true, defaultType: Constants.TEXTURETYPE_UNSIGNED_INT, types: [] });
|
|
|
rt.samples = 1;
|
|
|
|
|
|
- this._renderTargets.push(rt);
|
|
|
+ this.renderTargets.push(rt);
|
|
|
return rt;
|
|
|
}
|
|
|
|
|
@@ -122,7 +125,7 @@ export class PrePassRenderer {
|
|
|
* @param subMesh Submesh on which the effect is applied
|
|
|
*/
|
|
|
public bindAttachmentsForEffect(effect: Effect, subMesh: SubMesh) {
|
|
|
- if (this.enabled) {
|
|
|
+ if (this.enabled && this._currentTarget.enabled) {
|
|
|
if (effect._multiTarget) {
|
|
|
this._engine.bindAttachments(this._currentTarget._multiRenderAttachments);
|
|
|
} else {
|
|
@@ -152,11 +155,16 @@ export class PrePassRenderer {
|
|
|
* @hidden
|
|
|
*/
|
|
|
public _beforeDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
|
|
|
- if (this._isDirty) {
|
|
|
- this._update(this._currentTarget);
|
|
|
+ let postProcesses = undefined;
|
|
|
+ if (texture) {
|
|
|
+ postProcesses = texture.postProcesses || texture.activeCamera?._postProcesses || [];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this._currentTarget._isDirty) {
|
|
|
+ this._update(this._currentTarget, postProcesses);
|
|
|
}
|
|
|
|
|
|
- if (!this._enabled) {
|
|
|
+ if (!this._enabled || !this._currentTarget.enabled) {
|
|
|
// Prepass disabled, we render only on 1 color attachment
|
|
|
if (texture) {
|
|
|
texture._bindFrameBuffer();
|
|
@@ -173,14 +181,14 @@ export class PrePassRenderer {
|
|
|
this._currentTarget._geometryBuffer.renderList!.length = 0;
|
|
|
}
|
|
|
|
|
|
- this._setupOutputForThisPass(this._currentTarget, camera, texture ? texture.postProcesses : []);
|
|
|
+ this._setupOutputForThisPass(this._currentTarget, camera, postProcesses);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @hidden
|
|
|
*/
|
|
|
public _afterDraw(camera: Nullable<Camera>, texture: Nullable<RenderTargetTexture>) {
|
|
|
- if (this._enabled) {
|
|
|
+ if (this._enabled && this._currentTarget.enabled) {
|
|
|
this._scene.postProcessManager._prepareFrame();
|
|
|
const firstCameraPP = camera && camera._getFirstPostProcess();
|
|
|
let outputTexture = firstCameraPP ? firstCameraPP.inputTexture : (texture ? texture.getInternalTexture() : null);
|
|
@@ -215,7 +223,7 @@ export class PrePassRenderer {
|
|
|
* Clears the render target (in the sense of settings pixels to the scene clear color value)
|
|
|
*/
|
|
|
public _clear() {
|
|
|
- if (this._enabled) {
|
|
|
+ if (this._enabled && this._currentTarget.enabled) {
|
|
|
this._bindFrameBuffer(this._currentTarget);
|
|
|
|
|
|
// Clearing other attachment with 0 on all other attachments
|
|
@@ -232,7 +240,7 @@ export class PrePassRenderer {
|
|
|
}
|
|
|
|
|
|
private _bindFrameBuffer(prePassRenderTarget: PrePassRenderTarget) {
|
|
|
- if (this._enabled) {
|
|
|
+ if (this._enabled && this._currentTarget.enabled) {
|
|
|
this._currentTarget._checkSize();
|
|
|
var internalTexture = this._currentTarget.getInternalTexture();
|
|
|
if (internalTexture) {
|
|
@@ -244,8 +252,7 @@ export class PrePassRenderer {
|
|
|
private _setState(prePassRenderTarget: PrePassRenderTarget, enabled: boolean) {
|
|
|
this._enabled = enabled;
|
|
|
|
|
|
- // TODO : generalize flag to signalize we are rendering to prepass for this frame
|
|
|
- this._scene.prePass = enabled;
|
|
|
+ prePassRenderTarget.enabled = enabled;
|
|
|
|
|
|
if (prePassRenderTarget.imageProcessingPostProcess) {
|
|
|
prePassRenderTarget.imageProcessingPostProcess.imageProcessingConfiguration.applyByPostProcess = enabled;
|
|
@@ -389,7 +396,9 @@ export class PrePassRenderer {
|
|
|
* Marks the prepass renderer as dirty, triggering a check if the prepass is necessary for the next rendering.
|
|
|
*/
|
|
|
public markAsDirty() {
|
|
|
- this._isDirty = true;
|
|
|
+ for (let i = 0; i < this.renderTargets.length; i++) {
|
|
|
+ this.renderTargets[i]._isDirty = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -409,7 +418,7 @@ export class PrePassRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private _update(prePassRenderTarget: PrePassRenderTarget) {
|
|
|
+ private _update(prePassRenderTarget: PrePassRenderTarget, forcePostProcesses?: PostProcess[]) {
|
|
|
this._disable(prePassRenderTarget);
|
|
|
let enablePrePass = false;
|
|
|
|
|
@@ -419,12 +428,20 @@ export class PrePassRenderer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- const camera = this._scene.activeCamera;
|
|
|
- if (!camera) {
|
|
|
- return;
|
|
|
+ let postProcesses;
|
|
|
+
|
|
|
+ if (forcePostProcesses) {
|
|
|
+ postProcesses = forcePostProcesses;
|
|
|
+ } else {
|
|
|
+ const camera = this._scene.activeCamera;
|
|
|
+ if (!camera) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ postProcesses = camera._postProcesses;
|
|
|
}
|
|
|
|
|
|
- const postProcesses = (<Nullable<PostProcess[]>>camera._postProcesses.filter((pp) => { return pp != null; }));
|
|
|
+ postProcesses = (<Nullable<PostProcess[]>>postProcesses.filter((pp) => { return pp != null; }));
|
|
|
|
|
|
if (postProcesses) {
|
|
|
for (let i = 0; i < postProcesses.length; i++) {
|
|
@@ -435,7 +452,7 @@ export class PrePassRenderer {
|
|
|
}
|
|
|
|
|
|
this._markAllMaterialsAsPrePassDirty();
|
|
|
- this._isDirty = false;
|
|
|
+ prePassRenderTarget._isDirty = false;
|
|
|
|
|
|
if (enablePrePass) {
|
|
|
this._enable(prePassRenderTarget);
|
|
@@ -454,8 +471,14 @@ export class PrePassRenderer {
|
|
|
* Disposes the prepass renderer.
|
|
|
*/
|
|
|
public dispose() {
|
|
|
- for (let i = 0; i < this._renderTargets.length; i++) {
|
|
|
- this._renderTargets[i].dispose();
|
|
|
+ for (let i = this.renderTargets.length - 1; i >= 0; i--) {
|
|
|
+
|
|
|
+ for (let j = 0; j < this.renderTargets[i]._effectConfigurations.length; j++) {
|
|
|
+ if (this.renderTargets[i]._effectConfigurations[j].dispose) {
|
|
|
+ this.renderTargets[i]._effectConfigurations[j].dispose!();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.renderTargets[i].dispose();
|
|
|
}
|
|
|
}
|
|
|
|