123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827 |
- import arraySlice from '../Core/arraySlice.js';
- import Check from '../Core/Check.js';
- import defined from '../Core/defined.js';
- import defineProperties from '../Core/defineProperties.js';
- import destroyObject from '../Core/destroyObject.js';
- import DeveloperError from '../Core/DeveloperError.js';
- import PixelFormat from '../Core/PixelFormat.js';
- import PixelDatatype from '../Renderer/PixelDatatype.js';
- import Sampler from '../Renderer/Sampler.js';
- import Texture from '../Renderer/Texture.js';
- import TextureMagnificationFilter from '../Renderer/TextureMagnificationFilter.js';
- import TextureMinificationFilter from '../Renderer/TextureMinificationFilter.js';
- import TextureWrap from '../Renderer/TextureWrap.js';
- import PassThrough from '../Shaders/PostProcessStages/PassThrough.js';
- import PostProcessStageLibrary from './PostProcessStageLibrary.js';
- import PostProcessStageTextureCache from './PostProcessStageTextureCache.js';
- import Tonemapper from './Tonemapper.js';
- var stackScratch = [];
- /**
- * A collection of {@link PostProcessStage}s and/or {@link PostProcessStageComposite}s.
- * <p>
- * The input texture for each post-process stage is the texture rendered to by the scene or the texture rendered
- * to by the previous stage in the collection.
- * </p>
- * <p>
- * If the ambient occlusion or bloom stages are enabled, they will execute before all other stages.
- * </p>
- * <p>
- * If the FXAA stage is enabled, it will execute after all other stages.
- * </p>
- *
- * @alias PostProcessStageCollection
- * @constructor
- */
- function PostProcessStageCollection() {
- var fxaa = PostProcessStageLibrary.createFXAAStage();
- var ao = PostProcessStageLibrary.createAmbientOcclusionStage();
- var bloom = PostProcessStageLibrary.createBloomStage();
- // Auto-exposure is currently disabled because most shaders output a value in [0.0, 1.0].
- // Some shaders, such as the atmosphere and ground atmosphere, output values slightly over 1.0.
- this._autoExposureEnabled = false;
- this._autoExposure = PostProcessStageLibrary.createAutoExposureStage();
- this._tonemapping = undefined;
- this._tonemapper = undefined;
- // set tonemapper and tonemapping
- this.tonemapper = Tonemapper.ACES;
- var tonemapping = this._tonemapping;
- fxaa.enabled = false;
- ao.enabled = false;
- bloom.enabled = false;
- tonemapping.enabled = false; // will be enabled if necessary in update
- var textureCache = new PostProcessStageTextureCache(this);
- var stageNames = {};
- var stack = stackScratch;
- stack.push(fxaa, ao, bloom, tonemapping);
- while (stack.length > 0) {
- var stage = stack.pop();
- stageNames[stage.name] = stage;
- stage._textureCache = textureCache;
- var length = stage.length;
- if (defined(length)) {
- for (var i = 0; i < length; ++i) {
- stack.push(stage.get(i));
- }
- }
- }
- this._stages = [];
- this._activeStages = [];
- this._previousActiveStages = [];
- this._randomTexture = undefined; // For AO
- var that = this;
- ao.uniforms.randomTexture = function() {
- return that._randomTexture;
- };
- this._ao = ao;
- this._bloom = bloom;
- this._fxaa = fxaa;
- this._lastLength = undefined;
- this._aoEnabled = undefined;
- this._bloomEnabled = undefined;
- this._tonemappingEnabled = undefined;
- this._fxaaEnabled = undefined;
- this._stagesRemoved = false;
- this._textureCacheDirty = false;
- this._stageNames = stageNames;
- this._textureCache = textureCache;
- }
- defineProperties(PostProcessStageCollection.prototype, {
- /**
- * Determines if all of the post-process stages in the collection are ready to be executed.
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {Boolean}
- * @readonly
- */
- ready : {
- get : function() {
- var readyAndEnabled = false;
- var stages = this._stages;
- var length = stages.length;
- for (var i = length - 1; i >= 0; --i) {
- var stage = stages[i];
- readyAndEnabled = readyAndEnabled || (stage.ready && stage.enabled);
- }
- var fxaa = this._fxaa;
- var ao = this._ao;
- var bloom = this._bloom;
- var tonemapping = this._tonemapping;
- readyAndEnabled = readyAndEnabled || (fxaa.ready && fxaa.enabled);
- readyAndEnabled = readyAndEnabled || (ao.ready && ao.enabled);
- readyAndEnabled = readyAndEnabled || (bloom.ready && bloom.enabled);
- readyAndEnabled = readyAndEnabled || (tonemapping.ready && tonemapping.enabled);
- return readyAndEnabled;
- }
- },
- /**
- * A post-process stage for Fast Approximate Anti-aliasing.
- * <p>
- * When enabled, this stage will execute after all others.
- * </p>
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {PostProcessStage}
- * @readonly
- */
- fxaa : {
- get : function() {
- return this._fxaa;
- }
- },
- /**
- * A post-process stage that applies Horizon-based Ambient Occlusion (HBAO) to the input texture.
- * <p>
- * Ambient occlusion simulates shadows from ambient light. These shadows would always be present when the
- * surface receives light and regardless of the light's position.
- * </p>
- * <p>
- * The uniforms have the following properties: <code>intensity</code>, <code>bias</code>, <code>lengthCap</code>,
- * <code>stepSize</code>, <code>frustumLength</code>, <code>ambientOcclusionOnly</code>,
- * <code>delta</code>, <code>sigma</code>, and <code>blurStepSize</code>.
- * </p>
- * <ul>
- * <li><code>intensity</code> is a scalar value used to lighten or darken the shadows exponentially. Higher values make the shadows darker. The default value is <code>3.0</code>.</li>
- *
- * <li><code>bias</code> is a scalar value representing an angle in radians. If the dot product between the normal of the sample and the vector to the camera is less than this value,
- * sampling stops in the current direction. This is used to remove shadows from near planar edges. The default value is <code>0.1</code>.</li>
- *
- * <li><code>lengthCap</code> is a scalar value representing a length in meters. If the distance from the current sample to first sample is greater than this value,
- * sampling stops in the current direction. The default value is <code>0.26</code>.</li>
- *
- * <li><code>stepSize</code> is a scalar value indicating the distance to the next texel sample in the current direction. The default value is <code>1.95</code>.</li>
- *
- * <li><code>frustumLength</code> is a scalar value in meters. If the current fragment has a distance from the camera greater than this value, ambient occlusion is not computed for the fragment.
- * The default value is <code>1000.0</code>.</li>
- *
- * <li><code>ambientOcclusionOnly</code> is a boolean value. When <code>true</code>, only the shadows generated are written to the output. When <code>false</code>, the input texture is modulated
- * with the ambient occlusion. This is a useful debug option for seeing the effects of changing the uniform values. The default value is <code>false</code>.</li>
- * </ul>
- * <p>
- * <code>delta</code>, <code>sigma</code>, and <code>blurStepSize</code> are the same properties as {@link PostProcessStageLibrary#createBlurStage}.
- * The blur is applied to the shadows generated from the image to make them smoother.
- * </p>
- * <p>
- * When enabled, this stage will execute before all others.
- * </p>
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {PostProcessStageComposite}
- * @readonly
- */
- ambientOcclusion : {
- get : function() {
- return this._ao;
- }
- },
- /**
- * A post-process stage for a bloom effect.
- * <p>
- * A bloom effect adds glow effect, makes bright areas brighter, and dark areas darker.
- * </p>
- * <p>
- * This stage has the following uniforms: <code>contrast</code>, <code>brightness</code>, <code>glowOnly</code>,
- * <code>delta</code>, <code>sigma</code>, and <code>stepSize</code>.
- * </p>
- * <ul>
- * <li><code>contrast</code> is a scalar value in the range [-255.0, 255.0] and affects the contract of the effect. The default value is <code>128.0</code>.</li>
- *
- * <li><code>brightness</code> is a scalar value. The input texture RGB value is converted to hue, saturation, and brightness (HSB) then this value is
- * added to the brightness. The default value is <code>-0.3</code>.</li>
- *
- * <li><code>glowOnly</code> is a boolean value. When <code>true</code>, only the glow effect will be shown. When <code>false</code>, the glow will be added to the input texture.
- * The default value is <code>false</code>. This is a debug option for viewing the effects when changing the other uniform values.</li>
- * </ul>
- * <p>
- * <code>delta</code>, <code>sigma</code>, and <code>stepSize</code> are the same properties as {@link PostProcessStageLibrary#createBlurStage}.
- * The blur is applied to the shadows generated from the image to make them smoother.
- * </p>
- * <p>
- * When enabled, this stage will execute before all others.
- * </p>
- *
- * @memberOf PostProcessStageCollection.prototype
- * @type {PostProcessStageComposite}
- * @readonly
- */
- bloom : {
- get : function() {
- return this._bloom;
- }
- },
- /**
- * The number of post-process stages in this collection.
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {Number}
- * @readonly
- */
- length : {
- get : function() {
- removeStages(this);
- return this._stages.length;
- }
- },
- /**
- * A reference to the last texture written to when executing the post-process stages in this collection.
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {Texture}
- * @readonly
- * @private
- */
- outputTexture : {
- get : function() {
- var fxaa = this._fxaa;
- if (fxaa.enabled && fxaa.ready) {
- return this.getOutputTexture(fxaa.name);
- }
- var stages = this._stages;
- var length = stages.length;
- for (var i = length - 1; i >= 0; --i) {
- var stage = stages[i];
- if (defined(stage) && stage.ready && stage.enabled) {
- return this.getOutputTexture(stage.name);
- }
- }
- var tonemapping = this._tonemapping;
- if (tonemapping.enabled && tonemapping.ready) {
- return this.getOutputTexture(tonemapping.name);
- }
- var bloom = this._bloom;
- if (bloom.enabled && bloom.ready) {
- return this.getOutputTexture(bloom.name);
- }
- var ao = this._ao;
- if (ao.enabled && ao.ready) {
- return this.getOutputTexture(ao.name);
- }
- return undefined;
- }
- },
- /**
- * Whether the collection has a stage that has selected features.
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {Boolean}
- * @readonly
- * @private
- */
- hasSelected : {
- get : function() {
- var stages = arraySlice(this._stages);
- while (stages.length > 0) {
- var stage = stages.pop();
- if (!defined(stage)) {
- continue;
- }
- if (defined(stage.selected)) {
- return true;
- }
- var length = stage.length;
- if (defined(length)) {
- for (var i = 0; i < length; ++i) {
- stages.push(stage.get(i));
- }
- }
- }
- return false;
- }
- },
- /**
- * Gets and sets the tonemapping algorithm used when rendering with high dynamic range.
- *
- * @memberof PostProcessStageCollection.prototype
- * @type {Tonemapper}
- * @private
- */
- tonemapper : {
- get : function() {
- return this._tonemapper;
- },
- set : function(value) {
- if (this._tonemapper === value) {
- return;
- }
- //>>includeStart('debug', pragmas.debug);
- if (!Tonemapper.validate(value)) {
- throw new DeveloperError('tonemapper was set to an invalid value.');
- }
- //>>includeEnd('debug');
- if (defined(this._tonemapping)) {
- delete this._stageNames[this._tonemapping.name];
- this._tonemapping.destroy();
- }
- var useAutoExposure = this._autoExposureEnabled;
- var tonemapper;
- switch(value) {
- case Tonemapper.REINHARD:
- tonemapper = PostProcessStageLibrary.createReinhardTonemappingStage(useAutoExposure);
- break;
- case Tonemapper.MODIFIED_REINHARD:
- tonemapper = PostProcessStageLibrary.createModifiedReinhardTonemappingStage(useAutoExposure);
- break;
- case Tonemapper.FILMIC:
- tonemapper = PostProcessStageLibrary.createFilmicTonemappingStage(useAutoExposure);
- break;
- default:
- tonemapper = PostProcessStageLibrary.createAcesTonemappingStage(useAutoExposure);
- break;
- }
- if (useAutoExposure) {
- var autoexposure = this._autoExposure;
- tonemapper.uniforms.autoExposure = function() {
- return autoexposure.outputTexture;
- };
- }
- this._tonemapper = value;
- this._tonemapping = tonemapper;
- if (defined(this._stageNames)) {
- this._stageNames[tonemapper.name] = tonemapper;
- tonemapper._textureCache = this._textureCache;
- }
- this._textureCacheDirty = true;
- }
- }
- });
- function removeStages(collection) {
- if (!collection._stagesRemoved) {
- return;
- }
- collection._stagesRemoved = false;
- var newStages = [];
- var stages = collection._stages;
- var length = stages.length;
- for (var i = 0, j = 0; i < length; ++i) {
- var stage = stages[i];
- if (stage) {
- stage._index = j++;
- newStages.push(stage);
- }
- }
- collection._stages = newStages;
- }
- /**
- * Adds the post-process stage to the collection.
- *
- * @param {PostProcessStage|PostProcessStageComposite} stage The post-process stage to add to the collection.
- * @return {PostProcessStage|PostProcessStageComposite} The post-process stage that was added to the collection.
- *
- * @exception {DeveloperError} The post-process stage has already been added to the collection or does not have a unique name.
- */
- PostProcessStageCollection.prototype.add = function(stage) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object('stage', stage);
- //>>includeEnd('debug');
- var stageNames = this._stageNames;
- var stack = stackScratch;
- stack.push(stage);
- while (stack.length > 0) {
- var currentStage = stack.pop();
- //>>includeStart('debug', pragmas.debug);
- if (defined(stageNames[currentStage.name])) {
- throw new DeveloperError(currentStage.name + ' has already been added to the collection or does not have a unique name.');
- }
- //>>includeEnd('debug');
- stageNames[currentStage.name] = currentStage;
- currentStage._textureCache = this._textureCache;
- var length = currentStage.length;
- if (defined(length)) {
- for (var i = 0; i < length; ++i) {
- stack.push(currentStage.get(i));
- }
- }
- }
- var stages = this._stages;
- stage._index = stages.length;
- stages.push(stage);
- this._textureCacheDirty = true;
- return stage;
- };
- /**
- * Removes a post-process stage from the collection and destroys it.
- *
- * @param {PostProcessStage|PostProcessStageComposite} stage The post-process stage to remove from the collection.
- * @return {Boolean} Whether the post-process stage was removed.
- */
- PostProcessStageCollection.prototype.remove = function(stage) {
- if (!this.contains(stage)) {
- return false;
- }
- var stageNames = this._stageNames;
- var stack = stackScratch;
- stack.push(stage);
- while (stack.length > 0) {
- var currentStage = stack.pop();
- delete stageNames[currentStage.name];
- var length = currentStage.length;
- if (defined(length)) {
- for (var i = 0; i < length; ++i) {
- stack.push(currentStage.get(i));
- }
- }
- }
- this._stages[stage._index] = undefined;
- this._stagesRemoved = true;
- this._textureCacheDirty = true;
- stage._index = undefined;
- stage._textureCache = undefined;
- stage.destroy();
- return true;
- };
- /**
- * Returns whether the collection contains a post-process stage.
- *
- * @param {PostProcessStage|PostProcessStageComposite} stage The post-process stage.
- * @return {Boolean} Whether the collection contains the post-process stage.
- */
- PostProcessStageCollection.prototype.contains = function(stage) {
- return defined(stage) && defined(stage._index) && stage._textureCache === this._textureCache;
- };
- /**
- * Gets the post-process stage at <code>index</code>.
- *
- * @param {Number} index The index of the post-process stage.
- * @return {PostProcessStage|PostProcessStageComposite} The post-process stage at index.
- */
- PostProcessStageCollection.prototype.get = function(index) {
- removeStages(this);
- var stages = this._stages;
- //>>includeStart('debug', pragmas.debug);
- var length = stages.length;
- Check.typeOf.number.greaterThanOrEquals('stages length', length, 0);
- Check.typeOf.number.greaterThanOrEquals('index', index, 0);
- Check.typeOf.number.lessThan('index', index, length);
- //>>includeEnd('debug');
- return stages[index];
- };
- /**
- * Removes all post-process stages from the collection and destroys them.
- */
- PostProcessStageCollection.prototype.removeAll = function() {
- var stages = this._stages;
- var length = stages.length;
- for (var i = 0; i < length; ++i) {
- this.remove(stages[i]);
- }
- stages.length = 0;
- };
- /**
- * Gets a post-process stage in the collection by its name.
- *
- * @param {String} name The name of the post-process stage.
- * @return {PostProcessStage|PostProcessStageComposite} The post-process stage.
- *
- * @private
- */
- PostProcessStageCollection.prototype.getStageByName = function(name) {
- return this._stageNames[name];
- };
- /**
- * Called before the post-process stages in the collection are executed. Calls update for each stage and creates WebGL resources.
- *
- * @param {Context} context The context.
- * @param {Boolean} useLogDepth Whether the scene uses a logarithmic depth buffer.
- *
- * @private
- */
- PostProcessStageCollection.prototype.update = function(context, useLogDepth, useHdr) {
- removeStages(this);
- var previousActiveStages = this._activeStages;
- var activeStages = this._activeStages = this._previousActiveStages;
- this._previousActiveStages = previousActiveStages;
- var stages = this._stages;
- var length = activeStages.length = stages.length;
- var i;
- var stage;
- var count = 0;
- for (i = 0; i < length; ++i) {
- stage = stages[i];
- if (stage.ready && stage.enabled && stage._isSupported(context)) {
- activeStages[count++] = stage;
- }
- }
- activeStages.length = count;
- var activeStagesChanged = count !== previousActiveStages.length;
- if (!activeStagesChanged) {
- for (i = 0; i < count; ++i) {
- if (activeStages[i] !== previousActiveStages[i]) {
- activeStagesChanged = true;
- break;
- }
- }
- }
- var ao = this._ao;
- var bloom = this._bloom;
- var autoexposure = this._autoExposure;
- var tonemapping = this._tonemapping;
- var fxaa = this._fxaa;
- tonemapping.enabled = useHdr;
- var aoEnabled = ao.enabled && ao._isSupported(context);
- var bloomEnabled = bloom.enabled && bloom._isSupported(context);
- var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context);
- var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context);
- if (activeStagesChanged || this._textureCacheDirty || count !== this._lastLength || aoEnabled !== this._aoEnabled ||
- bloomEnabled !== this._bloomEnabled || tonemappingEnabled !== this._tonemappingEnabled || fxaaEnabled !== this._fxaaEnabled) {
- // The number of stages to execute has changed.
- // Update dependencies and recreate framebuffers.
- this._textureCache.updateDependencies();
- this._lastLength = count;
- this._aoEnabled = aoEnabled;
- this._bloomEnabled = bloomEnabled;
- this._tonemappingEnabled = tonemappingEnabled;
- this._fxaaEnabled = fxaaEnabled;
- this._textureCacheDirty = false;
- }
- if (defined(this._randomTexture) && !aoEnabled) {
- this._randomTexture.destroy();
- this._randomTexture = undefined;
- }
- if (!defined(this._randomTexture) && aoEnabled) {
- length = 256 * 256 * 3;
- var random = new Uint8Array(length);
- for (i = 0; i < length; i += 3) {
- random[i] = Math.floor(Math.random() * 255.0);
- }
- this._randomTexture = new Texture({
- context : context,
- pixelFormat : PixelFormat.RGB,
- pixelDatatype : PixelDatatype.UNSIGNED_BYTE,
- source : {
- arrayBufferView : random,
- width : 256,
- height : 256
- },
- sampler : new Sampler({
- wrapS : TextureWrap.REPEAT,
- wrapT : TextureWrap.REPEAT,
- minificationFilter : TextureMinificationFilter.NEAREST,
- magnificationFilter : TextureMagnificationFilter.NEAREST
- })
- });
- }
- this._textureCache.update(context);
- fxaa.update(context, useLogDepth);
- ao.update(context, useLogDepth);
- bloom.update(context, useLogDepth);
- tonemapping.update(context, useLogDepth);
- if (this._autoExposureEnabled) {
- autoexposure.update(context, useLogDepth);
- }
- length = stages.length;
- for (i = 0; i < length; ++i) {
- stages[i].update(context, useLogDepth);
- }
- };
- /**
- * Clears all of the framebuffers used by the stages.
- *
- * @param {Context} context The context.
- *
- * @private
- */
- PostProcessStageCollection.prototype.clear = function(context) {
- this._textureCache.clear(context);
- if (this._autoExposureEnabled) {
- this._autoExposure.clear(context);
- }
- };
- function getOutputTexture(stage) {
- while (defined(stage.length)) {
- stage = stage.get(stage.length - 1);
- }
- return stage.outputTexture;
- }
- /**
- * Gets the output texture of a stage with the given name.
- *
- * @param {String} stageName The name of the stage.
- * @return {Texture|undefined} The texture rendered to by the stage with the given name.
- *
- * @private
- */
- PostProcessStageCollection.prototype.getOutputTexture = function(stageName) {
- var stage = this.getStageByName(stageName);
- if (!defined(stage)) {
- return undefined;
- }
- return getOutputTexture(stage);
- };
- function execute(stage, context, colorTexture, depthTexture, idTexture) {
- if (defined(stage.execute)) {
- stage.execute(context, colorTexture, depthTexture, idTexture);
- return;
- }
- var length = stage.length;
- var i;
- if (stage.inputPreviousStageTexture) {
- execute(stage.get(0), context, colorTexture, depthTexture, idTexture);
- for (i = 1; i < length; ++i) {
- execute(stage.get(i), context, getOutputTexture(stage.get(i - 1)), depthTexture, idTexture);
- }
- } else {
- for (i = 0; i < length; ++i) {
- execute(stage.get(i), context, colorTexture, depthTexture, idTexture);
- }
- }
- }
- /**
- * Executes all ready and enabled stages in the collection.
- *
- * @param {Context} context The context.
- * @param {Texture} colorTexture The color texture rendered to by the scene.
- * @param {Texture} depthTexture The depth texture written to by the scene.
- * @param {Texture} idTexture The id texture written to by the scene.
- *
- * @private
- */
- PostProcessStageCollection.prototype.execute = function(context, colorTexture, depthTexture, idTexture) {
- var activeStages = this._activeStages;
- var length = activeStages.length;
- var fxaa = this._fxaa;
- var ao = this._ao;
- var bloom = this._bloom;
- var autoexposure = this._autoExposure;
- var tonemapping = this._tonemapping;
- var aoEnabled = ao.enabled && ao._isSupported(context);
- var bloomEnabled = bloom.enabled && bloom._isSupported(context);
- var autoExposureEnabled = this._autoExposureEnabled;
- var tonemappingEnabled = tonemapping.enabled && tonemapping._isSupported(context);
- var fxaaEnabled = fxaa.enabled && fxaa._isSupported(context);
- if (!fxaaEnabled && !aoEnabled && !bloomEnabled && !tonemappingEnabled && length === 0) {
- return;
- }
- var initialTexture = colorTexture;
- if (aoEnabled && ao.ready) {
- execute(ao, context, initialTexture, depthTexture, idTexture);
- initialTexture = getOutputTexture(ao);
- }
- if (bloomEnabled && bloom.ready) {
- execute(bloom, context, initialTexture, depthTexture, idTexture);
- initialTexture = getOutputTexture(bloom);
- }
- if (autoExposureEnabled && autoexposure.ready) {
- execute(autoexposure, context, initialTexture, depthTexture, idTexture);
- }
- if (tonemappingEnabled && tonemapping.ready) {
- execute(tonemapping, context, initialTexture, depthTexture, idTexture);
- initialTexture = getOutputTexture(tonemapping);
- }
- var lastTexture = initialTexture;
- if (length > 0) {
- execute(activeStages[0], context, initialTexture, depthTexture, idTexture);
- for (var i = 1; i < length; ++i) {
- execute(activeStages[i], context, getOutputTexture(activeStages[i - 1]), depthTexture, idTexture);
- }
- lastTexture = getOutputTexture(activeStages[length - 1]);
- }
- if (fxaaEnabled && fxaa.ready) {
- execute(fxaa, context, lastTexture, depthTexture, idTexture);
- }
- };
- /**
- * Copies the output of all executed stages to the color texture of a framebuffer.
- *
- * @param {Context} context The context.
- * @param {Framebuffer} framebuffer The framebuffer to copy to.
- *
- * @private
- */
- PostProcessStageCollection.prototype.copy = function(context, framebuffer) {
- if (!defined(this._copyColorCommand)) {
- var that = this;
- this._copyColorCommand = context.createViewportQuadCommand(PassThrough, {
- uniformMap : {
- colorTexture : function() {
- return that.outputTexture;
- }
- },
- owner : this
- });
- }
- this._copyColorCommand.framebuffer = framebuffer;
- this._copyColorCommand.execute(context);
- };
- /**
- * Returns true if this object was destroyed; otherwise, false.
- * <p>
- * If this object was destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
- * </p>
- *
- * @returns {Boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
- *
- * @see PostProcessStageCollection#destroy
- */
- PostProcessStageCollection.prototype.isDestroyed = function() {
- return false;
- };
- /**
- * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
- * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
- * <p>
- * Once an object is destroyed, it should not be used; calling any function other than
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
- * assign the return value (<code>undefined</code>) to the object as done in the example.
- * </p>
- *
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
- *
- * @see PostProcessStageCollection#isDestroyed
- */
- PostProcessStageCollection.prototype.destroy = function() {
- this._fxaa.destroy();
- this._ao.destroy();
- this._bloom.destroy();
- this._autoExposure.destroy();
- this._tonemapping.destroy();
- this.removeAll();
- this._textureCache = this._textureCache && this._textureCache.destroy();
- return destroyObject(this);
- };
- export default PostProcessStageCollection;
|