|
@@ -2,42 +2,89 @@
|
|
export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
|
|
export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
|
|
private _scene: Scene;
|
|
private _scene: Scene;
|
|
|
|
|
|
- /**
|
|
|
|
- * The FxaaPostProcess Id
|
|
|
|
- * @type {string}
|
|
|
|
- */
|
|
|
|
|
|
+ readonly PassPostProcessId: string = "PassPostProcessEffect";
|
|
|
|
+ readonly HighLightsPostProcessId: string = "HighLightsPostProcessEffect";
|
|
|
|
+ readonly BlurXPostProcessId: string = "BlurXPostProcessEffect";
|
|
|
|
+ readonly BlurYPostProcessId: string = "BlurYPostProcessEffect";
|
|
|
|
+ readonly CopyBackPostProcessId: string = "CopyBackPostProcessEffect";
|
|
|
|
+ readonly ImageProcessingPostProcessId: string = "ImageProcessingPostProcessEffect";
|
|
readonly FxaaPostProcessId: string = "FxaaPostProcessEffect";
|
|
readonly FxaaPostProcessId: string = "FxaaPostProcessEffect";
|
|
|
|
+ readonly FinalMergePostProcessId: string = "FinalMergePostProcessEffect";
|
|
|
|
|
|
// Post-processes
|
|
// Post-processes
|
|
|
|
+ public pass: BABYLON.PassPostProcess;
|
|
|
|
+ public highlights: BABYLON.HighlightsPostProcess;
|
|
|
|
+ public blurX: BABYLON.BlurPostProcess;
|
|
|
|
+ public blurY: BABYLON.BlurPostProcess;
|
|
|
|
+ public copyBack: BABYLON.PassPostProcess;
|
|
public fxaa: FxaaPostProcess;
|
|
public fxaa: FxaaPostProcess;
|
|
public imageProcessing: ImageProcessingPostProcess;
|
|
public imageProcessing: ImageProcessingPostProcess;
|
|
|
|
+ public finalMerge: BABYLON.PassPostProcess;
|
|
|
|
|
|
// IAnimatable
|
|
// IAnimatable
|
|
public animations: Animation[] = [];
|
|
public animations: Animation[] = [];
|
|
|
|
|
|
// Values
|
|
// Values
|
|
|
|
+ private _bloomEnabled: boolean = false;
|
|
private _fxaaEnabled: boolean = false;
|
|
private _fxaaEnabled: boolean = false;
|
|
private _imageProcessingEnabled: boolean = false;
|
|
private _imageProcessingEnabled: boolean = false;
|
|
|
|
+ private _defaultPipelineTextureType: number;
|
|
|
|
+ private _bloomScale: number = 0.6;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Specifies the size of the bloom blur kernel, relative to the final output size
|
|
|
|
+ */
|
|
|
|
+ @serialize()
|
|
|
|
+ public bloomKernel: number = 64;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Specifies the weight of the bloom in the final rendering
|
|
|
|
+ */
|
|
|
|
+ @serialize()
|
|
|
|
+ public bloomWeight: number = 0.15;
|
|
|
|
|
|
@serialize()
|
|
@serialize()
|
|
private _hdr: boolean;
|
|
private _hdr: boolean;
|
|
|
|
|
|
- public set FxaaEnabled(enabled: boolean) {
|
|
|
|
- if (this._fxaaEnabled === enabled) {
|
|
|
|
|
|
+ public set bloomScale(value: number) {
|
|
|
|
+ if (this._bloomScale === value) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- this._fxaaEnabled = enabled;
|
|
|
|
|
|
+ this._bloomScale = value;
|
|
|
|
|
|
- if (enabled) {
|
|
|
|
- this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, this.FxaaPostProcessId, this._scene.cameras);
|
|
|
|
|
|
+ this._buildPipeline();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @serialize()
|
|
|
|
+ public get bloomScale(): number {
|
|
|
|
+ return this._bloomScale;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public set bloomEnabled(enabled: boolean) {
|
|
|
|
+ if (this._bloomEnabled === enabled) {
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, this.FxaaPostProcessId, this._scene.cameras);
|
|
|
|
|
|
+ this._bloomEnabled = enabled;
|
|
|
|
+
|
|
|
|
+ this._buildPipeline();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @serialize()
|
|
|
|
+ public get bloomEnabled(): boolean {
|
|
|
|
+ return this._bloomEnabled;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public set fxaaEnabled(enabled: boolean) {
|
|
|
|
+ if (this._fxaaEnabled === enabled) {
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
+ this._fxaaEnabled = enabled;
|
|
|
|
+
|
|
|
|
+ this._buildPipeline();
|
|
}
|
|
}
|
|
|
|
|
|
@serialize()
|
|
@serialize()
|
|
- public get FxaaEnabled(): boolean {
|
|
|
|
|
|
+ public get fxaaEnabled(): boolean {
|
|
return this._fxaaEnabled;
|
|
return this._fxaaEnabled;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -57,29 +104,145 @@
|
|
this._scene = scene;
|
|
this._scene = scene;
|
|
|
|
|
|
// Misc
|
|
// Misc
|
|
- var floatTextureType = scene.getEngine().getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
|
|
|
|
-
|
|
|
|
- // fxaa
|
|
|
|
- this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, floatTextureType);
|
|
|
|
- this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.FxaaPostProcessId, () => { return this.fxaa; }, true));
|
|
|
|
|
|
+ this._defaultPipelineTextureType = scene.getEngine().getCaps().textureFloatRender ? Engine.TEXTURETYPE_FLOAT : Engine.TEXTURETYPE_HALF_FLOAT;
|
|
|
|
|
|
- // Finish
|
|
|
|
|
|
+ // Attach
|
|
scene.postProcessRenderPipelineManager.addPipeline(this);
|
|
scene.postProcessRenderPipelineManager.addPipeline(this);
|
|
|
|
|
|
- if (cameras !== null) {
|
|
|
|
- scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras);
|
|
|
|
- }
|
|
|
|
|
|
+ this._buildPipeline();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private _buildPipeline() {
|
|
|
|
+ var engine = this._scene.getEngine();
|
|
|
|
|
|
- // Deactivate
|
|
|
|
- this.FxaaEnabled = false;
|
|
|
|
|
|
+ this._disposePostProcesses();
|
|
|
|
+ this._reset();
|
|
|
|
+
|
|
|
|
+ if (this.bloomEnabled) {
|
|
|
|
+ this.pass = new BABYLON.PassPostProcess("sceneRenderTarget", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.PassPostProcessId, () => { return this.pass; }, true));
|
|
|
|
+
|
|
|
|
+ if (!this._hdr) { // Need to enhance highlights if not using float rendering
|
|
|
|
+ this.highlights = new BABYLON.HighlightsPostProcess("highlights", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.HighLightsPostProcessId, () => { return this.highlights; }, true));
|
|
|
|
+ this.highlights.autoClear = false;
|
|
|
|
+ this.highlights.alwaysForcePOT = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.blurX = new BABYLON.BlurPostProcess("horizontal blur", new BABYLON.Vector2(1.0, 0), 10.0, this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.BlurXPostProcessId, () => { return this.blurX; }, true));
|
|
|
|
+ this.blurX.alwaysForcePOT = true;
|
|
|
|
+ this.blurX.autoClear = false;
|
|
|
|
+ this.blurX.onActivateObservable.add(() => {
|
|
|
|
+ let dw = this.blurX.width / engine.getRenderWidth();
|
|
|
|
+ this.blurX.kernel = this.bloomKernel * dw;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.blurY = new BABYLON.BlurPostProcess("vertical blur", new BABYLON.Vector2(0, 1.0), 10.0, this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.BlurYPostProcessId, () => { return this.blurY; }, true));
|
|
|
|
+ this.blurY.alwaysForcePOT = true;
|
|
|
|
+ this.blurY.autoClear = false;
|
|
|
|
+ this.blurY.onActivateObservable.add(() => {
|
|
|
|
+ let dh = this.blurY.height / engine.getRenderHeight();
|
|
|
|
+ this.blurY.kernel = this.bloomKernel * dh;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ this.copyBack = new BABYLON.PassPostProcess("bloomBlendBlit", this.bloomScale, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.CopyBackPostProcessId, () => { return this.copyBack; }, true));
|
|
|
|
+ this.copyBack.alwaysForcePOT = true;
|
|
|
|
+ if (this._hdr) {
|
|
|
|
+ this.copyBack.alphaMode = BABYLON.Engine.ALPHA_INTERPOLATE;
|
|
|
|
+ let w = this.bloomWeight;
|
|
|
|
+ this.copyBack.alphaConstants = new BABYLON.Color4(w, w, w, w);
|
|
|
|
+ } else {
|
|
|
|
+ this.copyBack.alphaMode = BABYLON.Engine.ALPHA_SCREENMODE;
|
|
|
|
+ }
|
|
|
|
+ this.copyBack.autoClear = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.imageProcessing = new BABYLON.ImageProcessingPostProcess("imageProcessing", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ if (this._hdr) {
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.ImageProcessingPostProcessId, () => { return this.imageProcessing; }, true));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.fxaaEnabled) {
|
|
|
|
+ this.fxaa = new FxaaPostProcess("fxaa", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.FxaaPostProcessId, () => { return this.fxaa; }, true));
|
|
|
|
+ this.fxaa.autoClear = false;
|
|
|
|
+ } else {
|
|
|
|
+ this.finalMerge = new BABYLON.PassPostProcess("finalMerge", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this.addEffect(new PostProcessRenderEffect(engine, this.FinalMergePostProcessId, () => { return this.finalMerge; }, true));
|
|
|
|
+ this.finalMerge.autoClear = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.bloomEnabled) {
|
|
|
|
+ if (this._hdr) { // Share render targets to save memory
|
|
|
|
+ this.copyBack.shareOutputWith(this.blurX);
|
|
|
|
+ this.imageProcessing.shareOutputWith(this.pass);
|
|
|
|
+ this.imageProcessing.autoClear = false;
|
|
|
|
+ } else {
|
|
|
|
+ if (this.fxaa) {
|
|
|
|
+ this.fxaa.shareOutputWith(this.pass);
|
|
|
|
+ } else {
|
|
|
|
+ this.finalMerge.shareOutputWith(this.pass);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this._cameras !== null) {
|
|
|
|
+ this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- // Dispose
|
|
|
|
- public dispose(): void {
|
|
|
|
|
|
+
|
|
|
|
+ private _disposePostProcesses(): void {
|
|
for (var i = 0; i < this._cameras.length; i++) {
|
|
for (var i = 0; i < this._cameras.length; i++) {
|
|
var camera = this._cameras[i];
|
|
var camera = this._cameras[i];
|
|
|
|
|
|
- this.fxaa.dispose(camera);
|
|
|
|
|
|
+ if (this.pass) {
|
|
|
|
+ this.pass.dispose(camera);
|
|
|
|
+ this.pass = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.highlights) {
|
|
|
|
+ this.highlights.dispose(camera);
|
|
|
|
+ this.highlights = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.blurX) {
|
|
|
|
+ this.blurX.dispose(camera);
|
|
|
|
+ this.blurX = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.blurY) {
|
|
|
|
+ this.blurY.dispose(camera);
|
|
|
|
+ this.blurY = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.copyBack) {
|
|
|
|
+ this.copyBack.dispose(camera);
|
|
|
|
+ this.copyBack = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.imageProcessing) {
|
|
|
|
+ this.imageProcessing.dispose(camera);
|
|
|
|
+ this.imageProcessing = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.fxaa) {
|
|
|
|
+ this.fxaa.dispose(camera);
|
|
|
|
+ this.fxaa = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.finalMerge) {
|
|
|
|
+ this.finalMerge.dispose(camera);
|
|
|
|
+ this.finalMerge = null;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Dispose
|
|
|
|
+ public dispose(): void {
|
|
|
|
+ this._disposePostProcesses();
|
|
|
|
|
|
this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
|
|
this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
|
|
|
|
|