123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- import { Texture } from "../../Materials/Textures/texture.js";
- import { Vector2 } from "../../Maths/math.vector.js";
- import { PostProcess } from "../../PostProcesses/postProcess.js";
- import { Observable } from "../../Misc/observable.js";
- /** @internal */
- export class FluidRenderingTextures {
- get blurNumIterations() {
- return this._blurNumIterations;
- }
- set blurNumIterations(numIterations) {
- if (this._blurNumIterations === numIterations) {
- return;
- }
- this._blurNumIterations = numIterations;
- if (this._blurPostProcesses !== null) {
- const blurX = this._blurPostProcesses[0];
- const blurY = this._blurPostProcesses[1];
- this._blurPostProcesses = [];
- for (let i = 0; i < this._blurNumIterations * 2; ++i) {
- this._blurPostProcesses[i] = i & 1 ? blurY : blurX;
- }
- }
- }
- get renderTarget() {
- return this._rt;
- }
- get renderTargetBlur() {
- return this._rtBlur;
- }
- get texture() {
- return this._texture;
- }
- get textureBlur() {
- return this._textureBlurred;
- }
- constructor(name, scene, width, height, blurTextureSizeX, blurTextureSizeY, textureType = 1, textureFormat = 6, blurTextureType = 1, blurTextureFormat = 6, useStandardBlur = false, camera = null, generateDepthBuffer = true, samples = 1) {
- this.enableBlur = true;
- this.blurSizeDivisor = 1;
- this.blurFilterSize = 7;
- this._blurNumIterations = 3;
- this.blurMaxFilterSize = 100;
- this.blurDepthScale = 10;
- this.particleSize = 0.02;
- this.onDisposeObservable = new Observable();
- this._name = name;
- this._scene = scene;
- this._camera = camera;
- this._engine = scene.getEngine();
- this._width = width;
- this._height = height;
- this._blurTextureSizeX = blurTextureSizeX;
- this._blurTextureSizeY = blurTextureSizeY;
- this._textureType = textureType;
- this._textureFormat = textureFormat;
- this._blurTextureType = blurTextureType;
- this._blurTextureFormat = blurTextureFormat;
- this._useStandardBlur = useStandardBlur;
- this._generateDepthBuffer = generateDepthBuffer;
- this._samples = samples;
- this._postProcessRunningIndex = 0;
- this.enableBlur = blurTextureSizeX !== 0 && blurTextureSizeY !== 0;
- this._rt = null;
- this._texture = null;
- this._rtBlur = null;
- this._textureBlurred = null;
- this._blurPostProcesses = null;
- }
- initialize() {
- this.dispose();
- this._createRenderTarget();
- if (this.enableBlur && this._texture) {
- const [rtBlur, textureBlurred, blurPostProcesses] = this._createBlurPostProcesses(this._texture, this._blurTextureType, this._blurTextureFormat, this.blurSizeDivisor, this._name, this._useStandardBlur);
- this._rtBlur = rtBlur;
- this._textureBlurred = textureBlurred;
- this._blurPostProcesses = blurPostProcesses;
- }
- }
- applyBlurPostProcesses() {
- if (this.enableBlur && this._blurPostProcesses) {
- this._postProcessRunningIndex = 0;
- this._scene.postProcessManager.directRender(this._blurPostProcesses, this._rtBlur, true);
- this._engine.unBindFramebuffer(this._rtBlur);
- }
- }
- _createRenderTarget() {
- this._rt = this._engine.createRenderTargetTexture({ width: this._width, height: this._height }, {
- generateMipMaps: false,
- type: this._textureType,
- format: this._textureFormat,
- samplingMode: 1,
- generateDepthBuffer: this._generateDepthBuffer,
- generateStencilBuffer: false,
- samples: this._samples,
- label: `FluidRenderingRTT-${this._name}`,
- });
- const renderTexture = this._rt.texture;
- renderTexture.incrementReferences();
- this._texture = new Texture(null, this._scene);
- this._texture.name = "rtt" + this._name;
- this._texture._texture = renderTexture;
- this._texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- this._texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- this._texture.anisotropicFilteringLevel = 1;
- }
- _createBlurPostProcesses(textureBlurSource, textureType, textureFormat, blurSizeDivisor, debugName, useStandardBlur = false) {
- const engine = this._scene.getEngine();
- const targetSize = new Vector2(Math.floor(this._blurTextureSizeX / blurSizeDivisor), Math.floor(this._blurTextureSizeY / blurSizeDivisor));
- const useBilinearFiltering = (textureType === 1 && engine.getCaps().textureFloatLinearFiltering) ||
- (textureType === 2 && engine.getCaps().textureHalfFloatLinearFiltering);
- const rtBlur = this._engine.createRenderTargetTexture({ width: targetSize.x, height: targetSize.y }, {
- generateMipMaps: false,
- type: textureType,
- format: textureFormat,
- samplingMode: useBilinearFiltering ? 2 : 1,
- generateDepthBuffer: false,
- generateStencilBuffer: false,
- samples: this._samples,
- label: `FluidRenderingRTTBlur-${debugName}`,
- });
- const renderTexture = rtBlur.texture;
- renderTexture.incrementReferences();
- const texture = new Texture(null, this._scene);
- texture.name = "rttBlurred" + debugName;
- texture._texture = renderTexture;
- texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- texture.anisotropicFilteringLevel = 1;
- if (useStandardBlur) {
- const kernelBlurXPostprocess = new PostProcess("BilateralBlurX", "fluidRenderingStandardBlur", ["filterSize", "blurDir"], null, 1, null, 1, engine, true, null, textureType, undefined, undefined, undefined, textureFormat);
- kernelBlurXPostprocess.samples = this._samples;
- kernelBlurXPostprocess.externalTextureSamplerBinding = true;
- kernelBlurXPostprocess.onApplyObservable.add((effect) => {
- if (this._postProcessRunningIndex === 0) {
- effect.setTexture("textureSampler", textureBlurSource);
- }
- else {
- effect._bindTexture("textureSampler", kernelBlurXPostprocess.inputTexture.texture);
- }
- effect.setInt("filterSize", this.blurFilterSize);
- effect.setFloat2("blurDir", 1 / this._blurTextureSizeX, 0);
- this._postProcessRunningIndex++;
- });
- kernelBlurXPostprocess.onSizeChangedObservable.add(() => {
- kernelBlurXPostprocess._textures.forEach((rt) => {
- rt.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- rt.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- });
- });
- this._fixReusablePostProcess(kernelBlurXPostprocess);
- const kernelBlurYPostprocess = new PostProcess("BilateralBlurY", "fluidRenderingStandardBlur", ["filterSize", "blurDir"], null, 1, null, 1, engine, true, null, textureType, undefined, undefined, undefined, textureFormat);
- kernelBlurYPostprocess.samples = this._samples;
- kernelBlurYPostprocess.onApplyObservable.add((effect) => {
- effect.setInt("filterSize", this.blurFilterSize);
- effect.setFloat2("blurDir", 0, 1 / this._blurTextureSizeY);
- this._postProcessRunningIndex++;
- });
- kernelBlurYPostprocess.onSizeChangedObservable.add(() => {
- kernelBlurYPostprocess._textures.forEach((rt) => {
- rt.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- rt.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- });
- });
- this._fixReusablePostProcess(kernelBlurYPostprocess);
- kernelBlurXPostprocess.autoClear = false;
- kernelBlurYPostprocess.autoClear = false;
- const blurList = [];
- for (let i = 0; i < this._blurNumIterations * 2; ++i) {
- blurList[i] = i & 1 ? kernelBlurYPostprocess : kernelBlurXPostprocess;
- }
- return [rtBlur, texture, blurList];
- }
- else {
- const uniforms = ["maxFilterSize", "blurDir", "projectedParticleConstant", "depthThreshold"];
- const kernelBlurXPostprocess = new PostProcess("BilateralBlurX", "fluidRenderingBilateralBlur", uniforms, null, 1, null, 1, engine, true, null, textureType, undefined, undefined, undefined, textureFormat);
- kernelBlurXPostprocess.samples = this._samples;
- kernelBlurXPostprocess.externalTextureSamplerBinding = true;
- kernelBlurXPostprocess.onApplyObservable.add((effect) => {
- if (this._postProcessRunningIndex === 0) {
- effect.setTexture("textureSampler", textureBlurSource);
- }
- else {
- effect._bindTexture("textureSampler", kernelBlurXPostprocess.inputTexture.texture);
- }
- effect.setInt("maxFilterSize", this.blurMaxFilterSize);
- effect.setFloat2("blurDir", 1 / this._blurTextureSizeX, 0);
- effect.setFloat("projectedParticleConstant", this._getProjectedParticleConstant());
- effect.setFloat("depthThreshold", this._getDepthThreshold());
- this._postProcessRunningIndex++;
- });
- kernelBlurXPostprocess.onSizeChangedObservable.add(() => {
- kernelBlurXPostprocess._textures.forEach((rt) => {
- rt.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- rt.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- });
- });
- this._fixReusablePostProcess(kernelBlurXPostprocess);
- const kernelBlurYPostprocess = new PostProcess("BilateralBlurY", "fluidRenderingBilateralBlur", uniforms, null, 1, null, 1, engine, true, null, textureType, undefined, undefined, undefined, textureFormat);
- kernelBlurYPostprocess.samples = this._samples;
- kernelBlurYPostprocess.onApplyObservable.add((effect) => {
- effect.setInt("maxFilterSize", this.blurMaxFilterSize);
- effect.setFloat2("blurDir", 0, 1 / this._blurTextureSizeY);
- effect.setFloat("projectedParticleConstant", this._getProjectedParticleConstant());
- effect.setFloat("depthThreshold", this._getDepthThreshold());
- this._postProcessRunningIndex++;
- });
- kernelBlurYPostprocess.onSizeChangedObservable.add(() => {
- kernelBlurYPostprocess._textures.forEach((rt) => {
- rt.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
- rt.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
- });
- });
- this._fixReusablePostProcess(kernelBlurYPostprocess);
- kernelBlurXPostprocess.autoClear = false;
- kernelBlurYPostprocess.autoClear = false;
- const blurList = [];
- for (let i = 0; i < this._blurNumIterations * 2; ++i) {
- blurList[i] = i & 1 ? kernelBlurYPostprocess : kernelBlurXPostprocess;
- }
- return [rtBlur, texture, blurList];
- }
- }
- _fixReusablePostProcess(pp) {
- if (!pp.isReusable()) {
- return;
- }
- pp.onActivateObservable.add(() => {
- // undo what calling activate() does which will make sure we will retrieve the right texture when getting the input for the post process
- pp._currentRenderTextureInd = (pp._currentRenderTextureInd + 1) % 2;
- });
- pp.onApplyObservable.add(() => {
- // now we can advance to the next texture
- pp._currentRenderTextureInd = (pp._currentRenderTextureInd + 1) % 2;
- });
- }
- _getProjectedParticleConstant() {
- return (this.blurFilterSize * this.particleSize * 0.05 * (this._height / 2)) / Math.tan((this._camera?.fov ?? (45 * Math.PI) / 180) / 2);
- }
- _getDepthThreshold() {
- return (this.particleSize / 2) * this.blurDepthScale;
- }
- dispose() {
- if (this.onDisposeObservable.hasObservers()) {
- this.onDisposeObservable.notifyObservers(this);
- }
- this._rt?.dispose();
- this._rt = null;
- this._texture?.dispose();
- this._texture = null;
- this._rtBlur?.dispose();
- this._rtBlur = null;
- this._textureBlurred?.dispose();
- this._textureBlurred = null;
- if (this._blurPostProcesses) {
- this._blurPostProcesses[0].dispose();
- this._blurPostProcesses[1].dispose();
- }
- this._blurPostProcesses = null;
- }
- }
- //# sourceMappingURL=fluidRenderingTextures.js.map
|