|
@@ -5,7 +5,7 @@
|
|
*/
|
|
*/
|
|
export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
|
|
export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable {
|
|
private _scene: Scene;
|
|
private _scene: Scene;
|
|
-
|
|
|
|
|
|
+ private _originalCameras:Array<Camera> = [];
|
|
/**
|
|
/**
|
|
* ID of the sharpen post process,
|
|
* ID of the sharpen post process,
|
|
*/
|
|
*/
|
|
@@ -52,6 +52,7 @@
|
|
* Sharpen post process which will apply a sharpen convolution to enhance edges
|
|
* Sharpen post process which will apply a sharpen convolution to enhance edges
|
|
*/
|
|
*/
|
|
public sharpen: SharpenPostProcess;
|
|
public sharpen: SharpenPostProcess;
|
|
|
|
+ private _sharpenEffect: PostProcessRenderEffect;
|
|
/**
|
|
/**
|
|
* First pass of bloom to capture the original image texture for later use.
|
|
* First pass of bloom to capture the original image texture for later use.
|
|
*/
|
|
*/
|
|
@@ -92,6 +93,7 @@
|
|
* Chromatic aberration post process which will shift rgb colors in the image
|
|
* Chromatic aberration post process which will shift rgb colors in the image
|
|
*/
|
|
*/
|
|
public chromaticAberration: ChromaticAberrationPostProcess;
|
|
public chromaticAberration: ChromaticAberrationPostProcess;
|
|
|
|
+ private _chromaticAberrationEffect: PostProcessRenderEffect;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Animations which can be used to tweak settings over a period of time
|
|
* Animations which can be used to tweak settings over a period of time
|
|
@@ -228,6 +230,20 @@
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
this._depthOfFieldBlurLevel = value;
|
|
this._depthOfFieldBlurLevel = value;
|
|
|
|
+
|
|
|
|
+ // recreate dof and dispose old as this setting is not dynamic
|
|
|
|
+ var oldDof = this.depthOfField;
|
|
|
|
+
|
|
|
|
+ this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
|
|
|
|
+ this.depthOfField.focalLength = oldDof.focalLength;
|
|
|
|
+ this.depthOfField.focusDistance = oldDof.focusDistance;
|
|
|
|
+ this.depthOfField.fStop = oldDof.fStop;
|
|
|
|
+ this.depthOfField.lensSize = oldDof.lensSize;
|
|
|
|
+
|
|
|
|
+ for (var i = 0; i < this._cameras.length; i++) {
|
|
|
|
+ oldDof.disposeEffects(this._cameras[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
this._buildPipeline();
|
|
this._buildPipeline();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -310,6 +326,7 @@
|
|
constructor(name: string, hdr: boolean, scene: Scene, cameras?: Camera[], automaticBuild = true) {
|
|
constructor(name: string, hdr: boolean, scene: Scene, cameras?: Camera[], automaticBuild = true) {
|
|
super(scene.getEngine(), name);
|
|
super(scene.getEngine(), name);
|
|
this._cameras = cameras || [];
|
|
this._cameras = cameras || [];
|
|
|
|
+ this._originalCameras = this._cameras.slice();
|
|
|
|
|
|
this._buildAllowed = automaticBuild;
|
|
this._buildAllowed = automaticBuild;
|
|
|
|
|
|
@@ -333,6 +350,15 @@
|
|
// Attach
|
|
// Attach
|
|
scene.postProcessRenderPipelineManager.addPipeline(this);
|
|
scene.postProcessRenderPipelineManager.addPipeline(this);
|
|
|
|
|
|
|
|
+ var engine = this._scene.getEngine();
|
|
|
|
+ this.sharpen = new SharpenPostProcess("sharpen", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this._sharpenEffect = new PostProcessRenderEffect(engine, this.SharpenPostProcessId, () => { return this.sharpen; }, true);
|
|
|
|
+
|
|
|
|
+ this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
|
|
|
|
+
|
|
|
|
+ this.chromaticAberration = new ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this._chromaticAberrationEffect = new PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, () => { return this.chromaticAberration; }, true);
|
|
|
|
+
|
|
this._buildPipeline();
|
|
this._buildPipeline();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -346,6 +372,30 @@
|
|
this._buildAllowed = previousState;
|
|
this._buildAllowed = previousState;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private _prevPostProcess:Nullable<PostProcess> = null;
|
|
|
|
+ private _prevPrevPostProcess:Nullable<PostProcess> = null;
|
|
|
|
+
|
|
|
|
+ private _setAutoClearAndTextureSharing(postProcess:PostProcess, skipTextureSharing = false){
|
|
|
|
+ if(this._prevPostProcess && this._prevPostProcess.autoClear){
|
|
|
|
+ postProcess.autoClear = false;
|
|
|
|
+ }else{
|
|
|
|
+ postProcess.autoClear = true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!skipTextureSharing){
|
|
|
|
+ if(this._prevPrevPostProcess){
|
|
|
|
+ postProcess.shareOutputWith(this._prevPrevPostProcess);
|
|
|
|
+ }else{
|
|
|
|
+ postProcess.useOwnOutput();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(this._prevPostProcess){
|
|
|
|
+ this._prevPrevPostProcess = this._prevPostProcess;
|
|
|
|
+ }
|
|
|
|
+ this._prevPostProcess = postProcess;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
private _buildPipeline() {
|
|
private _buildPipeline() {
|
|
if (!this._buildAllowed) {
|
|
if (!this._buildAllowed) {
|
|
return;
|
|
return;
|
|
@@ -354,23 +404,37 @@
|
|
var engine = this._scene.getEngine();
|
|
var engine = this._scene.getEngine();
|
|
|
|
|
|
this._disposePostProcesses();
|
|
this._disposePostProcesses();
|
|
|
|
+ if (this._cameras !== null) {
|
|
|
|
+ this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
|
|
|
|
+ // get back cameras to be used to reattach pipeline
|
|
|
|
+ this._cameras = this._originalCameras.slice();
|
|
|
|
+ }
|
|
this._reset();
|
|
this._reset();
|
|
|
|
+ this._prevPostProcess = null;
|
|
|
|
+ this._prevPrevPostProcess = null;
|
|
|
|
+
|
|
|
|
+ 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._setAutoClearAndTextureSharing(this.fxaa);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
if (this.sharpenEnabled) {
|
|
if (this.sharpenEnabled) {
|
|
- this.sharpen = new SharpenPostProcess("sharpen", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
- this.addEffect(new PostProcessRenderEffect(engine, this.SharpenPostProcessId, () => { return this.sharpen; }, true));
|
|
|
|
|
|
+ this.addEffect(this._sharpenEffect);
|
|
|
|
+ this._setAutoClearAndTextureSharing(this.sharpen);
|
|
}
|
|
}
|
|
|
|
|
|
- if(this.depthOfFieldEnabled){
|
|
|
|
- // Enable and get current depth map
|
|
|
|
|
|
+ if (this.depthOfFieldEnabled) {
|
|
var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
|
|
var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
|
|
-
|
|
|
|
- this.depthOfField = new DepthOfFieldEffect(this._scene, depthTexture, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType);
|
|
|
|
|
|
+ this.depthOfField.depthTexture = depthTexture;
|
|
this.addEffect(this.depthOfField);
|
|
this.addEffect(this.depthOfField);
|
|
|
|
+ this._setAutoClearAndTextureSharing(this.depthOfField._depthOfFieldMerge);
|
|
}
|
|
}
|
|
|
|
|
|
if (this.bloomEnabled) {
|
|
if (this.bloomEnabled) {
|
|
this.pass = new PassPostProcess("sceneRenderTarget", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
this.pass = new PassPostProcess("sceneRenderTarget", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
+ this._setAutoClearAndTextureSharing(this.pass, true);
|
|
this.addEffect(new PostProcessRenderEffect(engine, this.PassPostProcessId, () => { return this.pass; }, true));
|
|
this.addEffect(new PostProcessRenderEffect(engine, this.PassPostProcessId, () => { return this.pass; }, true));
|
|
|
|
|
|
if (!this._hdr) { // Need to enhance highlights if not using float rendering
|
|
if (!this._hdr) { // Need to enhance highlights if not using float rendering
|
|
@@ -420,18 +484,14 @@
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- 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 = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
|
|
|
|
- } else if (this._hdr && this.imageProcessing) {
|
|
|
|
|
|
+ if (this._hdr && this.imageProcessing) {
|
|
this.finalMerge = this.imageProcessing;
|
|
this.finalMerge = this.imageProcessing;
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
this.finalMerge = new PassPostProcess("finalMerge", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
this.finalMerge = new PassPostProcess("finalMerge", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
this.addEffect(new PostProcessRenderEffect(engine, this.FinalMergePostProcessId, () => { return this.finalMerge; }, true));
|
|
this.addEffect(new PostProcessRenderEffect(engine, this.FinalMergePostProcessId, () => { return this.finalMerge; }, true));
|
|
-
|
|
|
|
|
|
+ this._setAutoClearAndTextureSharing(this.finalMerge, true);
|
|
|
|
+
|
|
this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
|
|
this.finalMerge.autoClear = !this.bloomEnabled && (!this._hdr || !this.imageProcessing);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -441,30 +501,23 @@
|
|
if (this.imageProcessing) {
|
|
if (this.imageProcessing) {
|
|
this.imageProcessing.shareOutputWith(this.pass);
|
|
this.imageProcessing.shareOutputWith(this.pass);
|
|
this.imageProcessing.autoClear = false;
|
|
this.imageProcessing.autoClear = false;
|
|
- } else if (this.fxaa) {
|
|
|
|
- this.fxaa.shareOutputWith(this.pass);
|
|
|
|
} else {
|
|
} else {
|
|
this.finalMerge.shareOutputWith(this.pass);
|
|
this.finalMerge.shareOutputWith(this.pass);
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- if (this.fxaa) {
|
|
|
|
- this.fxaa.shareOutputWith(this.pass);
|
|
|
|
- } else {
|
|
|
|
- this.finalMerge.shareOutputWith(this.pass);
|
|
|
|
- }
|
|
|
|
|
|
+ this.finalMerge.shareOutputWith(this.pass);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (this.chromaticAberrationEnabled) {
|
|
if (this.chromaticAberrationEnabled) {
|
|
- this.chromaticAberration = new ChromaticAberrationPostProcess("ChromaticAberration", engine.getRenderWidth(), engine.getRenderHeight(), 1.0, null, Texture.BILINEAR_SAMPLINGMODE, engine, false, this._defaultPipelineTextureType);
|
|
|
|
- this.addEffect(new PostProcessRenderEffect(engine, this.ChromaticAberrationPostProcessId, () => { return this.chromaticAberration; }, true));
|
|
|
|
|
|
+ this.addEffect(this._chromaticAberrationEffect);
|
|
|
|
+ this._setAutoClearAndTextureSharing(this.chromaticAberration);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
if (this._cameras !== null) {
|
|
if (this._cameras !== null) {
|
|
this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
|
|
this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if(this.msaaEnabled){
|
|
if(this.msaaEnabled){
|
|
if(!this._enableMSAAOnFirstPostProcess()){
|
|
if(!this._enableMSAAOnFirstPostProcess()){
|
|
BABYLON.Tools.Warn("MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0");
|
|
BABYLON.Tools.Warn("MSAA failed to enable, MSAA is only supported in browsers that support webGL >= 2.0");
|
|
@@ -472,14 +525,10 @@
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private _disposePostProcesses(): void {
|
|
|
|
|
|
+ private _disposePostProcesses(disposeNonRecreated = false): 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];
|
|
|
|
|
|
- if (this.sharpen) {
|
|
|
|
- this.sharpen.dispose(camera);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (this.pass) {
|
|
if (this.pass) {
|
|
this.pass.dispose(camera);
|
|
this.pass.dispose(camera);
|
|
}
|
|
}
|
|
@@ -512,16 +561,22 @@
|
|
this.finalMerge.dispose(camera);
|
|
this.finalMerge.dispose(camera);
|
|
}
|
|
}
|
|
|
|
|
|
- if(this.depthOfField){
|
|
|
|
- this.depthOfField.disposeEffects(camera);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(this.chromaticAberration){
|
|
|
|
- this.chromaticAberration.dispose(camera);
|
|
|
|
|
|
+ // These are created in the constructor and should not be disposed on every pipeline change
|
|
|
|
+ if(disposeNonRecreated){
|
|
|
|
+ if (this.sharpen) {
|
|
|
|
+ this.sharpen.dispose(camera);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(this.depthOfField){
|
|
|
|
+ this.depthOfField.disposeEffects(camera);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(this.chromaticAberration){
|
|
|
|
+ this.chromaticAberration.dispose(camera);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- (<any>this.sharpen) = null;
|
|
|
|
(<any>this.pass) = null;
|
|
(<any>this.pass) = null;
|
|
(<any>this.highlights) = null;
|
|
(<any>this.highlights) = null;
|
|
(<any>this.blurX) = null;
|
|
(<any>this.blurX) = null;
|
|
@@ -530,15 +585,19 @@
|
|
(<any>this.imageProcessing) = null;
|
|
(<any>this.imageProcessing) = null;
|
|
(<any>this.fxaa) = null;
|
|
(<any>this.fxaa) = null;
|
|
(<any>this.finalMerge) = null;
|
|
(<any>this.finalMerge) = null;
|
|
- (<any>this.depthOfField) = null;
|
|
|
|
- (<any>this.chromaticAberration) = null;
|
|
|
|
|
|
+
|
|
|
|
+ if(disposeNonRecreated){
|
|
|
|
+ (<any>this.sharpen) = null;
|
|
|
|
+ (<any>this.depthOfField) = null;
|
|
|
|
+ (<any>this.chromaticAberration) = null;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* Dispose of the pipeline and stop all post processes
|
|
* Dispose of the pipeline and stop all post processes
|
|
*/
|
|
*/
|
|
public dispose(): void {
|
|
public dispose(): void {
|
|
- this._disposePostProcesses();
|
|
|
|
|
|
+ this._disposePostProcesses(true);
|
|
|
|
|
|
this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
|
|
this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
|
|
|
|
|