From 5b016c594fd41e4d1dfd9118fd71fb6f6c778902 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 19:08:21 +0100 Subject: [PATCH 1/9] Add hooks to alter shader code in post processes --- .../Pipelines/defaultRenderingPipeline.ts | 20 +++-- .../core/src/PostProcesses/blurPostProcess.ts | 9 +- .../circleOfConfusionPostProcess.ts | 10 ++- .../depthOfFieldBlurPostProcess.ts | 9 +- .../src/PostProcesses/depthOfFieldEffect.ts | 34 +++++-- .../depthOfFieldMergePostProcess.ts | 10 ++- .../dev/core/src/PostProcesses/postProcess.ts | 88 +++++++++++++++++-- 7 files changed, 148 insertions(+), 32 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts index 7349a1b7778..00230c7767a 100644 --- a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts +++ b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts @@ -13,7 +13,7 @@ import { Constants } from "../../../Engines/constants"; import type { IDisposable, Scene } from "../../../scene"; import { GlowLayer } from "../../../Layers/glowLayer"; -import type { PostProcess } from "../../../PostProcesses/postProcess"; +import type { PostProcess, PostProcessCustomShaderCodeProcessing } from "../../../PostProcesses/postProcess"; import { SharpenPostProcess } from "../../../PostProcesses/sharpenPostProcess"; import { ImageProcessingPostProcess } from "../../../PostProcesses/imageProcessingPostProcess"; import { ChromaticAberrationPostProcess } from "../../../PostProcesses/chromaticAberrationPostProcess"; @@ -37,6 +37,7 @@ declare type Animation = import("../../../Animations/animation").Animation; export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable { private _scene: Scene; private _camerasToBeAttached: Array = []; + private _customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; /** * ID of the sharpen post process, */ @@ -297,7 +298,7 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen // recreate dof and dispose old as this setting is not dynamic const oldDof = this.depthOfField; - this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false); + this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false, this._customShaderCodeProcessing); this.depthOfField.focalLength = oldDof.focalLength; this.depthOfField.focusDistance = oldDof.focusDistance; this.depthOfField.fStop = oldDof.fStop; @@ -425,14 +426,23 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen * @param scene The scene linked to this pipeline (default: the last created scene) * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras) * @param automaticBuild If false, you will have to manually call prepare() to update the pipeline (default: true) - */ - constructor(name = "", hdr = true, scene: Scene = EngineStore.LastCreatedScene!, cameras?: Camera[], automaticBuild = true) { + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-processes. The callbacks will be called for all post processes used by the rendering pipeline + */ + constructor( + name = "", + hdr = true, + scene: Scene = EngineStore.LastCreatedScene!, + cameras?: Camera[], + automaticBuild = true, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + ) { super(scene.getEngine(), name); this._cameras = cameras || scene.cameras; this._cameras = this._cameras.slice(); this._camerasToBeAttached = this._cameras.slice(); this._buildAllowed = automaticBuild; + this._customShaderCodeProcessing = customShaderCodeProcessing; // Initialize this._scene = scene; @@ -466,7 +476,7 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen true ); - this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true); + this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true, this._customShaderCodeProcessing); this.bloom = new BloomEffect(this._scene, this._bloomScale, this._bloomWeight, this.bloomKernel, this._defaultPipelineTextureType, true); diff --git a/packages/dev/core/src/PostProcesses/blurPostProcess.ts b/packages/dev/core/src/PostProcesses/blurPostProcess.ts index 43040ee3385..9b2ce329d18 100644 --- a/packages/dev/core/src/PostProcesses/blurPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/blurPostProcess.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { Vector2 } from "../Maths/math.vector"; import type { Nullable } from "../types"; -import type { PostProcessOptions } from "./postProcess"; +import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; @@ -97,6 +97,7 @@ export class BlurPostProcess extends PostProcess { * @param defines * @param _blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -110,7 +111,8 @@ export class BlurPostProcess extends PostProcess { textureType = Constants.TEXTURETYPE_UNSIGNED_INT, defines = "", private _blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA + textureFormat = Constants.TEXTUREFORMAT_RGBA, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super( name, @@ -127,7 +129,8 @@ export class BlurPostProcess extends PostProcess { "kernelBlur", { varyingCount: 0, depCount: 0 }, true, - textureFormat + textureFormat, + customShaderCodeProcessing ); this._staticDefines = defines; this.direction = direction; diff --git a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts index 895da9d4656..071d4798e6b 100644 --- a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts @@ -1,6 +1,6 @@ import type { Nullable } from "../types"; import type { Engine } from "../Engines/engine"; -import type { PostProcessOptions } from "./postProcess"; +import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Effect } from "../Materials/effect"; import type { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture"; @@ -57,6 +57,7 @@ export class CircleOfConfusionPostProcess extends PostProcess { * @param reusable If the post process can be reused on the same frame. (default: false) * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -67,7 +68,8 @@ export class CircleOfConfusionPostProcess extends PostProcess { engine?: Engine, reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, - blockCompilation = false + blockCompilation = false, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super( name, @@ -83,7 +85,9 @@ export class CircleOfConfusionPostProcess extends PostProcess { textureType, undefined, null, - blockCompilation + blockCompilation, + undefined, + customShaderCodeProcessing ); this._depthTexture = depthTexture; this.onApplyObservable.add((effect: Effect) => { diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts b/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts index b0ed4eb85af..9c5f7f1b341 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts @@ -3,7 +3,7 @@ import type { Vector2 } from "../Maths/math.vector"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; import { Texture } from "../Materials/Textures/texture"; -import type { PostProcess, PostProcessOptions } from "./postProcess"; +import type { PostProcess, PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; import { BlurPostProcess } from "./blurPostProcess"; import type { Engine } from "../Engines/engine"; import type { Scene } from "../scene"; @@ -48,6 +48,7 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -63,7 +64,8 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA + textureFormat = Constants.TEXTUREFORMAT_RGBA, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super( name, @@ -78,7 +80,8 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { textureType, `#define DOF 1\r\n`, blockCompilation, - textureFormat + textureFormat, + customShaderCodeProcessing ); this.direction = direction; diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts index 7ad0d419d66..c5cfbf512d4 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts @@ -3,7 +3,7 @@ import { Vector2 } from "../Maths/math.vector"; import type { Camera } from "../Cameras/camera"; import { Texture } from "../Materials/Textures/texture"; import type { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture"; -import type { PostProcess } from "./postProcess"; +import type { PostProcess, PostProcessCustomShaderCodeProcessing } from "./postProcess"; import { PostProcessRenderEffect } from "../PostProcesses/RenderPipeline/postProcessRenderEffect"; import { CircleOfConfusionPostProcess } from "./circleOfConfusionPostProcess"; import { DepthOfFieldBlurPostProcess } from "./depthOfFieldBlurPostProcess"; @@ -33,6 +33,21 @@ export enum DepthOfFieldEffectBlurLevel { */ export class DepthOfFieldEffect extends PostProcessRenderEffect { private _circleOfConfusion: CircleOfConfusionPostProcess; + + /** + * Gets the Circle Of Confusion post process used by the depth of field effect + */ + public get circleOfConfusion() { + return this._circleOfConfusion; + } + + /** + * Gets the Depth of Field Merge post process used by the depth of field effect + */ + public get dofMerge() { + return this._dofMerge; + } + /** * @internal Internal, blurs from high to low */ @@ -89,13 +104,15 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { * @param blurLevel * @param pipelineTextureType The type of texture to be used when performing the post processing. * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( scene: Scene, depthTexture: Nullable, blurLevel: DepthOfFieldEffectBlurLevel = DepthOfFieldEffectBlurLevel.Low, pipelineTextureType = 0, - blockCompilation = false + blockCompilation = false, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super( scene.getEngine(), @@ -121,7 +138,8 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation + blockCompilation, + customShaderCodeProcessing ); // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur) @@ -165,7 +183,8 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { false, pipelineTextureType, blockCompilation, - i == 0 ? circleOfConfusionTextureFormat : Constants.TEXTUREFORMAT_RGBA + i == 0 ? circleOfConfusionTextureFormat : Constants.TEXTUREFORMAT_RGBA, + customShaderCodeProcessing ); blurY.autoClear = false; ratio = 0.75 / Math.pow(2, i); @@ -182,7 +201,9 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation + blockCompilation, + undefined, + customShaderCodeProcessing ); blurX.autoClear = false; this._depthOfFieldBlurY.push(blurY); @@ -208,7 +229,8 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation + blockCompilation, + customShaderCodeProcessing ); this._dofMerge.autoClear = false; this._effects.push(this._dofMerge); diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts index fee3c8dcc0d..1f3c1dced16 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts @@ -1,7 +1,7 @@ import type { Nullable } from "../types"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; -import type { PostProcessOptions } from "./postProcess"; +import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Engine } from "../Engines/engine"; import { Constants } from "../Engines/constants"; @@ -57,6 +57,7 @@ export class DepthOfFieldMergePostProcess extends PostProcess { * @param reusable If the post process can be reused on the same frame. (default: false) * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -69,7 +70,8 @@ export class DepthOfFieldMergePostProcess extends PostProcess { engine?: Engine, reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, - blockCompilation = false + blockCompilation = false, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super( name, @@ -85,7 +87,9 @@ export class DepthOfFieldMergePostProcess extends PostProcess { textureType, undefined, null, - true + true, + undefined, + customShaderCodeProcessing ); this.externalTextureSamplerBinding = true; this.onApplyObservable.add((effect: Effect) => { diff --git a/packages/dev/core/src/PostProcesses/postProcess.ts b/packages/dev/core/src/PostProcesses/postProcess.ts index fc71b9ebb4c..f76c56dffb6 100644 --- a/packages/dev/core/src/PostProcesses/postProcess.ts +++ b/packages/dev/core/src/PostProcesses/postProcess.ts @@ -19,6 +19,7 @@ import { GetClass, RegisterClass } from "../Misc/typeStore"; import { DrawWrapper } from "../Materials/drawWrapper"; import type { AbstractScene } from "../abstractScene"; import type { RenderTargetWrapper } from "../Engines/renderTargetWrapper"; +import type { ShaderCustomProcessingFunction } from "../Engines/Processors/shaderProcessingOptions"; declare type Scene = import("../scene").Scene; declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture; @@ -27,6 +28,43 @@ declare type Animation = import("../Animations/animation").Animation; declare type PrePassRenderer = import("../Rendering/prePassRenderer").PrePassRenderer; declare type PrePassEffectConfiguration = import("../Rendering/prePassEffectConfiguration").PrePassEffectConfiguration; +/** + * Function for custom code injection when dealing with post processes + */ +export type PostProcessShaderCustomProcessingFunction = (postProcessName: string, shaderType: string, code: string) => string; + +/** + * Function for defining custom bindings (defines, uniforms, samplers) when dealing with post processes + */ +export type PostProcessShaderDefineCustomBindingFunction = (postProcessName: string, defines: Nullable, uniforms: string[], samplers: string[]) => Nullable; + +/** + * Function for binding custom bindings (uniforms, samplers) when dealing with post processes + */ +export type PostProcessShaderBindCustomBindingFunction = (postProcessName: string, effect: Effect) => void; + +/** + * Allows for custom processing of the shader code used by a post process + */ +export type PostProcessCustomShaderCodeProcessing = { + /** + * If provided, will be called two times with the vertex and fragment code so that this code can be updated after the #include have been processed + */ + processCodeAfterIncludes?: PostProcessShaderCustomProcessingFunction; + /** + * If provided, will be called two times with the vertex and fragment code so that this code can be updated before it is compiled by the GPU + */ + processFinalCode?: PostProcessShaderCustomProcessingFunction; + /** + * If provided, will be called before creating the effect to collect additional custom bindings (defines, uniforms, samplers) + */ + defineCustomBindings?: PostProcessShaderDefineCustomBindingFunction; + /** + * If provided, will be called when binding inputs to the shader code to allow the user to add custom bindings + */ + bindCustomBindings?: PostProcessShaderBindCustomBindingFunction; +}; + /** * Size options for a post process */ @@ -209,6 +247,10 @@ export class PostProcess { protected _indexParameters: any; private _shareOutputWithPostProcess: Nullable; private _texelSize = Vector2.Zero(); + private _customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; + private _processCodeAfterIncludes: Nullable; + private _processFinalCode: Nullable; + /** @internal */ public _forcedOutputTexture: Nullable; @@ -374,6 +416,7 @@ export class PostProcess { * @param indexParameters The index parameters to be used for babylons include syntax "#include[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx * @param blockCompilation If the shader should not be compiled immediatly. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) + * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -390,7 +433,8 @@ export class PostProcess { vertexUrl: string = "postprocess", indexParameters?: any, blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA + textureFormat = Constants.TEXTUREFORMAT_RGBA, + customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { this.name = name; if (camera != null) { @@ -417,6 +461,13 @@ export class PostProcess { this._fragmentUrl = fragmentUrl; this._vertexUrl = vertexUrl; this._parameters = parameters || []; + this._customShaderCodeProcessing = customShaderCodeProcessing; + this._processCodeAfterIncludes = this._customShaderCodeProcessing?.processCodeAfterIncludes + ? (shaderType: string, code: string) => this._customShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) + : null; + this._processFinalCode = this._customShaderCodeProcessing?.processFinalCode + ? (shaderType: string, code: string) => this._customShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) + : null; this._parameters.push("scale"); @@ -498,17 +549,34 @@ export class PostProcess { vertexUrl?: string, fragmentUrl?: string ) { + if (this._customShaderCodeProcessing?.defineCustomBindings) { + const newUniforms = uniforms?.slice() ?? []; + newUniforms.push(...this._parameters); + + const newSamplers = samplers?.slice() ?? []; + newSamplers.push(...this._samplers); + + defines = this._customShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); + uniforms = newUniforms; + samplers = newSamplers; + } this._postProcessDefines = defines; this._drawWrapper.effect = this._engine.createEffect( { vertex: vertexUrl ?? this._vertexUrl, fragment: fragmentUrl ?? this._fragmentUrl }, - ["position"], - uniforms || this._parameters, - samplers || this._samplers, - defines !== null ? defines : "", - undefined, - onCompiled, - onError, - indexParameters || this._indexParameters + { + attributes: ["position"], + uniformsNames: uniforms || this._parameters, + uniformBuffersNames: [], + samplers: samplers || this._samplers, + defines: defines !== null ? defines : "", + fallbacks: null, + onCompiled: onCompiled ?? null, + onError: onError ?? null, + indexParameters: indexParameters || this._indexParameters, + processCodeAfterIncludes: this._processCodeAfterIncludes, + processFinalCode: this._processFinalCode, + }, + this._engine ); } @@ -787,6 +855,8 @@ export class PostProcess { this._drawWrapper.effect.setVector2("scale", this._scaleRatio); this.onApplyObservable.notifyObservers(this._drawWrapper.effect); + this._customShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); + return this._drawWrapper.effect; } From be581a3a238d4936629e48b13d984adcfb95c39e Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 19:27:03 +0100 Subject: [PATCH 2/9] Remove unused functions --- .../core/src/PostProcesses/depthOfFieldEffect.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts index c5cfbf512d4..b874a0f53c7 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts @@ -34,20 +34,6 @@ export enum DepthOfFieldEffectBlurLevel { export class DepthOfFieldEffect extends PostProcessRenderEffect { private _circleOfConfusion: CircleOfConfusionPostProcess; - /** - * Gets the Circle Of Confusion post process used by the depth of field effect - */ - public get circleOfConfusion() { - return this._circleOfConfusion; - } - - /** - * Gets the Depth of Field Merge post process used by the depth of field effect - */ - public get dofMerge() { - return this._dofMerge; - } - /** * @internal Internal, blurs from high to low */ From 25f757deb0bddbbc46eeb6b1b694f9340778e4f8 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 20:17:38 +0100 Subject: [PATCH 3/9] Make the changes static --- .../Pipelines/defaultRenderingPipeline.ts | 8 +--- .../core/src/PostProcesses/blurPostProcess.ts | 9 ++-- .../circleOfConfusionPostProcess.ts | 9 ++-- .../depthOfFieldBlurPostProcess.ts | 9 ++-- .../src/PostProcesses/depthOfFieldEffect.ts | 19 +++------ .../depthOfFieldMergePostProcess.ts | 9 ++-- .../dev/core/src/PostProcesses/postProcess.ts | 41 +++++++++++-------- 7 files changed, 43 insertions(+), 61 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts index 00230c7767a..3ba98ef4851 100644 --- a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts +++ b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts @@ -37,7 +37,6 @@ declare type Animation = import("../../../Animations/animation").Animation; export class DefaultRenderingPipeline extends PostProcessRenderPipeline implements IDisposable, IAnimatable { private _scene: Scene; private _camerasToBeAttached: Array = []; - private _customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; /** * ID of the sharpen post process, */ @@ -298,7 +297,7 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen // recreate dof and dispose old as this setting is not dynamic const oldDof = this.depthOfField; - this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false, this._customShaderCodeProcessing); + this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, false); this.depthOfField.focalLength = oldDof.focalLength; this.depthOfField.focusDistance = oldDof.focusDistance; this.depthOfField.fStop = oldDof.fStop; @@ -426,7 +425,6 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen * @param scene The scene linked to this pipeline (default: the last created scene) * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras) * @param automaticBuild If false, you will have to manually call prepare() to update the pipeline (default: true) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-processes. The callbacks will be called for all post processes used by the rendering pipeline */ constructor( name = "", @@ -434,7 +432,6 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen scene: Scene = EngineStore.LastCreatedScene!, cameras?: Camera[], automaticBuild = true, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing ) { super(scene.getEngine(), name); this._cameras = cameras || scene.cameras; @@ -442,7 +439,6 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen this._camerasToBeAttached = this._cameras.slice(); this._buildAllowed = automaticBuild; - this._customShaderCodeProcessing = customShaderCodeProcessing; // Initialize this._scene = scene; @@ -476,7 +472,7 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen true ); - this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true, this._customShaderCodeProcessing); + this.depthOfField = new DepthOfFieldEffect(this._scene, null, this._depthOfFieldBlurLevel, this._defaultPipelineTextureType, true); this.bloom = new BloomEffect(this._scene, this._bloomScale, this._bloomWeight, this.bloomKernel, this._defaultPipelineTextureType, true); diff --git a/packages/dev/core/src/PostProcesses/blurPostProcess.ts b/packages/dev/core/src/PostProcesses/blurPostProcess.ts index 9b2ce329d18..43040ee3385 100644 --- a/packages/dev/core/src/PostProcesses/blurPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/blurPostProcess.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { Vector2 } from "../Maths/math.vector"; import type { Nullable } from "../types"; -import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; +import type { PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; @@ -97,7 +97,6 @@ export class BlurPostProcess extends PostProcess { * @param defines * @param _blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -111,8 +110,7 @@ export class BlurPostProcess extends PostProcess { textureType = Constants.TEXTURETYPE_UNSIGNED_INT, defines = "", private _blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + textureFormat = Constants.TEXTUREFORMAT_RGBA ) { super( name, @@ -129,8 +127,7 @@ export class BlurPostProcess extends PostProcess { "kernelBlur", { varyingCount: 0, depCount: 0 }, true, - textureFormat, - customShaderCodeProcessing + textureFormat ); this._staticDefines = defines; this.direction = direction; diff --git a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts index 071d4798e6b..51987d33662 100644 --- a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts @@ -1,6 +1,6 @@ import type { Nullable } from "../types"; import type { Engine } from "../Engines/engine"; -import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; +import type { PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Effect } from "../Materials/effect"; import type { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture"; @@ -57,7 +57,6 @@ export class CircleOfConfusionPostProcess extends PostProcess { * @param reusable If the post process can be reused on the same frame. (default: false) * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -68,8 +67,7 @@ export class CircleOfConfusionPostProcess extends PostProcess { engine?: Engine, reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, - blockCompilation = false, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + blockCompilation = false ) { super( name, @@ -86,8 +84,7 @@ export class CircleOfConfusionPostProcess extends PostProcess { undefined, null, blockCompilation, - undefined, - customShaderCodeProcessing + undefined ); this._depthTexture = depthTexture; this.onApplyObservable.add((effect: Effect) => { diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts b/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts index 9c5f7f1b341..b0ed4eb85af 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldBlurPostProcess.ts @@ -3,7 +3,7 @@ import type { Vector2 } from "../Maths/math.vector"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; import { Texture } from "../Materials/Textures/texture"; -import type { PostProcess, PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; +import type { PostProcess, PostProcessOptions } from "./postProcess"; import { BlurPostProcess } from "./blurPostProcess"; import type { Engine } from "../Engines/engine"; import type { Scene } from "../scene"; @@ -48,7 +48,6 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -64,8 +63,7 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + textureFormat = Constants.TEXTUREFORMAT_RGBA ) { super( name, @@ -80,8 +78,7 @@ export class DepthOfFieldBlurPostProcess extends BlurPostProcess { textureType, `#define DOF 1\r\n`, blockCompilation, - textureFormat, - customShaderCodeProcessing + textureFormat ); this.direction = direction; diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts index b874a0f53c7..91e43ca5b88 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts @@ -3,7 +3,7 @@ import { Vector2 } from "../Maths/math.vector"; import type { Camera } from "../Cameras/camera"; import { Texture } from "../Materials/Textures/texture"; import type { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture"; -import type { PostProcess, PostProcessCustomShaderCodeProcessing } from "./postProcess"; +import type { PostProcess } from "./postProcess"; import { PostProcessRenderEffect } from "../PostProcesses/RenderPipeline/postProcessRenderEffect"; import { CircleOfConfusionPostProcess } from "./circleOfConfusionPostProcess"; import { DepthOfFieldBlurPostProcess } from "./depthOfFieldBlurPostProcess"; @@ -33,7 +33,6 @@ export enum DepthOfFieldEffectBlurLevel { */ export class DepthOfFieldEffect extends PostProcessRenderEffect { private _circleOfConfusion: CircleOfConfusionPostProcess; - /** * @internal Internal, blurs from high to low */ @@ -90,15 +89,13 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { * @param blurLevel * @param pipelineTextureType The type of texture to be used when performing the post processing. * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( scene: Scene, depthTexture: Nullable, blurLevel: DepthOfFieldEffectBlurLevel = DepthOfFieldEffectBlurLevel.Low, pipelineTextureType = 0, - blockCompilation = false, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + blockCompilation = false ) { super( scene.getEngine(), @@ -124,8 +121,7 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation, - customShaderCodeProcessing + blockCompilation ); // Create a pyramid of blurred images (eg. fullSize 1/4 blur, half size 1/2 blur, quarter size 3/4 blur, eith size 4/4 blur) @@ -169,8 +165,7 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { false, pipelineTextureType, blockCompilation, - i == 0 ? circleOfConfusionTextureFormat : Constants.TEXTUREFORMAT_RGBA, - customShaderCodeProcessing + i == 0 ? circleOfConfusionTextureFormat : Constants.TEXTUREFORMAT_RGBA ); blurY.autoClear = false; ratio = 0.75 / Math.pow(2, i); @@ -188,8 +183,7 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { false, pipelineTextureType, blockCompilation, - undefined, - customShaderCodeProcessing + undefined ); blurX.autoClear = false; this._depthOfFieldBlurY.push(blurY); @@ -215,8 +209,7 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation, - customShaderCodeProcessing + blockCompilation ); this._dofMerge.autoClear = false; this._effects.push(this._dofMerge); diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts index 1f3c1dced16..4270e3b389e 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts @@ -1,7 +1,7 @@ import type { Nullable } from "../types"; import type { Camera } from "../Cameras/camera"; import type { Effect } from "../Materials/effect"; -import type { PostProcessCustomShaderCodeProcessing, PostProcessOptions } from "./postProcess"; +import type { PostProcessOptions } from "./postProcess"; import { PostProcess } from "./postProcess"; import type { Engine } from "../Engines/engine"; import { Constants } from "../Engines/constants"; @@ -57,7 +57,6 @@ export class DepthOfFieldMergePostProcess extends PostProcess { * @param reusable If the post process can be reused on the same frame. (default: false) * @param textureType Type of textures used when performing the post process. (default: 0) * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -70,8 +69,7 @@ export class DepthOfFieldMergePostProcess extends PostProcess { engine?: Engine, reusable?: boolean, textureType = Constants.TEXTURETYPE_UNSIGNED_INT, - blockCompilation = false, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + blockCompilation = false ) { super( name, @@ -88,8 +86,7 @@ export class DepthOfFieldMergePostProcess extends PostProcess { undefined, null, true, - undefined, - customShaderCodeProcessing + undefined ); this.externalTextureSamplerBinding = true; this.onApplyObservable.add((effect: Effect) => { diff --git a/packages/dev/core/src/PostProcesses/postProcess.ts b/packages/dev/core/src/PostProcesses/postProcess.ts index f76c56dffb6..8ca838817d5 100644 --- a/packages/dev/core/src/PostProcesses/postProcess.ts +++ b/packages/dev/core/src/PostProcesses/postProcess.ts @@ -80,6 +80,19 @@ export class PostProcess { /** @internal */ public _parentContainer: Nullable = null; + private static _CustomShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; + + /** + * Gets or sets the custom callbacks used to alther the post process shader code + */ + public static get CustomShaderCodeProcessing() { + return PostProcess._CustomShaderCodeProcessing; + } + + public static set CustomShaderCodeProcessing(customShaderCodeProcessing: PostProcessCustomShaderCodeProcessing | undefined) { + PostProcess._CustomShaderCodeProcessing = customShaderCodeProcessing; + } + /** * Gets or sets the unique id of the post process */ @@ -247,9 +260,6 @@ export class PostProcess { protected _indexParameters: any; private _shareOutputWithPostProcess: Nullable; private _texelSize = Vector2.Zero(); - private _customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; - private _processCodeAfterIncludes: Nullable; - private _processFinalCode: Nullable; /** @internal */ public _forcedOutputTexture: Nullable; @@ -416,7 +426,6 @@ export class PostProcess { * @param indexParameters The index parameters to be used for babylons include syntax "#include[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx * @param blockCompilation If the shader should not be compiled immediatly. (default: false) * @param textureFormat Format of textures used when performing the post process. (default: TEXTUREFORMAT_RGBA) - * @param customShaderCodeProcessing Callbacks to alter the shader code used by the post-process */ constructor( name: string, @@ -433,8 +442,7 @@ export class PostProcess { vertexUrl: string = "postprocess", indexParameters?: any, blockCompilation = false, - textureFormat = Constants.TEXTUREFORMAT_RGBA, - customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing + textureFormat = Constants.TEXTUREFORMAT_RGBA ) { this.name = name; if (camera != null) { @@ -461,13 +469,6 @@ export class PostProcess { this._fragmentUrl = fragmentUrl; this._vertexUrl = vertexUrl; this._parameters = parameters || []; - this._customShaderCodeProcessing = customShaderCodeProcessing; - this._processCodeAfterIncludes = this._customShaderCodeProcessing?.processCodeAfterIncludes - ? (shaderType: string, code: string) => this._customShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) - : null; - this._processFinalCode = this._customShaderCodeProcessing?.processFinalCode - ? (shaderType: string, code: string) => this._customShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) - : null; this._parameters.push("scale"); @@ -549,14 +550,14 @@ export class PostProcess { vertexUrl?: string, fragmentUrl?: string ) { - if (this._customShaderCodeProcessing?.defineCustomBindings) { + if (PostProcess._CustomShaderCodeProcessing?.defineCustomBindings) { const newUniforms = uniforms?.slice() ?? []; newUniforms.push(...this._parameters); const newSamplers = samplers?.slice() ?? []; newSamplers.push(...this._samplers); - defines = this._customShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); + defines = PostProcess._CustomShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); uniforms = newUniforms; samplers = newSamplers; } @@ -573,8 +574,12 @@ export class PostProcess { onCompiled: onCompiled ?? null, onError: onError ?? null, indexParameters: indexParameters || this._indexParameters, - processCodeAfterIncludes: this._processCodeAfterIncludes, - processFinalCode: this._processFinalCode, + processCodeAfterIncludes: PostProcess._CustomShaderCodeProcessing?.processCodeAfterIncludes + ? (shaderType: string, code: string) => PostProcess._CustomShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) + : null, + processFinalCode: PostProcess._CustomShaderCodeProcessing?.processFinalCode + ? (shaderType: string, code: string) => PostProcess._CustomShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) + : null, }, this._engine ); @@ -855,7 +860,7 @@ export class PostProcess { this._drawWrapper.effect.setVector2("scale", this._scaleRatio); this.onApplyObservable.notifyObservers(this._drawWrapper.effect); - this._customShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); + PostProcess._CustomShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); return this._drawWrapper.effect; } From f5394d897600d0b1dbac86e4692f57fbfc901d66 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 20:19:23 +0100 Subject: [PATCH 4/9] Remove unnecessary code --- .../RenderPipeline/Pipelines/defaultRenderingPipeline.ts | 2 +- .../dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts | 3 +-- packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts | 3 +-- .../dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts | 3 +-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts index 3ba98ef4851..2e845021a49 100644 --- a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts +++ b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts @@ -13,7 +13,7 @@ import { Constants } from "../../../Engines/constants"; import type { IDisposable, Scene } from "../../../scene"; import { GlowLayer } from "../../../Layers/glowLayer"; -import type { PostProcess, PostProcessCustomShaderCodeProcessing } from "../../../PostProcesses/postProcess"; +import type { PostProcess } from "../../../PostProcesses/postProcess"; import { SharpenPostProcess } from "../../../PostProcesses/sharpenPostProcess"; import { ImageProcessingPostProcess } from "../../../PostProcesses/imageProcessingPostProcess"; import { ChromaticAberrationPostProcess } from "../../../PostProcesses/chromaticAberrationPostProcess"; diff --git a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts index 51987d33662..895da9d4656 100644 --- a/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts +++ b/packages/dev/core/src/PostProcesses/circleOfConfusionPostProcess.ts @@ -83,8 +83,7 @@ export class CircleOfConfusionPostProcess extends PostProcess { textureType, undefined, null, - blockCompilation, - undefined + blockCompilation ); this._depthTexture = depthTexture; this.onApplyObservable.add((effect: Effect) => { diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts index 91e43ca5b88..7ad0d419d66 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldEffect.ts @@ -182,8 +182,7 @@ export class DepthOfFieldEffect extends PostProcessRenderEffect { engine, false, pipelineTextureType, - blockCompilation, - undefined + blockCompilation ); blurX.autoClear = false; this._depthOfFieldBlurY.push(blurY); diff --git a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts index 4270e3b389e..fee3c8dcc0d 100644 --- a/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts +++ b/packages/dev/core/src/PostProcesses/depthOfFieldMergePostProcess.ts @@ -85,8 +85,7 @@ export class DepthOfFieldMergePostProcess extends PostProcess { textureType, undefined, null, - true, - undefined + true ); this.externalTextureSamplerBinding = true; this.onApplyObservable.add((effect: Effect) => { From b609b21d2d14162e147e33fcf725f96579f6e8d1 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 20:21:28 +0100 Subject: [PATCH 5/9] Remove unnecessary code --- .../dev/core/src/PostProcesses/postProcess.ts | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/postProcess.ts b/packages/dev/core/src/PostProcesses/postProcess.ts index 8ca838817d5..defdb202f0f 100644 --- a/packages/dev/core/src/PostProcesses/postProcess.ts +++ b/packages/dev/core/src/PostProcesses/postProcess.ts @@ -19,7 +19,6 @@ import { GetClass, RegisterClass } from "../Misc/typeStore"; import { DrawWrapper } from "../Materials/drawWrapper"; import type { AbstractScene } from "../abstractScene"; import type { RenderTargetWrapper } from "../Engines/renderTargetWrapper"; -import type { ShaderCustomProcessingFunction } from "../Engines/Processors/shaderProcessingOptions"; declare type Scene = import("../scene").Scene; declare type InternalTexture = import("../Materials/Textures/internalTexture").InternalTexture; @@ -28,21 +27,6 @@ declare type Animation = import("../Animations/animation").Animation; declare type PrePassRenderer = import("../Rendering/prePassRenderer").PrePassRenderer; declare type PrePassEffectConfiguration = import("../Rendering/prePassEffectConfiguration").PrePassEffectConfiguration; -/** - * Function for custom code injection when dealing with post processes - */ -export type PostProcessShaderCustomProcessingFunction = (postProcessName: string, shaderType: string, code: string) => string; - -/** - * Function for defining custom bindings (defines, uniforms, samplers) when dealing with post processes - */ -export type PostProcessShaderDefineCustomBindingFunction = (postProcessName: string, defines: Nullable, uniforms: string[], samplers: string[]) => Nullable; - -/** - * Function for binding custom bindings (uniforms, samplers) when dealing with post processes - */ -export type PostProcessShaderBindCustomBindingFunction = (postProcessName: string, effect: Effect) => void; - /** * Allows for custom processing of the shader code used by a post process */ @@ -50,19 +34,19 @@ export type PostProcessCustomShaderCodeProcessing = { /** * If provided, will be called two times with the vertex and fragment code so that this code can be updated after the #include have been processed */ - processCodeAfterIncludes?: PostProcessShaderCustomProcessingFunction; + processCodeAfterIncludes?: (postProcessName: string, shaderType: string, code: string) => string; /** * If provided, will be called two times with the vertex and fragment code so that this code can be updated before it is compiled by the GPU */ - processFinalCode?: PostProcessShaderCustomProcessingFunction; + processFinalCode?: (postProcessName: string, shaderType: string, code: string) => string; /** * If provided, will be called before creating the effect to collect additional custom bindings (defines, uniforms, samplers) */ - defineCustomBindings?: PostProcessShaderDefineCustomBindingFunction; + defineCustomBindings?: (postProcessName: string, defines: Nullable, uniforms: string[], samplers: string[]) => Nullable; /** * If provided, will be called when binding inputs to the shader code to allow the user to add custom bindings */ - bindCustomBindings?: PostProcessShaderBindCustomBindingFunction; + bindCustomBindings?: (postProcessName: string, effect: Effect) => void; }; /** From 4519fc9c1885a2145c422cc9324fca69807543c5 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 20:23:01 +0100 Subject: [PATCH 6/9] Remove getter and setter --- .../dev/core/src/PostProcesses/postProcess.ts | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/postProcess.ts b/packages/dev/core/src/PostProcesses/postProcess.ts index defdb202f0f..f529e34ae4f 100644 --- a/packages/dev/core/src/PostProcesses/postProcess.ts +++ b/packages/dev/core/src/PostProcesses/postProcess.ts @@ -64,18 +64,10 @@ export class PostProcess { /** @internal */ public _parentContainer: Nullable = null; - private static _CustomShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; - /** * Gets or sets the custom callbacks used to alther the post process shader code */ - public static get CustomShaderCodeProcessing() { - return PostProcess._CustomShaderCodeProcessing; - } - - public static set CustomShaderCodeProcessing(customShaderCodeProcessing: PostProcessCustomShaderCodeProcessing | undefined) { - PostProcess._CustomShaderCodeProcessing = customShaderCodeProcessing; - } + public static CustomShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; /** * Gets or sets the unique id of the post process @@ -534,14 +526,14 @@ export class PostProcess { vertexUrl?: string, fragmentUrl?: string ) { - if (PostProcess._CustomShaderCodeProcessing?.defineCustomBindings) { + if (PostProcess.CustomShaderCodeProcessing?.defineCustomBindings) { const newUniforms = uniforms?.slice() ?? []; newUniforms.push(...this._parameters); const newSamplers = samplers?.slice() ?? []; newSamplers.push(...this._samplers); - defines = PostProcess._CustomShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); + defines = PostProcess.CustomShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); uniforms = newUniforms; samplers = newSamplers; } @@ -558,11 +550,11 @@ export class PostProcess { onCompiled: onCompiled ?? null, onError: onError ?? null, indexParameters: indexParameters || this._indexParameters, - processCodeAfterIncludes: PostProcess._CustomShaderCodeProcessing?.processCodeAfterIncludes - ? (shaderType: string, code: string) => PostProcess._CustomShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) + processCodeAfterIncludes: PostProcess.CustomShaderCodeProcessing?.processCodeAfterIncludes + ? (shaderType: string, code: string) => PostProcess.CustomShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) : null, - processFinalCode: PostProcess._CustomShaderCodeProcessing?.processFinalCode - ? (shaderType: string, code: string) => PostProcess._CustomShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) + processFinalCode: PostProcess.CustomShaderCodeProcessing?.processFinalCode + ? (shaderType: string, code: string) => PostProcess.CustomShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) : null, }, this._engine @@ -844,7 +836,7 @@ export class PostProcess { this._drawWrapper.effect.setVector2("scale", this._scaleRatio); this.onApplyObservable.notifyObservers(this._drawWrapper.effect); - PostProcess._CustomShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); + PostProcess.CustomShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); return this._drawWrapper.effect; } From 3513c2bb248d64769783af2db423623b1e6a52e9 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 21:28:14 +0100 Subject: [PATCH 7/9] Register a shader code processing per pp name --- .../Pipelines/defaultRenderingPipeline.ts | 8 +---- .../dev/core/src/PostProcesses/postProcess.ts | 35 ++++++++++++++----- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts index 2e845021a49..7349a1b7778 100644 --- a/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts +++ b/packages/dev/core/src/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline.ts @@ -426,13 +426,7 @@ export class DefaultRenderingPipeline extends PostProcessRenderPipeline implemen * @param cameras The array of cameras that the rendering pipeline will be attached to (default: scene.cameras) * @param automaticBuild If false, you will have to manually call prepare() to update the pipeline (default: true) */ - constructor( - name = "", - hdr = true, - scene: Scene = EngineStore.LastCreatedScene!, - cameras?: Camera[], - automaticBuild = true, - ) { + constructor(name = "", hdr = true, scene: Scene = EngineStore.LastCreatedScene!, cameras?: Camera[], automaticBuild = true) { super(scene.getEngine(), name); this._cameras = cameras || scene.cameras; this._cameras = this._cameras.slice(); diff --git a/packages/dev/core/src/PostProcesses/postProcess.ts b/packages/dev/core/src/PostProcesses/postProcess.ts index f529e34ae4f..60d992fa10f 100644 --- a/packages/dev/core/src/PostProcesses/postProcess.ts +++ b/packages/dev/core/src/PostProcesses/postProcess.ts @@ -64,10 +64,26 @@ export class PostProcess { /** @internal */ public _parentContainer: Nullable = null; + private static _CustomShaderCodeProcessing: { [postProcessName: string]: PostProcessCustomShaderCodeProcessing } = {}; + /** - * Gets or sets the custom callbacks used to alther the post process shader code + * Registers a shader code processing with a post process name. + * @param postProcessName name of the post process. Use null for the fallback shader code processing. This is the shader code processing that will be used in case no specific shader code processing has been associated to a post process name + * @param customShaderCodeProcessing shader code processing to associate to the post process name + * @returns */ - public static CustomShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing; + public static RegisterShaderCodeProcessing(postProcessName: Nullable, customShaderCodeProcessing?: PostProcessCustomShaderCodeProcessing) { + if (!customShaderCodeProcessing) { + delete PostProcess._CustomShaderCodeProcessing[postProcessName ?? ""]; + return; + } + + PostProcess._CustomShaderCodeProcessing[postProcessName ?? ""] = customShaderCodeProcessing; + } + + private static _GetShaderCodeProcessing(postProcessName: string) { + return PostProcess._CustomShaderCodeProcessing[postProcessName] ?? PostProcess._CustomShaderCodeProcessing[""]; + } /** * Gets or sets the unique id of the post process @@ -526,14 +542,15 @@ export class PostProcess { vertexUrl?: string, fragmentUrl?: string ) { - if (PostProcess.CustomShaderCodeProcessing?.defineCustomBindings) { + const customShaderCodeProcessing = PostProcess._GetShaderCodeProcessing(this.name); + if (customShaderCodeProcessing?.defineCustomBindings) { const newUniforms = uniforms?.slice() ?? []; newUniforms.push(...this._parameters); const newSamplers = samplers?.slice() ?? []; newSamplers.push(...this._samplers); - defines = PostProcess.CustomShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); + defines = customShaderCodeProcessing.defineCustomBindings(this.name, defines, newUniforms, newSamplers); uniforms = newUniforms; samplers = newSamplers; } @@ -550,11 +567,11 @@ export class PostProcess { onCompiled: onCompiled ?? null, onError: onError ?? null, indexParameters: indexParameters || this._indexParameters, - processCodeAfterIncludes: PostProcess.CustomShaderCodeProcessing?.processCodeAfterIncludes - ? (shaderType: string, code: string) => PostProcess.CustomShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) + processCodeAfterIncludes: customShaderCodeProcessing?.processCodeAfterIncludes + ? (shaderType: string, code: string) => customShaderCodeProcessing!.processCodeAfterIncludes!(this.name, shaderType, code) : null, - processFinalCode: PostProcess.CustomShaderCodeProcessing?.processFinalCode - ? (shaderType: string, code: string) => PostProcess.CustomShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) + processFinalCode: customShaderCodeProcessing?.processFinalCode + ? (shaderType: string, code: string) => customShaderCodeProcessing!.processFinalCode!(this.name, shaderType, code) : null, }, this._engine @@ -836,7 +853,7 @@ export class PostProcess { this._drawWrapper.effect.setVector2("scale", this._scaleRatio); this.onApplyObservable.notifyObservers(this._drawWrapper.effect); - PostProcess.CustomShaderCodeProcessing?.bindCustomBindings?.(this.name, this._drawWrapper.effect); + PostProcess._GetShaderCodeProcessing(this.name)?.bindCustomBindings?.(this.name, this._drawWrapper.effect); return this._drawWrapper.effect; } From d32ff4c3d8a7cbb896545630760819668d0eeb54 Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 21:35:09 +0100 Subject: [PATCH 8/9] Add tags to ease code injections --- .../src/Shaders/ShadersInclude/imageProcessingFunctions.fx | 6 ++++++ packages/dev/core/src/Shaders/circleOfConfusion.fragment.fx | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx b/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx index 6e7960a27e9..4dc02492f29 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx @@ -93,8 +93,12 @@ } #endif +#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_DEFINITIONS + vec4 applyImageProcessing(vec4 result) { +#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATSTART + #ifdef EXPOSURE result.rgb *= exposureLinear; #endif @@ -174,5 +178,7 @@ vec4 applyImageProcessing(vec4 result) { result.rgb = saturate(result.rgb + vec3(dither)); #endif + #define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATEND + return result; } \ No newline at end of file diff --git a/packages/dev/core/src/Shaders/circleOfConfusion.fragment.fx b/packages/dev/core/src/Shaders/circleOfConfusion.fragment.fx index ff536ebd963..83bb02cde55 100644 --- a/packages/dev/core/src/Shaders/circleOfConfusion.fragment.fx +++ b/packages/dev/core/src/Shaders/circleOfConfusion.fragment.fx @@ -18,7 +18,13 @@ uniform float cocPrecalculation; void main(void) { float depth = texture2D(depthSampler, vUV).r; + + #define CUSTOM_COC_DEPTH + float pixelDistance = (cameraMinMaxZ.x + cameraMinMaxZ.y * depth) * 1000.0; // actual distance from the lens in scene units/1000 (eg. millimeter) + + #define CUSTOM_COC_PIXELDISTANCE + float coc = abs(cocPrecalculation * ((focusDistance - pixelDistance) / pixelDistance)); coc = clamp(coc, 0.0, 1.0); gl_FragColor = vec4(coc, coc, coc, 1.0); From 2876d839df2dc5eca931d4efe8fb1216e65b541a Mon Sep 17 00:00:00 2001 From: Evgeni Popov Date: Wed, 16 Nov 2022 21:38:38 +0100 Subject: [PATCH 9/9] nit --- .../core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx b/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx index 4dc02492f29..d7bae968c75 100644 --- a/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx +++ b/packages/dev/core/src/Shaders/ShadersInclude/imageProcessingFunctions.fx @@ -97,7 +97,7 @@ vec4 applyImageProcessing(vec4 result) { -#define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATSTART + #define CUSTOM_IMAGEPROCESSINGFUNCTIONS_UPDATERESULT_ATSTART #ifdef EXPOSURE result.rgb *= exposureLinear;