var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; if(typeof require !== 'undefined'){ var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this); var BABYLON = globalObject["BABYLON"] || {}; var BABYLON0 = require('babylonjs/renderingPipeline'); if(BABYLON !== BABYLON0) __extends(BABYLON, BABYLON0); var BABYLON1 = require('babylonjs/depthRenderer'); if(BABYLON !== BABYLON1) __extends(BABYLON, BABYLON1); var BABYLON; (function (BABYLON) { var SSAORenderingPipeline = /** @class */ (function (_super) { __extends(SSAORenderingPipeline, _super); /** * @constructor * @param {string} name - The rendering pipeline name * @param {BABYLON.Scene} scene - The scene linked to this pipeline * @param {any} ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, combineRatio: 1.0 } * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to */ function SSAORenderingPipeline(name, scene, ratio, cameras) { var _this = _super.call(this, scene.getEngine(), name) || this; // Members /** * The PassPostProcess id in the pipeline that contains the original scene color * @type {string} */ _this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect"; /** * The SSAO PostProcess id in the pipeline * @type {string} */ _this.SSAORenderEffect = "SSAORenderEffect"; /** * The horizontal blur PostProcess id in the pipeline * @type {string} */ _this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect"; /** * The vertical blur PostProcess id in the pipeline * @type {string} */ _this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect"; /** * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect) * @type {string} */ _this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect"; /** * The output strength of the SSAO post-process. Default value is 1.0. * @type {number} */ _this.totalStrength = 1.0; /** * The radius around the analyzed pixel used by the SSAO post-process. Default value is 0.0006 * @type {number} */ _this.radius = 0.0001; /** * Related to fallOff, used to interpolate SSAO samples (first interpolate function input) based on the occlusion difference of each pixel * Must not be equal to fallOff and superior to fallOff. * Default value is 0.975 * @type {number} */ _this.area = 0.0075; /** * Related to area, used to interpolate SSAO samples (second interpolate function input) based on the occlusion difference of each pixel * Must not be equal to area and inferior to area. * Default value is 0.0 * @type {number} */ _this.fallOff = 0.000001; /** * The base color of the SSAO post-process * The final result is "base + ssao" between [0, 1] * @type {number} */ _this.base = 0.5; _this._firstUpdate = true; _this._scene = scene; // Set up assets _this._createRandomTexture(); _this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on" var ssaoRatio = ratio.ssaoRatio || ratio; var combineRatio = ratio.combineRatio || ratio; _this._originalColorPostProcess = new BABYLON.PassPostProcess("SSAOOriginalSceneColor", combineRatio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false); _this._createSSAOPostProcess(ssaoRatio); _this._createBlurPostProcess(ssaoRatio); _this._createSSAOCombinePostProcess(combineRatio); // Set up pipeline _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOOriginalSceneColorEffect, function () { return _this._originalColorPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAORenderEffect, function () { return _this._ssaoPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOBlurHRenderEffect, function () { return _this._blurHPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOBlurVRenderEffect, function () { return _this._blurVPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOCombineRenderEffect, function () { return _this._ssaoCombinePostProcess; }, true)); // Finish scene.postProcessRenderPipelineManager.addPipeline(_this); if (cameras) scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras); return _this; } // Public Methods /** * Removes the internal pipeline assets and detatches the pipeline from the scene cameras */ SSAORenderingPipeline.prototype.dispose = function (disableDepthRender) { if (disableDepthRender === void 0) { disableDepthRender = false; } for (var i = 0; i < this._scene.cameras.length; i++) { var camera = this._scene.cameras[i]; this._originalColorPostProcess.dispose(camera); this._ssaoPostProcess.dispose(camera); this._blurHPostProcess.dispose(camera); this._blurVPostProcess.dispose(camera); this._ssaoCombinePostProcess.dispose(camera); } this._randomTexture.dispose(); if (disableDepthRender) this._scene.disableDepthRenderer(); this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras); _super.prototype.dispose.call(this); }; // Private Methods SSAORenderingPipeline.prototype._createBlurPostProcess = function (ratio) { var _this = this; var size = 16; this._blurHPostProcess = new BABYLON.BlurPostProcess("BlurH", new BABYLON.Vector2(1, 0), size, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this._blurVPostProcess = new BABYLON.BlurPostProcess("BlurV", new BABYLON.Vector2(0, 1), size, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this._blurHPostProcess.onActivateObservable.add(function () { var dw = _this._blurHPostProcess.width / _this._scene.getEngine().getRenderWidth(); _this._blurHPostProcess.kernel = size * dw; }); this._blurVPostProcess.onActivateObservable.add(function () { var dw = _this._blurVPostProcess.height / _this._scene.getEngine().getRenderHeight(); _this._blurVPostProcess.kernel = size * dw; }); }; SSAORenderingPipeline.prototype._rebuild = function () { this._firstUpdate = true; _super.prototype._rebuild.call(this); }; SSAORenderingPipeline.prototype._createSSAOPostProcess = function (ratio) { var _this = this; var numSamples = 16; var sampleSphere = [ 0.5381, 0.1856, -0.4319, 0.1379, 0.2486, 0.4430, 0.3371, 0.5679, -0.0057, -0.6999, -0.0451, -0.0019, 0.0689, -0.1598, -0.8547, 0.0560, 0.0069, -0.1843, -0.0146, 0.1402, 0.0762, 0.0100, -0.1924, -0.0344, -0.3577, -0.5301, -0.4358, -0.3169, 0.1063, 0.0158, 0.0103, -0.5869, 0.0046, -0.0897, -0.4940, 0.3287, 0.7119, -0.0154, -0.0918, -0.0533, 0.0596, -0.5411, 0.0352, -0.0631, 0.5460, -0.4776, 0.2847, -0.0271 ]; var samplesFactor = 1.0 / numSamples; this._ssaoPostProcess = new BABYLON.PostProcess("ssao", "ssao", [ "sampleSphere", "samplesFactor", "randTextureTiles", "totalStrength", "radius", "area", "fallOff", "base", "range", "viewport" ], ["randomSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define SAMPLES " + numSamples + "\n#define SSAO"); this._ssaoPostProcess.onApply = function (effect) { if (_this._firstUpdate) { effect.setArray3("sampleSphere", sampleSphere); effect.setFloat("samplesFactor", samplesFactor); effect.setFloat("randTextureTiles", 4.0); } effect.setFloat("totalStrength", _this.totalStrength); effect.setFloat("radius", _this.radius); effect.setFloat("area", _this.area); effect.setFloat("fallOff", _this.fallOff); effect.setFloat("base", _this.base); effect.setTexture("textureSampler", _this._depthTexture); effect.setTexture("randomSampler", _this._randomTexture); }; }; SSAORenderingPipeline.prototype._createSSAOCombinePostProcess = function (ratio) { var _this = this; this._ssaoCombinePostProcess = new BABYLON.PostProcess("ssaoCombine", "ssaoCombine", [], ["originalColor"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false); this._ssaoCombinePostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("originalColor", _this._originalColorPostProcess); }; }; SSAORenderingPipeline.prototype._createRandomTexture = function () { var size = 512; this._randomTexture = new BABYLON.DynamicTexture("SSAORandomTexture", size, this._scene, false, BABYLON.Texture.TRILINEAR_SAMPLINGMODE); this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE; this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; var context = this._randomTexture.getContext(); var rand = function (min, max) { return Math.random() * (max - min) + min; }; var randVector = BABYLON.Vector3.Zero(); for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { randVector.x = Math.floor(rand(-1.0, 1.0) * 255); randVector.y = Math.floor(rand(-1.0, 1.0) * 255); randVector.z = Math.floor(rand(-1.0, 1.0) * 255); context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')'; context.fillRect(x, y, 1, 1); } } this._randomTexture.update(false); }; __decorate([ BABYLON.serialize() ], SSAORenderingPipeline.prototype, "totalStrength", void 0); __decorate([ BABYLON.serialize() ], SSAORenderingPipeline.prototype, "radius", void 0); __decorate([ BABYLON.serialize() ], SSAORenderingPipeline.prototype, "area", void 0); __decorate([ BABYLON.serialize() ], SSAORenderingPipeline.prototype, "fallOff", void 0); __decorate([ BABYLON.serialize() ], SSAORenderingPipeline.prototype, "base", void 0); return SSAORenderingPipeline; }(BABYLON.PostProcessRenderPipeline)); BABYLON.SSAORenderingPipeline = SSAORenderingPipeline; })(BABYLON || (BABYLON = {})); //# sourceMappingURL=babylon.ssaoRenderingPipeline.js.map var BABYLON; (function (BABYLON) { var SSAO2RenderingPipeline = /** @class */ (function (_super) { __extends(SSAO2RenderingPipeline, _super); /** * @constructor * @param {string} name - The rendering pipeline name * @param {BABYLON.Scene} scene - The scene linked to this pipeline * @param {any} ratio - The size of the postprocesses. Can be a number shared between passes or an object for more precision: { ssaoRatio: 0.5, blurRatio: 1.0 } * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to */ function SSAO2RenderingPipeline(name, scene, ratio, cameras) { var _this = _super.call(this, scene.getEngine(), name) || this; // Members /** * The PassPostProcess id in the pipeline that contains the original scene color * @type {string} */ _this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect"; /** * The SSAO PostProcess id in the pipeline * @type {string} */ _this.SSAORenderEffect = "SSAORenderEffect"; /** * The horizontal blur PostProcess id in the pipeline * @type {string} */ _this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect"; /** * The vertical blur PostProcess id in the pipeline * @type {string} */ _this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect"; /** * The PostProcess id in the pipeline that combines the SSAO-Blur output with the original scene color (SSAOOriginalSceneColorEffect) * @type {string} */ _this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect"; /** * The output strength of the SSAO post-process. Default value is 1.0. * @type {number} */ _this.totalStrength = 1.0; /** * Maximum depth value to still render AO. A smooth falloff makes the dimming more natural, so there will be no abrupt shading change. * @type {number} */ _this.maxZ = 100.0; /** * In order to save performances, SSAO radius is clamped on close geometry. This ratio changes by how much * @type {number} */ _this.minZAspect = 0.2; /** * Number of samples used for the SSAO calculations. Default value is 8 * @type {number} */ _this._samples = 8; /** * Are we using bilateral blur ? * @type {boolean} */ _this._expensiveBlur = true; /** * The radius around the analyzed pixel used by the SSAO post-process. Default value is 2.0 * @type {number} */ _this.radius = 2.0; /** * The base color of the SSAO post-process * The final result is "base + ssao" between [0, 1] * @type {number} */ _this.base = 0.1; _this._firstUpdate = true; _this._scene = scene; if (!_this.isSupported) { BABYLON.Tools.Error("SSAO 2 needs WebGL 2 support."); return _this; } var ssaoRatio = ratio.ssaoRatio || ratio; var blurRatio = ratio.blurRatio || ratio; // Set up assets var geometryBufferRenderer = scene.enableGeometryBufferRenderer(); _this._createRandomTexture(); _this._depthTexture = geometryBufferRenderer.getGBuffer().textures[0]; _this._normalTexture = geometryBufferRenderer.getGBuffer().textures[1]; _this._originalColorPostProcess = new BABYLON.PassPostProcess("SSAOOriginalSceneColor", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false); _this._createSSAOPostProcess(1.0); _this._createBlurPostProcess(ssaoRatio, blurRatio); _this._createSSAOCombinePostProcess(blurRatio); // Set up pipeline _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOOriginalSceneColorEffect, function () { return _this._originalColorPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAORenderEffect, function () { return _this._ssaoPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOBlurHRenderEffect, function () { return _this._blurHPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOBlurVRenderEffect, function () { return _this._blurVPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.SSAOCombineRenderEffect, function () { return _this._ssaoCombinePostProcess; }, true)); // Finish scene.postProcessRenderPipelineManager.addPipeline(_this); if (cameras) scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras); return _this; } Object.defineProperty(SSAO2RenderingPipeline.prototype, "samples", { get: function () { return this._samples; }, set: function (n) { this._ssaoPostProcess.updateEffect("#define SAMPLES " + n + "\n#define SSAO"); this._samples = n; this._sampleSphere = this._generateHemisphere(); this._firstUpdate = true; }, enumerable: true, configurable: true }); Object.defineProperty(SSAO2RenderingPipeline.prototype, "expensiveBlur", { get: function () { return this._expensiveBlur; }, set: function (b) { this._blurHPostProcess.updateEffect("#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (b ? "1" : "0") + "\n", null, ["textureSampler", "depthSampler"]); this._blurVPostProcess.updateEffect("#define BILATERAL_BLUR\n#define SAMPLES 16\n#define EXPENSIVE " + (b ? "1" : "0") + "\n", null, ["textureSampler", "depthSampler"]); this._expensiveBlur = b; this._firstUpdate = true; }, enumerable: true, configurable: true }); Object.defineProperty(SSAO2RenderingPipeline, "IsSupported", { /** * Support test. * @type {boolean} */ get: function () { var engine = BABYLON.Engine.LastCreatedEngine; if (!engine) { return false; } return engine.getCaps().drawBuffersExtension; }, enumerable: true, configurable: true }); // Public Methods /** * Removes the internal pipeline assets and detatches the pipeline from the scene cameras */ SSAO2RenderingPipeline.prototype.dispose = function (disableGeometryBufferRenderer) { if (disableGeometryBufferRenderer === void 0) { disableGeometryBufferRenderer = false; } for (var i = 0; i < this._scene.cameras.length; i++) { var camera = this._scene.cameras[i]; this._originalColorPostProcess.dispose(camera); this._ssaoPostProcess.dispose(camera); this._blurHPostProcess.dispose(camera); this._blurVPostProcess.dispose(camera); this._ssaoCombinePostProcess.dispose(camera); } this._randomTexture.dispose(); if (disableGeometryBufferRenderer) this._scene.disableGeometryBufferRenderer(); this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras); _super.prototype.dispose.call(this); }; // Private Methods SSAO2RenderingPipeline.prototype._createBlurPostProcess = function (ssaoRatio, blurRatio) { var _this = this; this._samplerOffsets = []; var expensive = this.expensiveBlur; for (var i = -8; i < 8; i++) { this._samplerOffsets.push(i * 2 + 0.5); } this._blurHPostProcess = new BABYLON.PostProcess("BlurH", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], ssaoRatio, null, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_H\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n"); this._blurHPostProcess.onApply = function (effect) { if (!_this._scene.activeCamera) { return; } effect.setFloat("outSize", _this._ssaoCombinePostProcess.width > 0 ? _this._ssaoCombinePostProcess.width : _this._originalColorPostProcess.width); effect.setFloat("near", _this._scene.activeCamera.minZ); effect.setFloat("far", _this._scene.activeCamera.maxZ); effect.setFloat("radius", _this.radius); effect.setTexture("depthSampler", _this._depthTexture); if (_this._firstUpdate) { effect.setArray("samplerOffsets", _this._samplerOffsets); } }; this._blurVPostProcess = new BABYLON.PostProcess("BlurV", "ssao2", ["outSize", "samplerOffsets", "near", "far", "radius"], ["depthSampler"], blurRatio, null, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define BILATERAL_BLUR\n#define BILATERAL_BLUR_V\n#define SAMPLES 16\n#define EXPENSIVE " + (expensive ? "1" : "0") + "\n"); this._blurVPostProcess.onApply = function (effect) { if (!_this._scene.activeCamera) { return; } effect.setFloat("outSize", _this._ssaoCombinePostProcess.height > 0 ? _this._ssaoCombinePostProcess.height : _this._originalColorPostProcess.height); effect.setFloat("near", _this._scene.activeCamera.minZ); effect.setFloat("far", _this._scene.activeCamera.maxZ); effect.setFloat("radius", _this.radius); effect.setTexture("depthSampler", _this._depthTexture); if (_this._firstUpdate) { effect.setArray("samplerOffsets", _this._samplerOffsets); _this._firstUpdate = false; } }; }; SSAO2RenderingPipeline.prototype._rebuild = function () { this._firstUpdate = true; _super.prototype._rebuild.call(this); }; SSAO2RenderingPipeline.prototype._generateHemisphere = function () { var numSamples = this.samples; var result = []; var vector, scale; var rand = function (min, max) { return Math.random() * (max - min) + min; }; var i = 0; while (i < numSamples) { vector = new BABYLON.Vector3(rand(-1.0, 1.0), rand(-1.0, 1.0), rand(0.30, 1.0)); vector.normalize(); scale = i / numSamples; scale = BABYLON.Scalar.Lerp(0.1, 1.0, scale * scale); vector.scaleInPlace(scale); result.push(vector.x, vector.y, vector.z); i++; } return result; }; SSAO2RenderingPipeline.prototype._createSSAOPostProcess = function (ratio) { var _this = this; var numSamples = this.samples; this._sampleSphere = this._generateHemisphere(); this._ssaoPostProcess = new BABYLON.PostProcess("ssao2", "ssao2", [ "sampleSphere", "samplesFactor", "randTextureTiles", "totalStrength", "radius", "base", "range", "projection", "near", "far", "texelSize", "xViewport", "yViewport", "maxZ", "minZAspect" ], ["randomSampler", "normalSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, "#define SAMPLES " + numSamples + "\n#define SSAO"); this._ssaoPostProcess.onApply = function (effect) { if (_this._firstUpdate) { effect.setArray3("sampleSphere", _this._sampleSphere); effect.setFloat("randTextureTiles", 4.0); } if (!_this._scene.activeCamera) { return; } effect.setFloat("samplesFactor", 1 / _this.samples); effect.setFloat("totalStrength", _this.totalStrength); effect.setFloat2("texelSize", 1 / _this._ssaoPostProcess.width, 1 / _this._ssaoPostProcess.height); effect.setFloat("radius", _this.radius); effect.setFloat("maxZ", _this.maxZ); effect.setFloat("minZAspect", _this.minZAspect); effect.setFloat("base", _this.base); effect.setFloat("near", _this._scene.activeCamera.minZ); effect.setFloat("far", _this._scene.activeCamera.maxZ); effect.setFloat("xViewport", Math.tan(_this._scene.activeCamera.fov / 2) * _this._scene.getEngine().getAspectRatio(_this._scene.activeCamera, true)); effect.setFloat("yViewport", Math.tan(_this._scene.activeCamera.fov / 2)); effect.setMatrix("projection", _this._scene.getProjectionMatrix()); effect.setTexture("textureSampler", _this._depthTexture); effect.setTexture("normalSampler", _this._normalTexture); effect.setTexture("randomSampler", _this._randomTexture); }; }; SSAO2RenderingPipeline.prototype._createSSAOCombinePostProcess = function (ratio) { var _this = this; this._ssaoCombinePostProcess = new BABYLON.PostProcess("ssaoCombine", "ssaoCombine", [], ["originalColor"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false); this._ssaoCombinePostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("originalColor", _this._originalColorPostProcess); }; }; SSAO2RenderingPipeline.prototype._createRandomTexture = function () { var size = 512; this._randomTexture = new BABYLON.DynamicTexture("SSAORandomTexture", size, this._scene, false, BABYLON.Texture.TRILINEAR_SAMPLINGMODE); this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE; this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; var context = this._randomTexture.getContext(); var rand = function (min, max) { return Math.random() * (max - min) + min; }; var randVector = BABYLON.Vector3.Zero(); for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { randVector.x = rand(0.0, 1.0); randVector.y = rand(0.0, 1.0); randVector.z = 0.0; randVector.normalize(); randVector.scaleInPlace(255); randVector.x = Math.floor(randVector.x); randVector.y = Math.floor(randVector.y); context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')'; context.fillRect(x, y, 1, 1); } } this._randomTexture.update(false); }; __decorate([ BABYLON.serialize() ], SSAO2RenderingPipeline.prototype, "totalStrength", void 0); __decorate([ BABYLON.serialize() ], SSAO2RenderingPipeline.prototype, "maxZ", void 0); __decorate([ BABYLON.serialize() ], SSAO2RenderingPipeline.prototype, "minZAspect", void 0); __decorate([ BABYLON.serialize("samples") ], SSAO2RenderingPipeline.prototype, "_samples", void 0); __decorate([ BABYLON.serialize("expensiveBlur") ], SSAO2RenderingPipeline.prototype, "_expensiveBlur", void 0); __decorate([ BABYLON.serialize() ], SSAO2RenderingPipeline.prototype, "radius", void 0); __decorate([ BABYLON.serialize() ], SSAO2RenderingPipeline.prototype, "base", void 0); return SSAO2RenderingPipeline; }(BABYLON.PostProcessRenderPipeline)); BABYLON.SSAO2RenderingPipeline = SSAO2RenderingPipeline; })(BABYLON || (BABYLON = {})); //# sourceMappingURL=babylon.ssao2RenderingPipeline.js.map // BABYLON.JS Chromatic Aberration GLSL Shader // Author: Olivier Guyot // Separates very slightly R, G and B colors on the edges of the screen // Inspired by Francois Tarlier & Martins Upitis var BABYLON; (function (BABYLON) { var LensRenderingPipeline = /** @class */ (function (_super) { __extends(LensRenderingPipeline, _super); /** * @constructor * * Effect parameters are as follow: * { * chromatic_aberration: number; // from 0 to x (1 for realism) * edge_blur: number; // from 0 to x (1 for realism) * distortion: number; // from 0 to x (1 for realism) * grain_amount: number; // from 0 to 1 * grain_texture: BABYLON.Texture; // texture to use for grain effect; if unset, use random B&W noise * dof_focus_distance: number; // depth-of-field: focus distance; unset to disable (disabled by default) * dof_aperture: number; // depth-of-field: focus blur bias (default: 1) * dof_darken: number; // depth-of-field: darken that which is out of focus (from 0 to 1, disabled by default) * dof_pentagon: boolean; // depth-of-field: makes a pentagon-like "bokeh" effect * dof_gain: number; // depth-of-field: highlights gain; unset to disable (disabled by default) * dof_threshold: number; // depth-of-field: highlights threshold (default: 1) * blur_noise: boolean; // add a little bit of noise to the blur (default: true) * } * Note: if an effect parameter is unset, effect is disabled * * @param {string} name - The rendering pipeline name * @param {object} parameters - An object containing all parameters (see above) * @param {BABYLON.Scene} scene - The scene linked to this pipeline * @param {number} ratio - The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5) * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to */ function LensRenderingPipeline(name, parameters, scene, ratio, cameras) { if (ratio === void 0) { ratio = 1.0; } var _this = _super.call(this, scene.getEngine(), name) || this; // Lens effects can be of the following: // - chromatic aberration (slight shift of RGB colors) // - blur on the edge of the lens // - lens distortion // - depth-of-field blur & highlights enhancing // - depth-of-field 'bokeh' effect (shapes appearing in blurred areas) // - grain effect (noise or custom texture) // Two additional texture samplers are needed: // - depth map (for depth-of-field) // - grain texture /** * The chromatic aberration PostProcess id in the pipeline * @type {string} */ _this.LensChromaticAberrationEffect = "LensChromaticAberrationEffect"; /** * The highlights enhancing PostProcess id in the pipeline * @type {string} */ _this.HighlightsEnhancingEffect = "HighlightsEnhancingEffect"; /** * The depth-of-field PostProcess id in the pipeline * @type {string} */ _this.LensDepthOfFieldEffect = "LensDepthOfFieldEffect"; _this._scene = scene; // Fetch texture samplers _this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on" if (parameters.grain_texture) { _this._grainTexture = parameters.grain_texture; } else { _this._createGrainTexture(); } // save parameters _this._edgeBlur = parameters.edge_blur ? parameters.edge_blur : 0; _this._grainAmount = parameters.grain_amount ? parameters.grain_amount : 0; _this._chromaticAberration = parameters.chromatic_aberration ? parameters.chromatic_aberration : 0; _this._distortion = parameters.distortion ? parameters.distortion : 0; _this._highlightsGain = parameters.dof_gain !== undefined ? parameters.dof_gain : -1; _this._highlightsThreshold = parameters.dof_threshold ? parameters.dof_threshold : 1; _this._dofDistance = parameters.dof_focus_distance !== undefined ? parameters.dof_focus_distance : -1; _this._dofAperture = parameters.dof_aperture ? parameters.dof_aperture : 1; _this._dofDarken = parameters.dof_darken ? parameters.dof_darken : 0; _this._dofPentagon = parameters.dof_pentagon !== undefined ? parameters.dof_pentagon : true; _this._blurNoise = parameters.blur_noise !== undefined ? parameters.blur_noise : true; // Create effects _this._createChromaticAberrationPostProcess(ratio); _this._createHighlightsPostProcess(ratio); _this._createDepthOfFieldPostProcess(ratio / 4); // Set up pipeline _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.LensChromaticAberrationEffect, function () { return _this._chromaticAberrationPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.HighlightsEnhancingEffect, function () { return _this._highlightsPostProcess; }, true)); _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), _this.LensDepthOfFieldEffect, function () { return _this._depthOfFieldPostProcess; }, true)); if (_this._highlightsGain === -1) { _this._disableEffect(_this.HighlightsEnhancingEffect, null); } // Finish scene.postProcessRenderPipelineManager.addPipeline(_this); if (cameras) { scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(name, cameras); } return _this; } // public methods (self explanatory) LensRenderingPipeline.prototype.setEdgeBlur = function (amount) { this._edgeBlur = amount; }; LensRenderingPipeline.prototype.disableEdgeBlur = function () { this._edgeBlur = 0; }; LensRenderingPipeline.prototype.setGrainAmount = function (amount) { this._grainAmount = amount; }; LensRenderingPipeline.prototype.disableGrain = function () { this._grainAmount = 0; }; LensRenderingPipeline.prototype.setChromaticAberration = function (amount) { this._chromaticAberration = amount; }; LensRenderingPipeline.prototype.disableChromaticAberration = function () { this._chromaticAberration = 0; }; LensRenderingPipeline.prototype.setEdgeDistortion = function (amount) { this._distortion = amount; }; LensRenderingPipeline.prototype.disableEdgeDistortion = function () { this._distortion = 0; }; LensRenderingPipeline.prototype.setFocusDistance = function (amount) { this._dofDistance = amount; }; LensRenderingPipeline.prototype.disableDepthOfField = function () { this._dofDistance = -1; }; LensRenderingPipeline.prototype.setAperture = function (amount) { this._dofAperture = amount; }; LensRenderingPipeline.prototype.setDarkenOutOfFocus = function (amount) { this._dofDarken = amount; }; LensRenderingPipeline.prototype.enablePentagonBokeh = function () { this._highlightsPostProcess.updateEffect("#define PENTAGON\n"); }; LensRenderingPipeline.prototype.disablePentagonBokeh = function () { this._highlightsPostProcess.updateEffect(); }; LensRenderingPipeline.prototype.enableNoiseBlur = function () { this._blurNoise = true; }; LensRenderingPipeline.prototype.disableNoiseBlur = function () { this._blurNoise = false; }; LensRenderingPipeline.prototype.setHighlightsGain = function (amount) { this._highlightsGain = amount; }; LensRenderingPipeline.prototype.setHighlightsThreshold = function (amount) { if (this._highlightsGain === -1) { this._highlightsGain = 1.0; } this._highlightsThreshold = amount; }; LensRenderingPipeline.prototype.disableHighlights = function () { this._highlightsGain = -1; }; /** * Removes the internal pipeline assets and detaches the pipeline from the scene cameras */ LensRenderingPipeline.prototype.dispose = function (disableDepthRender) { if (disableDepthRender === void 0) { disableDepthRender = false; } this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._scene.cameras); this._chromaticAberrationPostProcess = null; this._highlightsPostProcess = null; this._depthOfFieldPostProcess = null; this._grainTexture.dispose(); if (disableDepthRender) this._scene.disableDepthRenderer(); }; // colors shifting and distortion LensRenderingPipeline.prototype._createChromaticAberrationPostProcess = function (ratio) { var _this = this; this._chromaticAberrationPostProcess = new BABYLON.PostProcess("LensChromaticAberration", "chromaticAberration", ["chromatic_aberration", "screen_width", "screen_height"], // uniforms [], // samplers ratio, null, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false); this._chromaticAberrationPostProcess.onApply = function (effect) { effect.setFloat('chromatic_aberration', _this._chromaticAberration); effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth()); effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight()); }; }; // highlights enhancing LensRenderingPipeline.prototype._createHighlightsPostProcess = function (ratio) { var _this = this; this._highlightsPostProcess = new BABYLON.PostProcess("LensHighlights", "lensHighlights", ["gain", "threshold", "screen_width", "screen_height"], // uniforms [], // samplers ratio, null, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false, this._dofPentagon ? "#define PENTAGON\n" : ""); this._highlightsPostProcess.onApply = function (effect) { effect.setFloat('gain', _this._highlightsGain); effect.setFloat('threshold', _this._highlightsThreshold); effect.setTextureFromPostProcess("textureSampler", _this._chromaticAberrationPostProcess); effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth()); effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight()); }; }; // colors shifting and distortion LensRenderingPipeline.prototype._createDepthOfFieldPostProcess = function (ratio) { var _this = this; this._depthOfFieldPostProcess = new BABYLON.PostProcess("LensDepthOfField", "depthOfField", [ "grain_amount", "blur_noise", "screen_width", "screen_height", "distortion", "dof_enabled", "screen_distance", "aperture", "darken", "edge_blur", "highlights", "near", "far" ], ["depthSampler", "grainSampler", "highlightsSampler"], ratio, null, BABYLON.Texture.TRILINEAR_SAMPLINGMODE, this._scene.getEngine(), false); this._depthOfFieldPostProcess.onApply = function (effect) { effect.setTexture("depthSampler", _this._depthTexture); effect.setTexture("grainSampler", _this._grainTexture); effect.setTextureFromPostProcess("textureSampler", _this._highlightsPostProcess); effect.setTextureFromPostProcess("highlightsSampler", _this._depthOfFieldPostProcess); effect.setFloat('grain_amount', _this._grainAmount); effect.setBool('blur_noise', _this._blurNoise); effect.setFloat('screen_width', _this._scene.getEngine().getRenderWidth()); effect.setFloat('screen_height', _this._scene.getEngine().getRenderHeight()); effect.setFloat('distortion', _this._distortion); effect.setBool('dof_enabled', (_this._dofDistance !== -1)); effect.setFloat('screen_distance', 1.0 / (0.1 - 1.0 / _this._dofDistance)); effect.setFloat('aperture', _this._dofAperture); effect.setFloat('darken', _this._dofDarken); effect.setFloat('edge_blur', _this._edgeBlur); effect.setBool('highlights', (_this._highlightsGain !== -1)); if (_this._scene.activeCamera) { effect.setFloat('near', _this._scene.activeCamera.minZ); effect.setFloat('far', _this._scene.activeCamera.maxZ); } }; }; // creates a black and white random noise texture, 512x512 LensRenderingPipeline.prototype._createGrainTexture = function () { var size = 512; this._grainTexture = new BABYLON.DynamicTexture("LensNoiseTexture", size, this._scene, false, BABYLON.Texture.BILINEAR_SAMPLINGMODE); this._grainTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE; this._grainTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE; var context = this._grainTexture.getContext(); var rand = function (min, max) { return Math.random() * (max - min) + min; }; var value; for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { value = Math.floor(rand(0.42, 0.58) * 255); context.fillStyle = 'rgb(' + value + ', ' + value + ', ' + value + ')'; context.fillRect(x, y, 1, 1); } } this._grainTexture.update(false); }; return LensRenderingPipeline; }(BABYLON.PostProcessRenderPipeline)); BABYLON.LensRenderingPipeline = LensRenderingPipeline; })(BABYLON || (BABYLON = {})); //# sourceMappingURL=babylon.lensRenderingPipeline.js.map var BABYLON; (function (BABYLON) { var StandardRenderingPipeline = /** @class */ (function (_super) { __extends(StandardRenderingPipeline, _super); /** * @constructor * @param {string} name - The rendering pipeline name * @param {BABYLON.Scene} scene - The scene linked to this pipeline * @param {any} ratio - The size of the postprocesses (0.5 means that your postprocess will have a width = canvas.width 0.5 and a height = canvas.height 0.5) * @param {BABYLON.PostProcess} originalPostProcess - the custom original color post-process. Must be "reusable". Can be null. * @param {BABYLON.Camera[]} cameras - The array of cameras that the rendering pipeline will be attached to */ function StandardRenderingPipeline(name, scene, ratio, originalPostProcess, cameras) { if (originalPostProcess === void 0) { originalPostProcess = null; } var _this = _super.call(this, scene.getEngine(), name) || this; _this.downSampleX4PostProcess = null; _this.brightPassPostProcess = null; _this.blurHPostProcesses = []; _this.blurVPostProcesses = []; _this.textureAdderPostProcess = null; _this.volumetricLightPostProcess = null; _this.volumetricLightSmoothXPostProcess = null; _this.volumetricLightSmoothYPostProcess = null; _this.volumetricLightMergePostProces = null; _this.volumetricLightFinalPostProcess = null; _this.luminancePostProcess = null; _this.luminanceDownSamplePostProcesses = []; _this.hdrPostProcess = null; _this.textureAdderFinalPostProcess = null; _this.lensFlareFinalPostProcess = null; _this.hdrFinalPostProcess = null; _this.lensFlarePostProcess = null; _this.lensFlareComposePostProcess = null; _this.motionBlurPostProcess = null; _this.depthOfFieldPostProcess = null; // Values _this.brightThreshold = 1.0; _this.blurWidth = 512.0; _this.horizontalBlur = false; _this.exposure = 1.0; _this.lensTexture = null; _this.volumetricLightCoefficient = 0.2; _this.volumetricLightPower = 4.0; _this.volumetricLightBlurScale = 64.0; _this.sourceLight = null; _this.hdrMinimumLuminance = 1.0; _this.hdrDecreaseRate = 0.5; _this.hdrIncreaseRate = 0.5; _this.lensColorTexture = null; _this.lensFlareStrength = 20.0; _this.lensFlareGhostDispersal = 1.4; _this.lensFlareHaloWidth = 0.7; _this.lensFlareDistortionStrength = 16.0; _this.lensStarTexture = null; _this.lensFlareDirtTexture = null; _this.depthOfFieldDistance = 10.0; _this.depthOfFieldBlurWidth = 64.0; _this.motionStrength = 1.0; // IAnimatable _this.animations = []; _this._currentDepthOfFieldSource = null; _this._hdrCurrentLuminance = 1.0; // Getters and setters _this._bloomEnabled = true; _this._depthOfFieldEnabled = false; _this._vlsEnabled = false; _this._lensFlareEnabled = false; _this._hdrEnabled = false; _this._motionBlurEnabled = false; _this._motionBlurSamples = 64.0; _this._volumetricLightStepsCount = 50.0; _this._cameras = cameras || []; // Initialize _this._scene = scene; _this._basePostProcess = originalPostProcess; _this._ratio = ratio; // Misc _this._floatTextureType = scene.getEngine().getCaps().textureFloatRender ? BABYLON.Engine.TEXTURETYPE_FLOAT : BABYLON.Engine.TEXTURETYPE_HALF_FLOAT; // Finish scene.postProcessRenderPipelineManager.addPipeline(_this); _this._buildPipeline(); return _this; } Object.defineProperty(StandardRenderingPipeline.prototype, "BloomEnabled", { get: function () { return this._bloomEnabled; }, set: function (enabled) { if (this._bloomEnabled === enabled) { return; } this._bloomEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "DepthOfFieldEnabled", { get: function () { return this._depthOfFieldEnabled; }, set: function (enabled) { if (this._depthOfFieldEnabled === enabled) { return; } this._depthOfFieldEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "LensFlareEnabled", { get: function () { return this._lensFlareEnabled; }, set: function (enabled) { if (this._lensFlareEnabled === enabled) { return; } this._lensFlareEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "HDREnabled", { get: function () { return this._hdrEnabled; }, set: function (enabled) { if (this._hdrEnabled === enabled) { return; } this._hdrEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "VLSEnabled", { get: function () { return this._vlsEnabled; }, set: function (enabled) { if (this._vlsEnabled === enabled) { return; } if (enabled) { var geometry = this._scene.enableGeometryBufferRenderer(); if (!geometry) { BABYLON.Tools.Warn("Geometry renderer is not supported, cannot create volumetric lights in Standard Rendering Pipeline"); return; } } this._vlsEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "MotionBlurEnabled", { get: function () { return this._motionBlurEnabled; }, set: function (enabled) { if (this._motionBlurEnabled === enabled) { return; } this._motionBlurEnabled = enabled; this._buildPipeline(); }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "volumetricLightStepsCount", { get: function () { return this._volumetricLightStepsCount; }, set: function (count) { if (this.volumetricLightPostProcess) { this.volumetricLightPostProcess.updateEffect("#define VLS\n#define NB_STEPS " + count.toFixed(1)); } this._volumetricLightStepsCount = count; }, enumerable: true, configurable: true }); Object.defineProperty(StandardRenderingPipeline.prototype, "motionBlurSamples", { get: function () { return this._motionBlurSamples; }, set: function (samples) { if (this.motionBlurPostProcess) { this.motionBlurPostProcess.updateEffect("#define MOTION_BLUR\n#define MAX_MOTION_SAMPLES " + samples.toFixed(1)); } this._motionBlurSamples = samples; }, enumerable: true, configurable: true }); StandardRenderingPipeline.prototype._buildPipeline = function () { var _this = this; var ratio = this._ratio; var scene = this._scene; this._disposePostProcesses(); this._reset(); // Create pass post-process if (!this._basePostProcess) { this.originalPostProcess = new BABYLON.PostProcess("HDRPass", "standard", [], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", this._floatTextureType); this.originalPostProcess.onApply = function (effect) { _this._currentDepthOfFieldSource = _this.originalPostProcess; }; } else { this.originalPostProcess = this._basePostProcess; } this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRPassPostProcess", function () { return _this.originalPostProcess; }, true)); this._currentDepthOfFieldSource = this.originalPostProcess; if (this._vlsEnabled) { // Create volumetric light this._createVolumetricLightPostProcess(scene, ratio); // Create volumetric light final post-process this.volumetricLightFinalPostProcess = new BABYLON.PostProcess("HDRVLSFinal", "standard", [], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRVLSFinal", function () { return _this.volumetricLightFinalPostProcess; }, true)); } if (this._bloomEnabled) { // Create down sample X4 post-process this._createDownSampleX4PostProcess(scene, ratio / 2); // Create bright pass post-process this._createBrightPassPostProcess(scene, ratio / 2); // Create gaussian blur post-processes (down sampling blurs) this._createBlurPostProcesses(scene, ratio / 4, 1); // Create texture adder post-process this._createTextureAdderPostProcess(scene, ratio); // Create depth-of-field source post-process this.textureAdderFinalPostProcess = new BABYLON.PostProcess("HDRDepthOfFieldSource", "standard", [], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRBaseDepthOfFieldSource", function () { return _this.textureAdderFinalPostProcess; }, true)); } if (this._lensFlareEnabled) { // Create lens flare post-process this._createLensFlarePostProcess(scene, ratio); // Create depth-of-field source post-process post lens-flare and disable it now this.lensFlareFinalPostProcess = new BABYLON.PostProcess("HDRPostLensFlareDepthOfFieldSource", "standard", [], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRPostLensFlareDepthOfFieldSource", function () { return _this.lensFlareFinalPostProcess; }, true)); } if (this._hdrEnabled) { // Create luminance this._createLuminancePostProcesses(scene, this._floatTextureType); // Create HDR this._createHdrPostProcess(scene, ratio); // Create depth-of-field source post-process post hdr and disable it now this.hdrFinalPostProcess = new BABYLON.PostProcess("HDRPostHDReDepthOfFieldSource", "standard", [], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRPostHDReDepthOfFieldSource", function () { return _this.hdrFinalPostProcess; }, true)); } if (this._depthOfFieldEnabled) { // Create gaussian blur used by depth-of-field this._createBlurPostProcesses(scene, ratio / 2, 3, "depthOfFieldBlurWidth"); // Create depth-of-field post-process this._createDepthOfFieldPostProcess(scene, ratio); } if (this._motionBlurEnabled) { // Create motion blur post-process this._createMotionBlurPostProcess(scene, ratio); } if (this._cameras !== null) { this._scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline(this._name, this._cameras); } }; // Down Sample X4 Post-Processs StandardRenderingPipeline.prototype._createDownSampleX4PostProcess = function (scene, ratio) { var _this = this; var downSampleX4Offsets = new Array(32); this.downSampleX4PostProcess = new BABYLON.PostProcess("HDRDownSampleX4", "standard", ["dsOffsets"], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DOWN_SAMPLE_X4", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.downSampleX4PostProcess.onApply = function (effect) { var id = 0; var width = _this.downSampleX4PostProcess.width; var height = _this.downSampleX4PostProcess.height; for (var i = -2; i < 2; i++) { for (var j = -2; j < 2; j++) { downSampleX4Offsets[id] = (i + 0.5) * (1.0 / width); downSampleX4Offsets[id + 1] = (j + 0.5) * (1.0 / height); id += 2; } } effect.setArray2("dsOffsets", downSampleX4Offsets); }; // Add to pipeline this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRDownSampleX4", function () { return _this.downSampleX4PostProcess; }, true)); }; // Brightpass Post-Process StandardRenderingPipeline.prototype._createBrightPassPostProcess = function (scene, ratio) { var _this = this; var brightOffsets = new Array(8); this.brightPassPostProcess = new BABYLON.PostProcess("HDRBrightPass", "standard", ["dsOffsets", "brightThreshold"], [], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define BRIGHT_PASS", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.brightPassPostProcess.onApply = function (effect) { var sU = (1.0 / _this.brightPassPostProcess.width); var sV = (1.0 / _this.brightPassPostProcess.height); brightOffsets[0] = -0.5 * sU; brightOffsets[1] = 0.5 * sV; brightOffsets[2] = 0.5 * sU; brightOffsets[3] = 0.5 * sV; brightOffsets[4] = -0.5 * sU; brightOffsets[5] = -0.5 * sV; brightOffsets[6] = 0.5 * sU; brightOffsets[7] = -0.5 * sV; effect.setArray2("dsOffsets", brightOffsets); effect.setFloat("brightThreshold", _this.brightThreshold); }; // Add to pipeline this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRBrightPass", function () { return _this.brightPassPostProcess; }, true)); }; // Create blur H&V post-processes StandardRenderingPipeline.prototype._createBlurPostProcesses = function (scene, ratio, indice, blurWidthKey) { var _this = this; if (blurWidthKey === void 0) { blurWidthKey = "blurWidth"; } var engine = scene.getEngine(); var blurX = new BABYLON.BlurPostProcess("HDRBlurH" + "_" + indice, new BABYLON.Vector2(1, 0), this[blurWidthKey], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); var blurY = new BABYLON.BlurPostProcess("HDRBlurV" + "_" + indice, new BABYLON.Vector2(0, 1), this[blurWidthKey], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); blurX.onActivateObservable.add(function () { var dw = blurX.width / engine.getRenderWidth(); blurX.kernel = _this[blurWidthKey] * dw; }); blurY.onActivateObservable.add(function () { var dw = blurY.height / engine.getRenderHeight(); blurY.kernel = _this.horizontalBlur ? 64 * dw : _this[blurWidthKey] * dw; }); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRBlurH" + indice, function () { return blurX; }, true)); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRBlurV" + indice, function () { return blurY; }, true)); this.blurHPostProcesses.push(blurX); this.blurVPostProcesses.push(blurY); }; // Create texture adder post-process StandardRenderingPipeline.prototype._createTextureAdderPostProcess = function (scene, ratio) { var _this = this; this.textureAdderPostProcess = new BABYLON.PostProcess("HDRTextureAdder", "standard", ["exposure"], ["otherSampler", "lensSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define TEXTURE_ADDER", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.textureAdderPostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("otherSampler", _this._vlsEnabled ? _this._currentDepthOfFieldSource : _this.originalPostProcess); effect.setTexture("lensSampler", _this.lensTexture); effect.setFloat("exposure", _this.exposure); _this._currentDepthOfFieldSource = _this.textureAdderFinalPostProcess; }; // Add to pipeline this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRTextureAdder", function () { return _this.textureAdderPostProcess; }, true)); }; StandardRenderingPipeline.prototype._createVolumetricLightPostProcess = function (scene, ratio) { var _this = this; var geometryRenderer = scene.enableGeometryBufferRenderer(); geometryRenderer.enablePosition = true; var geometry = geometryRenderer.getGBuffer(); // Base post-process this.volumetricLightPostProcess = new BABYLON.PostProcess("HDRVLS", "standard", ["shadowViewProjection", "cameraPosition", "sunDirection", "sunColor", "scatteringCoefficient", "scatteringPower", "depthValues"], ["shadowMapSampler", "positionSampler"], ratio / 8, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define VLS\n#define NB_STEPS " + this._volumetricLightStepsCount.toFixed(1)); var depthValues = BABYLON.Vector2.Zero(); this.volumetricLightPostProcess.onApply = function (effect) { if (_this.sourceLight && _this.sourceLight.getShadowGenerator() && _this._scene.activeCamera) { var generator = _this.sourceLight.getShadowGenerator(); effect.setTexture("shadowMapSampler", generator.getShadowMap()); effect.setTexture("positionSampler", geometry.textures[2]); effect.setColor3("sunColor", _this.sourceLight.diffuse); effect.setVector3("sunDirection", _this.sourceLight.getShadowDirection()); effect.setVector3("cameraPosition", _this._scene.activeCamera.globalPosition); effect.setMatrix("shadowViewProjection", generator.getTransformMatrix()); effect.setFloat("scatteringCoefficient", _this.volumetricLightCoefficient); effect.setFloat("scatteringPower", _this.volumetricLightPower); depthValues.x = generator.getLight().getDepthMinZ(_this._scene.activeCamera); depthValues.y = generator.getLight().getDepthMaxZ(_this._scene.activeCamera); effect.setVector2("depthValues", depthValues); } }; this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRVLS", function () { return _this.volumetricLightPostProcess; }, true)); // Smooth this._createBlurPostProcesses(scene, ratio / 4, 0, "volumetricLightBlurScale"); // Merge this.volumetricLightMergePostProces = new BABYLON.PostProcess("HDRVLSMerge", "standard", [], ["originalSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define VLSMERGE"); this.volumetricLightMergePostProces.onApply = function (effect) { effect.setTextureFromPostProcess("originalSampler", _this.originalPostProcess); _this._currentDepthOfFieldSource = _this.volumetricLightFinalPostProcess; }; this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRVLSMerge", function () { return _this.volumetricLightMergePostProces; }, true)); }; // Create luminance StandardRenderingPipeline.prototype._createLuminancePostProcesses = function (scene, textureType) { var _this = this; // Create luminance var size = Math.pow(3, StandardRenderingPipeline.LuminanceSteps); this.luminancePostProcess = new BABYLON.PostProcess("HDRLuminance", "standard", ["lumOffsets"], [], { width: size, height: size }, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LUMINANCE", textureType); var offsets = []; this.luminancePostProcess.onApply = function (effect) { var sU = (1.0 / _this.luminancePostProcess.width); var sV = (1.0 / _this.luminancePostProcess.height); offsets[0] = -0.5 * sU; offsets[1] = 0.5 * sV; offsets[2] = 0.5 * sU; offsets[3] = 0.5 * sV; offsets[4] = -0.5 * sU; offsets[5] = -0.5 * sV; offsets[6] = 0.5 * sU; offsets[7] = -0.5 * sV; effect.setArray2("lumOffsets", offsets); }; // Add to pipeline this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRLuminance", function () { return _this.luminancePostProcess; }, true)); // Create down sample luminance for (var i = StandardRenderingPipeline.LuminanceSteps - 1; i >= 0; i--) { var size = Math.pow(3, i); var defines = "#define LUMINANCE_DOWN_SAMPLE\n"; if (i === 0) { defines += "#define FINAL_DOWN_SAMPLER"; } var postProcess = new BABYLON.PostProcess("HDRLuminanceDownSample" + i, "standard", ["dsOffsets", "halfDestPixelSize"], [], { width: size, height: size }, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, defines, textureType); this.luminanceDownSamplePostProcesses.push(postProcess); } // Create callbacks and add effects var lastLuminance = this.luminancePostProcess; this.luminanceDownSamplePostProcesses.forEach(function (pp, index) { var downSampleOffsets = new Array(18); pp.onApply = function (effect) { if (!lastLuminance) { return; } var id = 0; for (var x = -1; x < 2; x++) { for (var y = -1; y < 2; y++) { downSampleOffsets[id] = x / lastLuminance.width; downSampleOffsets[id + 1] = y / lastLuminance.height; id += 2; } } effect.setArray2("dsOffsets", downSampleOffsets); effect.setFloat("halfDestPixelSize", 0.5 / lastLuminance.width); if (index === _this.luminanceDownSamplePostProcesses.length - 1) { lastLuminance = _this.luminancePostProcess; } else { lastLuminance = pp; } }; if (index === _this.luminanceDownSamplePostProcesses.length - 1) { pp.onAfterRender = function (effect) { var pixel = scene.getEngine().readPixels(0, 0, 1, 1); var bit_shift = new BABYLON.Vector4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0); _this._hdrCurrentLuminance = (pixel[0] * bit_shift.x + pixel[1] * bit_shift.y + pixel[2] * bit_shift.z + pixel[3] * bit_shift.w) / 100.0; }; } _this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRLuminanceDownSample" + index, function () { return pp; }, true)); }); }; // Create HDR post-process StandardRenderingPipeline.prototype._createHdrPostProcess = function (scene, ratio) { var _this = this; this.hdrPostProcess = new BABYLON.PostProcess("HDR", "standard", ["averageLuminance"], ["textureAdderSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define HDR", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); var outputLiminance = 1; var time = 0; var lastTime = 0; this.hdrPostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("textureAdderSampler", _this._currentDepthOfFieldSource); time += scene.getEngine().getDeltaTime(); if (outputLiminance < 0) { outputLiminance = _this._hdrCurrentLuminance; } else { var dt = (lastTime - time) / 1000.0; if (_this._hdrCurrentLuminance < outputLiminance + _this.hdrDecreaseRate * dt) { outputLiminance += _this.hdrDecreaseRate * dt; } else if (_this._hdrCurrentLuminance > outputLiminance - _this.hdrIncreaseRate * dt) { outputLiminance -= _this.hdrIncreaseRate * dt; } else { outputLiminance = _this._hdrCurrentLuminance; } } outputLiminance = BABYLON.Scalar.Clamp(outputLiminance, _this.hdrMinimumLuminance, 1e20); effect.setFloat("averageLuminance", outputLiminance); lastTime = time; _this._currentDepthOfFieldSource = _this.hdrFinalPostProcess; }; this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDR", function () { return _this.hdrPostProcess; }, true)); }; // Create lens flare post-process StandardRenderingPipeline.prototype._createLensFlarePostProcess = function (scene, ratio) { var _this = this; this.lensFlarePostProcess = new BABYLON.PostProcess("HDRLensFlare", "standard", ["strength", "ghostDispersal", "haloWidth", "resolution", "distortionStrength"], ["lensColorSampler"], ratio / 2, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRLensFlare", function () { return _this.lensFlarePostProcess; }, true)); this._createBlurPostProcesses(scene, ratio / 4, 2); this.lensFlareComposePostProcess = new BABYLON.PostProcess("HDRLensFlareCompose", "standard", ["lensStarMatrix"], ["otherSampler", "lensDirtSampler", "lensStarSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE_COMPOSE", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRLensFlareCompose", function () { return _this.lensFlareComposePostProcess; }, true)); var resolution = new BABYLON.Vector2(0, 0); // Lens flare this.lensFlarePostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("textureSampler", _this._bloomEnabled ? _this.blurHPostProcesses[0] : _this.originalPostProcess); effect.setTexture("lensColorSampler", _this.lensColorTexture); effect.setFloat("strength", _this.lensFlareStrength); effect.setFloat("ghostDispersal", _this.lensFlareGhostDispersal); effect.setFloat("haloWidth", _this.lensFlareHaloWidth); // Shift resolution.x = _this.lensFlarePostProcess.width; resolution.y = _this.lensFlarePostProcess.height; effect.setVector2("resolution", resolution); effect.setFloat("distortionStrength", _this.lensFlareDistortionStrength); }; // Compose var scaleBias1 = BABYLON.Matrix.FromValues(2.0, 0.0, -1.0, 0.0, 0.0, 2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); var scaleBias2 = BABYLON.Matrix.FromValues(0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); this.lensFlareComposePostProcess.onApply = function (effect) { if (!_this._scene.activeCamera) { return; } effect.setTextureFromPostProcess("otherSampler", _this._currentDepthOfFieldSource); effect.setTexture("lensDirtSampler", _this.lensFlareDirtTexture); effect.setTexture("lensStarSampler", _this.lensStarTexture); // Lens start rotation matrix var camerax = _this._scene.activeCamera.getViewMatrix().getRow(0); var cameraz = _this._scene.activeCamera.getViewMatrix().getRow(2); var camRot = BABYLON.Vector3.Dot(camerax.toVector3(), new BABYLON.Vector3(1.0, 0.0, 0.0)) + BABYLON.Vector3.Dot(cameraz.toVector3(), new BABYLON.Vector3(0.0, 0.0, 1.0)); camRot *= 4.0; var starRotation = BABYLON.Matrix.FromValues(Math.cos(camRot) * 0.5, -Math.sin(camRot), 0.0, 0.0, Math.sin(camRot), Math.cos(camRot) * 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); var lensStarMatrix = scaleBias2.multiply(starRotation).multiply(scaleBias1); effect.setMatrix("lensStarMatrix", lensStarMatrix); _this._currentDepthOfFieldSource = _this.lensFlareFinalPostProcess; }; }; // Create depth-of-field post-process StandardRenderingPipeline.prototype._createDepthOfFieldPostProcess = function (scene, ratio) { var _this = this; this.depthOfFieldPostProcess = new BABYLON.PostProcess("HDRDepthOfField", "standard", ["distance"], ["otherSampler", "depthSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DEPTH_OF_FIELD", BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); this.depthOfFieldPostProcess.onApply = function (effect) { effect.setTextureFromPostProcess("otherSampler", _this._currentDepthOfFieldSource); effect.setTexture("depthSampler", _this._getDepthTexture()); effect.setFloat("distance", _this.depthOfFieldDistance); }; // Add to pipeline this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRDepthOfField", function () { return _this.depthOfFieldPostProcess; }, true)); }; // Create motion blur post-process StandardRenderingPipeline.prototype._createMotionBlurPostProcess = function (scene, ratio) { var _this = this; this.motionBlurPostProcess = new BABYLON.PostProcess("HDRMotionBlur", "standard", ["inverseViewProjection", "prevViewProjection", "screenSize", "motionScale", "motionStrength"], ["depthSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define MOTION_BLUR\n#define MAX_MOTION_SAMPLES " + this.motionBlurSamples.toFixed(1), BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT); var motionScale = 0; var prevViewProjection = BABYLON.Matrix.Identity(); var invViewProjection = BABYLON.Matrix.Identity(); var viewProjection = BABYLON.Matrix.Identity(); var screenSize = BABYLON.Vector2.Zero(); this.motionBlurPostProcess.onApply = function (effect) { viewProjection = scene.getProjectionMatrix().multiply(scene.getViewMatrix()); viewProjection.invertToRef(invViewProjection); effect.setMatrix("inverseViewProjection", invViewProjection); effect.setMatrix("prevViewProjection", prevViewProjection); prevViewProjection = viewProjection; screenSize.x = _this.motionBlurPostProcess.width; screenSize.y = _this.motionBlurPostProcess.height; effect.setVector2("screenSize", screenSize); motionScale = scene.getEngine().getFps() / 60.0; effect.setFloat("motionScale", motionScale); effect.setFloat("motionStrength", _this.motionStrength); effect.setTexture("depthSampler", _this._getDepthTexture()); }; this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), "HDRMotionBlur", function () { return _this.motionBlurPostProcess; }, true)); }; StandardRenderingPipeline.prototype._getDepthTexture = function () { if (this._scene.getEngine().getCaps().drawBuffersExtension) { var renderer = this._scene.enableGeometryBufferRenderer(); return renderer.getGBuffer().textures[0]; } return this._scene.enableDepthRenderer().getDepthMap(); }; StandardRenderingPipeline.prototype._disposePostProcesses = function () { for (var i = 0; i < this._cameras.length; i++) { var camera = this._cameras[i]; if (this.originalPostProcess) { this.originalPostProcess.dispose(camera); } if (this.downSampleX4PostProcess) { this.downSampleX4PostProcess.dispose(camera); } if (this.brightPassPostProcess) { this.brightPassPostProcess.dispose(camera); } if (this.textureAdderPostProcess) { this.textureAdderPostProcess.dispose(camera); } if (this.textureAdderFinalPostProcess) { this.textureAdderFinalPostProcess.dispose(camera); } if (this.volumetricLightPostProcess) { this.volumetricLightPostProcess.dispose(camera); } if (this.volumetricLightSmoothXPostProcess) { this.volumetricLightSmoothXPostProcess.dispose(camera); } if (this.volumetricLightSmoothYPostProcess) { this.volumetricLightSmoothYPostProcess.dispose(camera); } if (this.volumetricLightMergePostProces) { this.volumetricLightMergePostProces.dispose(camera); } if (this.volumetricLightFinalPostProcess) { this.volumetricLightFinalPostProcess.dispose(camera); } if (this.lensFlarePostProcess) { this.lensFlarePostProcess.dispose(camera); } if (this.lensFlareComposePostProcess) { this.lensFlareComposePostProcess.dispose(camera); } for (var j = 0; j < this.luminanceDownSamplePostProcesses.length; j++) { this.luminanceDownSamplePostProcesses[j].dispose(camera); } if (this.luminancePostProcess) { this.luminancePostProcess.dispose(camera); } if (this.hdrPostProcess) { this.hdrPostProcess.dispose(camera); } if (this.hdrFinalPostProcess) { this.hdrFinalPostProcess.dispose(camera); } if (this.depthOfFieldPostProcess) { this.depthOfFieldPostProcess.dispose(camera); } if (this.motionBlurPostProcess) { this.motionBlurPostProcess.dispose(camera); } for (var j = 0; j < this.blurHPostProcesses.length; j++) { this.blurHPostProcesses[j].dispose(camera); } for (var j = 0; j < this.blurVPostProcesses.length; j++) { this.blurVPostProcesses[j].dispose(camera); } } this.originalPostProcess = null; this.downSampleX4PostProcess = null; this.brightPassPostProcess = null; this.textureAdderPostProcess = null; this.textureAdderFinalPostProcess = null; this.volumetricLightPostProcess = null; this.volumetricLightSmoothXPostProcess = null; this.volumetricLightSmoothYPostProcess = null; this.volumetricLightMergePostProces = null; this.volumetricLightFinalPostProcess = null; this.lensFlarePostProcess = null; this.lensFlareComposePostProcess = null; this.luminancePostProcess = null; this.hdrPostProcess = null; this.hdrFinalPostProcess = null; this.depthOfFieldPostProcess = null; this.motionBlurPostProcess = null; this.luminanceDownSamplePostProcesses = []; this.blurHPostProcesses = []; this.blurVPostProcesses = []; }; // Dispose StandardRenderingPipeline.prototype.dispose = function () { this._disposePostProcesses(); this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras); _super.prototype.dispose.call(this); }; // Serialize rendering pipeline StandardRenderingPipeline.prototype.serialize = function () { var serializationObject = BABYLON.SerializationHelper.Serialize(this); serializationObject.customType = "StandardRenderingPipeline"; return serializationObject; }; /** * Static members */ // Parse serialized pipeline StandardRenderingPipeline.Parse = function (source, scene, rootUrl) { return BABYLON.SerializationHelper.Parse(function () { return new StandardRenderingPipeline(source._name, scene, source._ratio); }, source, scene, rootUrl); }; // Luminance steps StandardRenderingPipeline.LuminanceSteps = 6; __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "brightThreshold", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "blurWidth", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "horizontalBlur", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "exposure", void 0); __decorate([ BABYLON.serializeAsTexture("lensTexture") ], StandardRenderingPipeline.prototype, "lensTexture", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "volumetricLightCoefficient", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "volumetricLightPower", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "volumetricLightBlurScale", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "hdrMinimumLuminance", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "hdrDecreaseRate", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "hdrIncreaseRate", void 0); __decorate([ BABYLON.serializeAsTexture("lensColorTexture") ], StandardRenderingPipeline.prototype, "lensColorTexture", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "lensFlareStrength", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "lensFlareGhostDispersal", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "lensFlareHaloWidth", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "lensFlareDistortionStrength", void 0); __decorate([ BABYLON.serializeAsTexture("lensStarTexture") ], StandardRenderingPipeline.prototype, "lensStarTexture", void 0); __decorate([ BABYLON.serializeAsTexture("lensFlareDirtTexture") ], StandardRenderingPipeline.prototype, "lensFlareDirtTexture", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "depthOfFieldDistance", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "depthOfFieldBlurWidth", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "motionStrength", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "_ratio", void 0); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "BloomEnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "DepthOfFieldEnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "LensFlareEnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "HDREnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "VLSEnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "MotionBlurEnabled", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "volumetricLightStepsCount", null); __decorate([ BABYLON.serialize() ], StandardRenderingPipeline.prototype, "motionBlurSamples", null); return StandardRenderingPipeline; }(BABYLON.PostProcessRenderPipeline)); BABYLON.StandardRenderingPipeline = StandardRenderingPipeline; })(BABYLON || (BABYLON = {})); //# sourceMappingURL=babylon.standardRenderingPipeline.js.map BABYLON.Effect.ShadersStore['defaultVertexShader'] = "#include<__decl__defaultVertex>\n\nattribute vec3 position;\n#ifdef NORMAL\nattribute vec3 normal;\n#endif\n#ifdef TANGENT\nattribute vec4 tangent;\n#endif\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#ifdef VERTEXCOLOR\nattribute vec4 color;\n#endif\n#include\n#include\n\n#include\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nvarying vec2 vDiffuseUV;\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nvarying vec2 vAmbientUV;\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nvarying vec2 vOpacityUV;\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nvarying vec2 vEmissiveUV;\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nvarying vec2 vLightmapUV;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nvarying vec2 vSpecularUV;\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nvarying vec2 vBumpUV;\n#endif\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#include\n#include\n#include\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include\n#include[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#include\nvoid main(void) {\nvec3 positionUpdated=position;\n#ifdef NORMAL \nvec3 normalUpdated=normal;\n#endif\n#ifdef TANGENT\nvec4 tangentUpdated=tangent;\n#endif\n#include[0..maxSimultaneousMorphTargets]\n#ifdef REFLECTIONMAP_SKYBOX\nvPositionUVW=positionUpdated;\n#endif \n#include\n#include\ngl_Position=viewProjection*finalWorld*vec4(positionUpdated,1.0);\nvec4 worldPos=finalWorld*vec4(positionUpdated,1.0);\nvPositionW=vec3(worldPos);\n#ifdef NORMAL\nmat3 normalWorld=mat3(finalWorld);\n#ifdef NONUNIFORMSCALING\nnormalWorld=transposeMat3(inverseMat3(normalWorld));\n#endif\nvNormalW=normalize(normalWorld*normalUpdated);\n#endif\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvDirectionW=normalize(vec3(finalWorld*vec4(positionUpdated,0.0)));\n#endif\n\n#ifndef UV1\nvec2 uv=vec2(0.,0.);\n#endif\n#ifndef UV2\nvec2 uv2=vec2(0.,0.);\n#endif\n#ifdef MAINUV1\nvMainUV1=uv;\n#endif\n#ifdef MAINUV2\nvMainUV2=uv2;\n#endif\n#if defined(DIFFUSE) && DIFFUSEDIRECTUV == 0\nif (vDiffuseInfos.x == 0.)\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvDiffuseUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(AMBIENT) && AMBIENTDIRECTUV == 0\nif (vAmbientInfos.x == 0.)\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvAmbientUV=vec2(ambientMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(OPACITY) && OPACITYDIRECTUV == 0\nif (vOpacityInfos.x == 0.)\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvOpacityUV=vec2(opacityMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(EMISSIVE) && EMISSIVEDIRECTUV == 0\nif (vEmissiveInfos.x == 0.)\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvEmissiveUV=vec2(emissiveMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(LIGHTMAP) && LIGHTMAPDIRECTUV == 0\nif (vLightmapInfos.x == 0.)\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvLightmapUV=vec2(lightmapMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM) && SPECULARDIRECTUV == 0\nif (vSpecularInfos.x == 0.)\n{\nvSpecularUV=vec2(specularMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvSpecularUV=vec2(specularMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#if defined(BUMP) && BUMPDIRECTUV == 0\nif (vBumpInfos.x == 0.)\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv,1.0,0.0));\n}\nelse\n{\nvBumpUV=vec2(bumpMatrix*vec4(uv2,1.0,0.0));\n}\n#endif\n#include\n#include\n#include\n#include[0..maxSimultaneousLights]\n#ifdef VERTEXCOLOR\n\nvColor=color;\n#endif\n#include\n#include\n}"; BABYLON.Effect.ShadersStore['defaultPixelShader'] = "#include<__decl__defaultFragment>\n#if defined(BUMP) || !defined(NORMAL)\n#extension GL_OES_standard_derivatives : enable\n#endif\n#ifdef LOGARITHMICDEPTH\n#extension GL_EXT_frag_depth : enable\n#endif\n\n#define RECIPROCAL_PI2 0.15915494\nuniform vec3 vEyePosition;\nuniform vec3 vAmbientColor;\n\nvarying vec3 vPositionW;\n#ifdef NORMAL\nvarying vec3 vNormalW;\n#endif\n#ifdef VERTEXCOLOR\nvarying vec4 vColor;\n#endif\n#ifdef MAINUV1\nvarying vec2 vMainUV1;\n#endif\n#ifdef MAINUV2\nvarying vec2 vMainUV2;\n#endif\n\n#include\n\n#include<__decl__lightFragment>[0..maxSimultaneousLights]\n#include\n#include\n\n#ifdef DIFFUSE\n#if DIFFUSEDIRECTUV == 1\n#define vDiffuseUV vMainUV1\n#elif DIFFUSEDIRECTUV == 2\n#define vDiffuseUV vMainUV2\n#else\nvarying vec2 vDiffuseUV;\n#endif\nuniform sampler2D diffuseSampler;\n#endif\n#ifdef AMBIENT\n#if AMBIENTDIRECTUV == 1\n#define vAmbientUV vMainUV1\n#elif AMBIENTDIRECTUV == 2\n#define vAmbientUV vMainUV2\n#else\nvarying vec2 vAmbientUV;\n#endif\nuniform sampler2D ambientSampler;\n#endif\n#ifdef OPACITY \n#if OPACITYDIRECTUV == 1\n#define vOpacityUV vMainUV1\n#elif OPACITYDIRECTUV == 2\n#define vOpacityUV vMainUV2\n#else\nvarying vec2 vOpacityUV;\n#endif\nuniform sampler2D opacitySampler;\n#endif\n#ifdef EMISSIVE\n#if EMISSIVEDIRECTUV == 1\n#define vEmissiveUV vMainUV1\n#elif EMISSIVEDIRECTUV == 2\n#define vEmissiveUV vMainUV2\n#else\nvarying vec2 vEmissiveUV;\n#endif\nuniform sampler2D emissiveSampler;\n#endif\n#ifdef LIGHTMAP\n#if LIGHTMAPDIRECTUV == 1\n#define vLightmapUV vMainUV1\n#elif LIGHTMAPDIRECTUV == 2\n#define vLightmapUV vMainUV2\n#else\nvarying vec2 vLightmapUV;\n#endif\nuniform sampler2D lightmapSampler;\n#endif\n#ifdef REFRACTION\n#ifdef REFRACTIONMAP_3D\nuniform samplerCube refractionCubeSampler;\n#else\nuniform sampler2D refraction2DSampler;\n#endif\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\n#if SPECULARDIRECTUV == 1\n#define vSpecularUV vMainUV1\n#elif SPECULARDIRECTUV == 2\n#define vSpecularUV vMainUV2\n#else\nvarying vec2 vSpecularUV;\n#endif\nuniform sampler2D specularSampler;\n#endif\n\n#include\n\n#ifdef REFLECTION\n#ifdef REFLECTIONMAP_3D\nuniform samplerCube reflectionCubeSampler;\n#else\nuniform sampler2D reflection2DSampler;\n#endif\n#ifdef REFLECTIONMAP_SKYBOX\nvarying vec3 vPositionUVW;\n#else\n#if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)\nvarying vec3 vDirectionW;\n#endif\n#endif\n#include\n#endif\n#include\n#include\n#include\n#include\n#include\n#include\nvoid main(void) {\n#include\nvec3 viewDirectionW=normalize(vEyePosition-vPositionW);\n\nvec4 baseColor=vec4(1.,1.,1.,1.);\nvec3 diffuseColor=vDiffuseColor.rgb;\n\nfloat alpha=vDiffuseColor.a;\n\n#ifdef NORMAL\nvec3 normalW=normalize(vNormalW);\n#else\nvec3 normalW=normalize(-cross(dFdx(vPositionW),dFdy(vPositionW)));\n#endif\n#include\n#ifdef TWOSIDEDLIGHTING\nnormalW=gl_FrontFacing ? normalW : -normalW;\n#endif\n#ifdef DIFFUSE\nbaseColor=texture2D(diffuseSampler,vDiffuseUV+uvOffset);\n#ifdef ALPHATEST\nif (baseColor.a<0.4)\ndiscard;\n#endif\n#ifdef ALPHAFROMDIFFUSE\nalpha*=baseColor.a;\n#endif\nbaseColor.rgb*=vDiffuseInfos.y;\n#endif\n#include\n#ifdef VERTEXCOLOR\nbaseColor.rgb*=vColor.rgb;\n#endif\n\nvec3 baseAmbientColor=vec3(1.,1.,1.);\n#ifdef AMBIENT\nbaseAmbientColor=texture2D(ambientSampler,vAmbientUV+uvOffset).rgb*vAmbientInfos.y;\n#endif\n\n#ifdef SPECULARTERM\nfloat glossiness=vSpecularColor.a;\nvec3 specularColor=vSpecularColor.rgb;\n#ifdef SPECULAR\nvec4 specularMapColor=texture2D(specularSampler,vSpecularUV+uvOffset);\nspecularColor=specularMapColor.rgb;\n#ifdef GLOSSINESS\nglossiness=glossiness*specularMapColor.a;\n#endif\n#endif\n#else\nfloat glossiness=0.;\n#endif\n\nvec3 diffuseBase=vec3(0.,0.,0.);\nlightingInfo info;\n#ifdef SPECULARTERM\nvec3 specularBase=vec3(0.,0.,0.);\n#endif\nfloat shadow=1.;\n#ifdef LIGHTMAP\nvec3 lightmapColor=texture2D(lightmapSampler,vLightmapUV+uvOffset).rgb*vLightmapInfos.y;\n#endif\n#include[0..maxSimultaneousLights]\n\nvec3 refractionColor=vec3(0.,0.,0.);\n#ifdef REFRACTION\nvec3 refractionVector=normalize(refract(-viewDirectionW,normalW,vRefractionInfos.y));\n#ifdef REFRACTIONMAP_3D\nrefractionVector.y=refractionVector.y*vRefractionInfos.w;\nif (dot(refractionVector,viewDirectionW)<1.0)\n{\nrefractionColor=textureCube(refractionCubeSampler,refractionVector).rgb*vRefractionInfos.x;\n}\n#else\nvec3 vRefractionUVW=vec3(refractionMatrix*(view*vec4(vPositionW+refractionVector*vRefractionInfos.z,1.0)));\nvec2 refractionCoords=vRefractionUVW.xy/vRefractionUVW.z;\nrefractionCoords.y=1.0-refractionCoords.y;\nrefractionColor=texture2D(refraction2DSampler,refractionCoords).rgb*vRefractionInfos.x;\n#endif\n#endif\n\nvec3 reflectionColor=vec3(0.,0.,0.);\n#ifdef REFLECTION\nvec3 vReflectionUVW=computeReflectionCoords(vec4(vPositionW,1.0),normalW);\n#ifdef REFLECTIONMAP_3D\n#ifdef ROUGHNESS\nfloat bias=vReflectionInfos.y;\n#ifdef SPECULARTERM\n#ifdef SPECULAR\n#ifdef GLOSSINESS\nbias*=(1.0-specularMapColor.a);\n#endif\n#endif\n#endif\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW,bias).rgb*vReflectionInfos.x;\n#else\nreflectionColor=textureCube(reflectionCubeSampler,vReflectionUVW).rgb*vReflectionInfos.x;\n#endif\n#else\nvec2 coords=vReflectionUVW.xy;\n#ifdef REFLECTIONMAP_PROJECTION\ncoords/=vReflectionUVW.z;\n#endif\ncoords.y=1.0-coords.y;\nreflectionColor=texture2D(reflection2DSampler,coords).rgb*vReflectionInfos.x;\n#endif\n#ifdef REFLECTIONFRESNEL\nfloat reflectionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,reflectionRightColor.a,reflectionLeftColor.a);\n#ifdef REFLECTIONFRESNELFROMSPECULAR\n#ifdef SPECULARTERM\nreflectionColor*=specularColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#else\nreflectionColor*=reflectionLeftColor.rgb*(1.0-reflectionFresnelTerm)+reflectionFresnelTerm*reflectionRightColor.rgb;\n#endif\n#endif\n#endif\n#ifdef REFRACTIONFRESNEL\nfloat refractionFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,refractionRightColor.a,refractionLeftColor.a);\nrefractionColor*=refractionLeftColor.rgb*(1.0-refractionFresnelTerm)+refractionFresnelTerm*refractionRightColor.rgb;\n#endif\n#ifdef OPACITY\nvec4 opacityMap=texture2D(opacitySampler,vOpacityUV+uvOffset);\n#ifdef OPACITYRGB\nopacityMap.rgb=opacityMap.rgb*vec3(0.3,0.59,0.11);\nalpha*=(opacityMap.x+opacityMap.y+opacityMap.z)* vOpacityInfos.y;\n#else\nalpha*=opacityMap.a*vOpacityInfos.y;\n#endif\n#endif\n#ifdef VERTEXALPHA\nalpha*=vColor.a;\n#endif\n#ifdef OPACITYFRESNEL\nfloat opacityFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,opacityParts.z,opacityParts.w);\nalpha+=opacityParts.x*(1.0-opacityFresnelTerm)+opacityFresnelTerm*opacityParts.y;\n#endif\n\nvec3 emissiveColor=vEmissiveColor;\n#ifdef EMISSIVE\nemissiveColor+=texture2D(emissiveSampler,vEmissiveUV+uvOffset).rgb*vEmissiveInfos.y;\n#endif\n#ifdef EMISSIVEFRESNEL\nfloat emissiveFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,emissiveRightColor.a,emissiveLeftColor.a);\nemissiveColor*=emissiveLeftColor.rgb*(1.0-emissiveFresnelTerm)+emissiveFresnelTerm*emissiveRightColor.rgb;\n#endif\n\n#ifdef DIFFUSEFRESNEL\nfloat diffuseFresnelTerm=computeFresnelTerm(viewDirectionW,normalW,diffuseRightColor.a,diffuseLeftColor.a);\ndiffuseBase*=diffuseLeftColor.rgb*(1.0-diffuseFresnelTerm)+diffuseFresnelTerm*diffuseRightColor.rgb;\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\n#ifdef LINKEMISSIVEWITHDIFFUSE\nvec3 finalDiffuse=clamp((diffuseBase+emissiveColor)*diffuseColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#else\nvec3 finalDiffuse=clamp(diffuseBase*diffuseColor+emissiveColor+vAmbientColor,0.0,1.0)*baseColor.rgb;\n#endif\n#endif\n#ifdef SPECULARTERM\nvec3 finalSpecular=specularBase*specularColor;\n#ifdef SPECULAROVERALPHA\nalpha=clamp(alpha+dot(finalSpecular,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n#else\nvec3 finalSpecular=vec3(0.0);\n#endif\n#ifdef REFLECTIONOVERALPHA\nalpha=clamp(alpha+dot(reflectionColor,vec3(0.3,0.59,0.11)),0.,1.);\n#endif\n\n#ifdef EMISSIVEASILLUMINATION\nvec4 color=vec4(clamp(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+emissiveColor+refractionColor,0.0,1.0),alpha);\n#else\nvec4 color=vec4(finalDiffuse*baseAmbientColor+finalSpecular+reflectionColor+refractionColor,alpha);\n#endif\n\n#ifdef LIGHTMAP\n#ifndef LIGHTMAPEXCLUDED\n#ifdef USELIGHTMAPASSHADOWMAP\ncolor.rgb*=lightmapColor;\n#else\ncolor.rgb+=lightmapColor;\n#endif\n#endif\n#endif\n#include\n#include\n\n\n#ifdef IMAGEPROCESSINGPOSTPROCESS\ncolor.rgb=toLinearSpace(color.rgb);\n#else\n#ifdef IMAGEPROCESSING\ncolor.rgb=toLinearSpace(color.rgb);\ncolor=applyImageProcessing(color);\n#endif\n#endif\n#ifdef PREMULTIPLYALPHA\n\ncolor.rgb*=color.a;\n#endif\ngl_FragColor=color;\n}"; BABYLON.Effect.ShadersStore['postprocessVertexShader'] = "\nattribute vec2 position;\nuniform vec2 scale;\n\nvarying vec2 vUV;\nconst vec2 madd=vec2(0.5,0.5);\nvoid main(void) { \nvUV=(position*madd+madd)*scale;\ngl_Position=vec4(position,0.0,1.0);\n}"; BABYLON.Effect.ShadersStore['passPixelShader'] = "\nvarying vec2 vUV;\nuniform sampler2D textureSampler;\nvoid main(void) \n{\ngl_FragColor=texture2D(textureSampler,vUV);\n}"; BABYLON.Effect.ShadersStore['depthVertexShader'] = "\nattribute vec3 position;\n#include\n\n#include\nuniform mat4 viewProjection;\nuniform vec2 depthValues;\n#if defined(ALPHATEST) || defined(NEED_UV)\nvarying vec2 vUV;\nuniform mat4 diffuseMatrix;\n#ifdef UV1\nattribute vec2 uv;\n#endif\n#ifdef UV2\nattribute vec2 uv2;\n#endif\n#endif\nvarying float vDepthMetric;\nvoid main(void)\n{\n#include\n#include\ngl_Position=viewProjection*finalWorld*vec4(position,1.0);\nvDepthMetric=((gl_Position.z+depthValues.x)/(depthValues.y));\n#if defined(ALPHATEST) || defined(BASIC_RENDER)\n#ifdef UV1\nvUV=vec2(diffuseMatrix*vec4(uv,1.0,0.0));\n#endif\n#ifdef UV2\nvUV=vec2(diffuseMatrix*vec4(uv2,1.0,0.0));\n#endif\n#endif\n}"; BABYLON.Effect.ShadersStore['depthPixelShader'] = "#ifdef ALPHATEST\nvarying vec2 vUV;\nuniform sampler2D diffuseSampler;\n#endif\nvarying float vDepthMetric;\nvoid main(void)\n{\n#ifdef ALPHATEST\nif (texture2D(diffuseSampler,vUV).a<0.4)\ndiscard;\n#endif\ngl_FragColor=vec4(vDepthMetric,vDepthMetric*vDepthMetric,0.0,1.0);\n}"; BABYLON.Effect.ShadersStore['ssaoPixelShader'] = "\nuniform sampler2D textureSampler;\nvarying vec2 vUV;\n#ifdef SSAO\nuniform sampler2D randomSampler;\nuniform float randTextureTiles;\nuniform float samplesFactor;\nuniform vec3 sampleSphere[SAMPLES];\nuniform float totalStrength;\nuniform float radius;\nuniform float area;\nuniform float fallOff;\nuniform float base;\nvec3 normalFromDepth(float depth,vec2 coords)\n{\nvec2 offset1=vec2(0.0,radius);\nvec2 offset2=vec2(radius,0.0);\nfloat depth1=texture2D(textureSampler,coords+offset1).r;\nfloat depth2=texture2D(textureSampler,coords+offset2).r;\nvec3 p1=vec3(offset1,depth1-depth);\nvec3 p2=vec3(offset2,depth2-depth);\nvec3 normal=cross(p1,p2);\nnormal.z=-normal.z;\nreturn normalize(normal);\n}\nvoid main()\n{\nvec3 random=normalize(texture2D(randomSampler,vUV*randTextureTiles).rgb);\nfloat depth=texture2D(textureSampler,vUV).r;\nvec3 position=vec3(vUV,depth);\nvec3 normal=normalFromDepth(depth,vUV);\nfloat radiusDepth=radius/depth;\nfloat occlusion=0.0;\nvec3 ray;\nvec3 hemiRay;\nfloat occlusionDepth;\nfloat difference;\nfor (int i=0; i