123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- import { InternalTextureSource } from "../Materials/Textures/internalTexture.js";
- /**
- * Wrapper around a render target (either single or multi textures)
- */
- export class RenderTargetWrapper {
- /**
- * Gets the depth/stencil texture (if created by a createDepthStencilTexture() call)
- */
- get depthStencilTexture() {
- return this._depthStencilTexture;
- }
- /**
- * Indicates if the depth/stencil texture has a stencil aspect
- */
- get depthStencilTextureWithStencil() {
- return this._depthStencilTextureWithStencil;
- }
- /**
- * Defines if the render target wrapper is for a cube texture or if false a 2d texture
- */
- get isCube() {
- return this._isCube;
- }
- /**
- * Defines if the render target wrapper is for a single or multi target render wrapper
- */
- get isMulti() {
- return this._isMulti;
- }
- /**
- * Defines if the render target wrapper is for a single or an array of textures
- */
- get is2DArray() {
- return this.layers > 0;
- }
- /**
- * Defines if the render target wrapper is for a 3D texture
- */
- get is3D() {
- return this.depth > 0;
- }
- /**
- * Gets the size of the render target wrapper (used for cubes, as width=height in this case)
- */
- get size() {
- return this.width;
- }
- /**
- * Gets the width of the render target wrapper
- */
- get width() {
- return this._size.width || this._size;
- }
- /**
- * Gets the height of the render target wrapper
- */
- get height() {
- return this._size.height || this._size;
- }
- /**
- * Gets the number of layers of the render target wrapper (only used if is2DArray is true and wrapper is not a multi render target)
- */
- get layers() {
- return this._size.layers || 0;
- }
- /**
- * Gets the depth of the render target wrapper (only used if is3D is true and wrapper is not a multi render target)
- */
- get depth() {
- return this._size.depth || 0;
- }
- /**
- * Gets the render texture. If this is a multi render target, gets the first texture
- */
- get texture() {
- return this._textures?.[0] ?? null;
- }
- /**
- * Gets the list of render textures. If we are not in a multi render target, the list will be null (use the texture getter instead)
- */
- get textures() {
- return this._textures;
- }
- /**
- * Gets the face indices that correspond to the list of render textures. If we are not in a multi render target, the list will be null
- */
- get faceIndices() {
- return this._faceIndices;
- }
- /**
- * Gets the layer indices that correspond to the list of render textures. If we are not in a multi render target, the list will be null
- */
- get layerIndices() {
- return this._layerIndices;
- }
- /**
- * Gets the sample count of the render target
- */
- get samples() {
- return this._samples;
- }
- /**
- * Sets the sample count of the render target
- * @param value sample count
- * @param initializeBuffers If set to true, the engine will make an initializing call to drawBuffers (only used when isMulti=true).
- * @param force true to force calling the update sample count engine function even if the current sample count is equal to value
- * @returns the sample count that has been set
- */
- setSamples(value, initializeBuffers = true, force = false) {
- if (this.samples === value && !force) {
- return value;
- }
- const result = this._isMulti
- ? this._engine.updateMultipleRenderTargetTextureSampleCount(this, value, initializeBuffers)
- : this._engine.updateRenderTargetTextureSampleCount(this, value);
- this._samples = value;
- return result;
- }
- /**
- * Initializes the render target wrapper
- * @param isMulti true if the wrapper is a multi render target
- * @param isCube true if the wrapper should render to a cube texture
- * @param size size of the render target (width/height/layers)
- * @param engine engine used to create the render target
- * @param label defines the label to use for the wrapper (for debugging purpose only)
- */
- constructor(isMulti, isCube, size, engine, label) {
- this._textures = null;
- this._faceIndices = null;
- this._layerIndices = null;
- /** @internal */
- this._samples = 1;
- /** @internal */
- this._attachments = null;
- /** @internal */
- this._generateStencilBuffer = false;
- /** @internal */
- this._generateDepthBuffer = false;
- /** @internal */
- this._depthStencilTextureWithStencil = false;
- this._isMulti = isMulti;
- this._isCube = isCube;
- this._size = size;
- this._engine = engine;
- this._depthStencilTexture = null;
- this.label = label;
- }
- /**
- * Sets the render target texture(s)
- * @param textures texture(s) to set
- */
- setTextures(textures) {
- if (Array.isArray(textures)) {
- this._textures = textures;
- }
- else if (textures) {
- this._textures = [textures];
- }
- else {
- this._textures = null;
- }
- }
- /**
- * Set a texture in the textures array
- * @param texture The texture to set
- * @param index The index in the textures array to set
- * @param disposePrevious If this function should dispose the previous texture
- */
- setTexture(texture, index = 0, disposePrevious = true) {
- if (!this._textures) {
- this._textures = [];
- }
- if (this._textures[index] === texture) {
- return;
- }
- if (this._textures[index] && disposePrevious) {
- this._textures[index].dispose();
- }
- this._textures[index] = texture;
- }
- /**
- * Sets the layer and face indices of every render target texture bound to each color attachment
- * @param layers The layers of each texture to be set
- * @param faces The faces of each texture to be set
- */
- setLayerAndFaceIndices(layers, faces) {
- this._layerIndices = layers;
- this._faceIndices = faces;
- }
- /**
- * Sets the layer and face indices of a texture in the textures array that should be bound to each color attachment
- * @param index The index of the texture in the textures array to modify
- * @param layer The layer of the texture to be set
- * @param face The face of the texture to be set
- */
- setLayerAndFaceIndex(index = 0, layer, face) {
- if (!this._layerIndices) {
- this._layerIndices = [];
- }
- if (!this._faceIndices) {
- this._faceIndices = [];
- }
- if (layer !== undefined && layer >= 0) {
- this._layerIndices[index] = layer;
- }
- if (face !== undefined && face >= 0) {
- this._faceIndices[index] = face;
- }
- }
- /**
- * Creates the depth/stencil texture
- * @param comparisonFunction Comparison function to use for the texture
- * @param bilinearFiltering true if bilinear filtering should be used when sampling the texture
- * @param generateStencil true if the stencil aspect should also be created
- * @param samples sample count to use when creating the texture
- * @param format format of the depth texture
- * @param label defines the label to use for the texture (for debugging purpose only)
- * @returns the depth/stencil created texture
- */
- createDepthStencilTexture(comparisonFunction = 0, bilinearFiltering = true, generateStencil = false, samples = 1, format = 14, label) {
- this._depthStencilTexture?.dispose();
- this._depthStencilTextureWithStencil = generateStencil;
- this._depthStencilTextureLabel = label;
- this._depthStencilTexture = this._engine.createDepthStencilTexture(this._size, {
- bilinearFiltering,
- comparisonFunction,
- generateStencil,
- isCube: this._isCube,
- samples,
- depthTextureFormat: format,
- label,
- }, this);
- return this._depthStencilTexture;
- }
- /**
- * @deprecated Use shareDepth instead
- * @param renderTarget Destination renderTarget
- */
- _shareDepth(renderTarget) {
- this.shareDepth(renderTarget);
- }
- /**
- * Shares the depth buffer of this render target with another render target.
- * @param renderTarget Destination renderTarget
- */
- shareDepth(renderTarget) {
- if (this._depthStencilTexture) {
- if (renderTarget._depthStencilTexture) {
- renderTarget._depthStencilTexture.dispose();
- }
- renderTarget._depthStencilTexture = this._depthStencilTexture;
- renderTarget._depthStencilTextureWithStencil = this._depthStencilTextureWithStencil;
- this._depthStencilTexture.incrementReferences();
- }
- }
- /**
- * @internal
- */
- _swapAndDie(target) {
- if (this.texture) {
- this.texture._swapAndDie(target);
- }
- this._textures = null;
- this.dispose(true);
- }
- _cloneRenderTargetWrapper() {
- let rtw = null;
- if (this._isMulti) {
- const textureArray = this.textures;
- if (textureArray && textureArray.length > 0) {
- let generateDepthTexture = false;
- let textureCount = textureArray.length;
- let depthTextureFormat = -1;
- const lastTextureSource = textureArray[textureArray.length - 1]._source;
- if (lastTextureSource === InternalTextureSource.Depth || lastTextureSource === InternalTextureSource.DepthStencil) {
- generateDepthTexture = true;
- depthTextureFormat = textureArray[textureArray.length - 1].format;
- textureCount--;
- }
- const samplingModes = [];
- const types = [];
- const formats = [];
- const targetTypes = [];
- const faceIndex = [];
- const layerIndex = [];
- const layerCounts = [];
- const internalTexture2Index = {};
- for (let i = 0; i < textureCount; ++i) {
- const texture = textureArray[i];
- samplingModes.push(texture.samplingMode);
- types.push(texture.type);
- formats.push(texture.format);
- const index = internalTexture2Index[texture.uniqueId];
- if (index !== undefined) {
- targetTypes.push(-1);
- layerCounts.push(0);
- }
- else {
- internalTexture2Index[texture.uniqueId] = i;
- if (texture.is2DArray) {
- targetTypes.push(35866);
- layerCounts.push(texture.depth);
- }
- else if (texture.isCube) {
- targetTypes.push(34067);
- layerCounts.push(0);
- } /*else if (texture.isCubeArray) {
- targetTypes.push(3735928559);
- layerCounts.push(texture.depth);
- }*/
- else if (texture.is3D) {
- targetTypes.push(32879);
- layerCounts.push(texture.depth);
- }
- else {
- targetTypes.push(3553);
- layerCounts.push(0);
- }
- }
- if (this._faceIndices) {
- faceIndex.push(this._faceIndices[i] ?? 0);
- }
- if (this._layerIndices) {
- layerIndex.push(this._layerIndices[i] ?? 0);
- }
- }
- const optionsMRT = {
- samplingModes,
- generateMipMaps: textureArray[0].generateMipMaps,
- generateDepthBuffer: this._generateDepthBuffer,
- generateStencilBuffer: this._generateStencilBuffer,
- generateDepthTexture,
- depthTextureFormat,
- types,
- formats,
- textureCount,
- targetTypes,
- faceIndex,
- layerIndex,
- layerCounts,
- label: this.label,
- };
- const size = {
- width: this.width,
- height: this.height,
- depth: this.depth,
- };
- rtw = this._engine.createMultipleRenderTarget(size, optionsMRT);
- for (let i = 0; i < textureCount; ++i) {
- if (targetTypes[i] !== -1) {
- continue;
- }
- const index = internalTexture2Index[textureArray[i].uniqueId];
- rtw.setTexture(rtw.textures[index], i);
- }
- }
- }
- else {
- const options = {};
- options.generateDepthBuffer = this._generateDepthBuffer;
- options.generateMipMaps = this.texture?.generateMipMaps ?? false;
- options.generateStencilBuffer = this._generateStencilBuffer;
- options.samplingMode = this.texture?.samplingMode;
- options.type = this.texture?.type;
- options.format = this.texture?.format;
- options.noColorAttachment = !this._textures;
- options.label = this.label;
- if (this.isCube) {
- rtw = this._engine.createRenderTargetCubeTexture(this.width, options);
- }
- else {
- const size = {
- width: this.width,
- height: this.height,
- layers: this.is2DArray || this.is3D ? this.texture?.depth : undefined,
- };
- rtw = this._engine.createRenderTargetTexture(size, options);
- }
- if (rtw.texture) {
- rtw.texture.isReady = true;
- }
- }
- return rtw;
- }
- _swapRenderTargetWrapper(target) {
- if (this._textures && target._textures) {
- for (let i = 0; i < this._textures.length; ++i) {
- this._textures[i]._swapAndDie(target._textures[i], false);
- target._textures[i].isReady = true;
- }
- }
- if (this._depthStencilTexture && target._depthStencilTexture) {
- this._depthStencilTexture._swapAndDie(target._depthStencilTexture);
- target._depthStencilTexture.isReady = true;
- }
- this._textures = null;
- this._depthStencilTexture = null;
- }
- /** @internal */
- _rebuild() {
- const rtw = this._cloneRenderTargetWrapper();
- if (!rtw) {
- return;
- }
- if (this._depthStencilTexture) {
- const samplingMode = this._depthStencilTexture.samplingMode;
- const format = this._depthStencilTexture.format;
- const bilinear = samplingMode === 2 ||
- samplingMode === 3 ||
- samplingMode === 11;
- rtw.createDepthStencilTexture(this._depthStencilTexture._comparisonFunction, bilinear, this._depthStencilTextureWithStencil, this._depthStencilTexture.samples, format, this._depthStencilTextureLabel);
- }
- if (this.samples > 1) {
- rtw.setSamples(this.samples);
- }
- rtw._swapRenderTargetWrapper(this);
- rtw.dispose();
- }
- /**
- * Releases the internal render textures
- */
- releaseTextures() {
- if (this._textures) {
- for (let i = 0; i < this._textures?.length ?? 0; ++i) {
- this._textures[i].dispose();
- }
- }
- this._textures = null;
- }
- /**
- * Disposes the whole render target wrapper
- * @param disposeOnlyFramebuffers true if only the frame buffers should be released (used for the WebGL engine). If false, all the textures will also be released
- */
- dispose(disposeOnlyFramebuffers = false) {
- if (!disposeOnlyFramebuffers) {
- this._depthStencilTexture?.dispose();
- this._depthStencilTexture = null;
- this.releaseTextures();
- }
- this._engine._releaseRenderTargetWrapper(this);
- }
- }
- //# sourceMappingURL=renderTargetWrapper.js.map
|