123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- import { Texture } from "../../Materials/Textures/texture.js";
- import { RenderTargetTexture } from "../../Materials/Textures/renderTargetTexture.js";
- import "../../Engines/Extensions/engine.multiRender.js";
- /**
- * A multi render target, like a render target provides the ability to render to a texture.
- * Unlike the render target, it can render to several draw buffers (render textures) in one draw.
- * This is specially interesting in deferred rendering or for any effects requiring more than
- * just one color from a single pass.
- */
- export class MultiRenderTarget extends RenderTargetTexture {
- /**
- * Get if draw buffers (render textures) are currently supported by the used hardware and browser.
- */
- get isSupported() {
- return this._engine?.getCaps().drawBuffersExtension ?? false;
- }
- /**
- * Get the list of textures generated by the multi render target.
- */
- get textures() {
- return this._textures;
- }
- /**
- * Gets the number of textures in this MRT. This number can be different from `_textures.length` in case a depth texture is generated.
- */
- get count() {
- return this._count;
- }
- /**
- * Get the depth texture generated by the multi render target if options.generateDepthTexture has been set
- */
- get depthTexture() {
- return this._textures[this._textures.length - 1];
- }
- /**
- * Set the wrapping mode on U of all the textures we are rendering to.
- * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
- */
- set wrapU(wrap) {
- if (this._textures) {
- for (let i = 0; i < this._textures.length; i++) {
- this._textures[i].wrapU = wrap;
- }
- }
- }
- /**
- * Set the wrapping mode on V of all the textures we are rendering to.
- * Can be any of the Texture. (CLAMP_ADDRESSMODE, MIRROR_ADDRESSMODE or WRAP_ADDRESSMODE)
- */
- set wrapV(wrap) {
- if (this._textures) {
- for (let i = 0; i < this._textures.length; i++) {
- this._textures[i].wrapV = wrap;
- }
- }
- }
- /**
- * Instantiate a new multi render target texture.
- * A multi render target, like a render target provides the ability to render to a texture.
- * Unlike the render target, it can render to several draw buffers (render textures) in one draw.
- * This is specially interesting in deferred rendering or for any effects requiring more than
- * just one color from a single pass.
- * @param name Define the name of the texture
- * @param size Define the size of the buffers to render to
- * @param count Define the number of target we are rendering into
- * @param scene Define the scene the texture belongs to
- * @param options Define the options used to create the multi render target
- * @param textureNames Define the names to set to the textures (if count \> 0 - optional)
- */
- constructor(name, size, count, scene, options, textureNames) {
- const generateMipMaps = options && options.generateMipMaps ? options.generateMipMaps : false;
- const generateDepthTexture = options && options.generateDepthTexture ? options.generateDepthTexture : false;
- const depthTextureFormat = options && options.depthTextureFormat ? options.depthTextureFormat : 15;
- const doNotChangeAspectRatio = !options || options.doNotChangeAspectRatio === undefined ? true : options.doNotChangeAspectRatio;
- const drawOnlyOnFirstAttachmentByDefault = options && options.drawOnlyOnFirstAttachmentByDefault ? options.drawOnlyOnFirstAttachmentByDefault : false;
- super(name, size, scene, generateMipMaps, doNotChangeAspectRatio, undefined, undefined, undefined, undefined, undefined, undefined, undefined, true);
- if (!this.isSupported) {
- this.dispose();
- return;
- }
- this._textureNames = textureNames;
- const types = [];
- const samplingModes = [];
- const useSRGBBuffers = [];
- const formats = [];
- const targetTypes = [];
- const faceIndex = [];
- const layerIndex = [];
- const layerCounts = [];
- this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options);
- const generateDepthBuffer = !options || options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer;
- const generateStencilBuffer = !options || options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer;
- this._multiRenderTargetOptions = {
- samplingModes: samplingModes,
- generateMipMaps: generateMipMaps,
- generateDepthBuffer: generateDepthBuffer,
- generateStencilBuffer: generateStencilBuffer,
- generateDepthTexture: generateDepthTexture,
- depthTextureFormat: depthTextureFormat,
- types: types,
- textureCount: count,
- useSRGBBuffers: useSRGBBuffers,
- formats: formats,
- targetTypes: targetTypes,
- faceIndex: faceIndex,
- layerIndex: layerIndex,
- layerCounts: layerCounts,
- labels: textureNames,
- label: name,
- };
- this._count = count;
- this._drawOnlyOnFirstAttachmentByDefault = drawOnlyOnFirstAttachmentByDefault;
- if (count > 0) {
- this._createInternalTextures();
- this._createTextures(textureNames);
- }
- }
- _initTypes(count, types, samplingModes, useSRGBBuffers, formats, targets, faceIndex, layerIndex, layerCounts, options) {
- for (let i = 0; i < count; i++) {
- if (options && options.types && options.types[i] !== undefined) {
- types.push(options.types[i]);
- }
- else {
- types.push(options && options.defaultType ? options.defaultType : 0);
- }
- if (options && options.samplingModes && options.samplingModes[i] !== undefined) {
- samplingModes.push(options.samplingModes[i]);
- }
- else {
- samplingModes.push(Texture.BILINEAR_SAMPLINGMODE);
- }
- if (options && options.useSRGBBuffers && options.useSRGBBuffers[i] !== undefined) {
- useSRGBBuffers.push(options.useSRGBBuffers[i]);
- }
- else {
- useSRGBBuffers.push(false);
- }
- if (options && options.formats && options.formats[i] !== undefined) {
- formats.push(options.formats[i]);
- }
- else {
- formats.push(5);
- }
- if (options && options.targetTypes && options.targetTypes[i] !== undefined) {
- targets.push(options.targetTypes[i]);
- }
- else {
- targets.push(3553);
- }
- if (options && options.faceIndex && options.faceIndex[i] !== undefined) {
- faceIndex.push(options.faceIndex[i]);
- }
- else {
- faceIndex.push(0);
- }
- if (options && options.layerIndex && options.layerIndex[i] !== undefined) {
- layerIndex.push(options.layerIndex[i]);
- }
- else {
- layerIndex.push(0);
- }
- if (options && options.layerCounts && options.layerCounts[i] !== undefined) {
- layerCounts.push(options.layerCounts[i]);
- }
- else {
- layerCounts.push(1);
- }
- }
- }
- _createInternaTextureIndexMapping() {
- const mapMainInternalTexture2Index = {};
- const mapInternalTexture2MainIndex = [];
- if (!this._renderTarget) {
- return mapInternalTexture2MainIndex;
- }
- const internalTextures = this._renderTarget.textures;
- for (let i = 0; i < internalTextures.length; i++) {
- const texture = internalTextures[i];
- if (!texture) {
- continue;
- }
- const mainIndex = mapMainInternalTexture2Index[texture.uniqueId];
- if (mainIndex !== undefined) {
- mapInternalTexture2MainIndex[i] = mainIndex;
- }
- else {
- mapMainInternalTexture2Index[texture.uniqueId] = i;
- }
- }
- return mapInternalTexture2MainIndex;
- }
- /**
- * @internal
- */
- _rebuild(fromContextLost = false, forceFullRebuild = false, textureNames) {
- if (this._count < 1 || fromContextLost) {
- return;
- }
- const mapInternalTexture2MainIndex = this._createInternaTextureIndexMapping();
- this.releaseInternalTextures();
- this._createInternalTextures();
- if (forceFullRebuild) {
- this._releaseTextures();
- this._createTextures(textureNames);
- }
- const internalTextures = this._renderTarget.textures;
- for (let i = 0; i < internalTextures.length; i++) {
- const texture = this._textures[i];
- if (mapInternalTexture2MainIndex[i] !== undefined) {
- this._renderTarget.setTexture(internalTextures[mapInternalTexture2MainIndex[i]], i);
- }
- texture._texture = internalTextures[i];
- if (texture._texture) {
- texture._noMipmap = !texture._texture.useMipMaps;
- texture._useSRGBBuffer = texture._texture._useSRGBBuffer;
- }
- }
- if (this.samples !== 1) {
- this._renderTarget.setSamples(this.samples, !this._drawOnlyOnFirstAttachmentByDefault, true);
- }
- }
- _createInternalTextures() {
- this._renderTarget = this._getEngine().createMultipleRenderTarget(this._size, this._multiRenderTargetOptions, !this._drawOnlyOnFirstAttachmentByDefault);
- this._texture = this._renderTarget.texture;
- }
- _releaseTextures() {
- if (this._textures) {
- for (let i = 0; i < this._textures.length; i++) {
- this._textures[i]._texture = null; // internal textures are released by a call to releaseInternalTextures()
- this._textures[i].dispose();
- }
- }
- }
- _createTextures(textureNames) {
- const internalTextures = this._renderTarget.textures;
- this._textures = [];
- for (let i = 0; i < internalTextures.length; i++) {
- const texture = new Texture(null, this.getScene());
- if (textureNames?.[i]) {
- texture.name = textureNames[i];
- }
- texture._texture = internalTextures[i];
- if (texture._texture) {
- texture._noMipmap = !texture._texture.useMipMaps;
- texture._useSRGBBuffer = texture._texture._useSRGBBuffer;
- }
- this._textures.push(texture);
- }
- }
- /**
- * Replaces an internal texture within the MRT. Useful to share textures between MultiRenderTarget.
- * @param texture The new texture to set in the MRT
- * @param index The index of the texture to replace
- * @param disposePrevious Set to true if the previous internal texture should be disposed
- */
- setInternalTexture(texture, index, disposePrevious = true) {
- if (!this.renderTarget) {
- return;
- }
- if (index === 0) {
- this._texture = texture;
- }
- this.renderTarget.setTexture(texture, index, disposePrevious);
- if (!this.textures[index]) {
- this.textures[index] = new Texture(null, this.getScene());
- this.textures[index].name = this._textureNames?.[index] ?? this.textures[index].name;
- }
- this.textures[index]._texture = texture;
- this.textures[index]._noMipmap = !texture.useMipMaps;
- this.textures[index]._useSRGBBuffer = texture._useSRGBBuffer;
- this._count = this.renderTarget.textures ? this.renderTarget.textures.length : 0;
- if (this._multiRenderTargetOptions.types) {
- this._multiRenderTargetOptions.types[index] = texture.type;
- }
- if (this._multiRenderTargetOptions.samplingModes) {
- this._multiRenderTargetOptions.samplingModes[index] = texture.samplingMode;
- }
- if (this._multiRenderTargetOptions.useSRGBBuffers) {
- this._multiRenderTargetOptions.useSRGBBuffers[index] = texture._useSRGBBuffer;
- }
- if (this._multiRenderTargetOptions.targetTypes && this._multiRenderTargetOptions.targetTypes[index] !== -1) {
- let target = 0;
- if (texture.is2DArray) {
- target = 35866;
- }
- else if (texture.isCube) {
- target = 34067;
- } /*else if (texture.isCubeArray) {
- target = 3735928559;
- }*/
- else if (texture.is3D) {
- target = 32879;
- }
- else {
- target = 3553;
- }
- this._multiRenderTargetOptions.targetTypes[index] = target;
- }
- }
- /**
- * Changes an attached texture's face index or layer.
- * @param index The index of the texture to modify the attachment of
- * @param layerIndex The layer index of the texture to be attached to the framebuffer
- * @param faceIndex The face index of the texture to be attached to the framebuffer
- */
- setLayerAndFaceIndex(index, layerIndex = -1, faceIndex = -1) {
- if (!this.textures[index] || !this.renderTarget) {
- return;
- }
- if (this._multiRenderTargetOptions.layerIndex) {
- this._multiRenderTargetOptions.layerIndex[index] = layerIndex;
- }
- if (this._multiRenderTargetOptions.faceIndex) {
- this._multiRenderTargetOptions.faceIndex[index] = faceIndex;
- }
- this.renderTarget.setLayerAndFaceIndex(index, layerIndex, faceIndex);
- }
- /**
- * Changes every attached texture's face index or layer.
- * @param layerIndices The layer indices of the texture to be attached to the framebuffer
- * @param faceIndices The face indices of the texture to be attached to the framebuffer
- */
- setLayerAndFaceIndices(layerIndices, faceIndices) {
- if (!this.renderTarget) {
- return;
- }
- this._multiRenderTargetOptions.layerIndex = layerIndices;
- this._multiRenderTargetOptions.faceIndex = faceIndices;
- this.renderTarget.setLayerAndFaceIndices(layerIndices, faceIndices);
- }
- /**
- * Define the number of samples used if MSAA is enabled.
- */
- get samples() {
- return this._samples;
- }
- set samples(value) {
- if (this._renderTarget) {
- this._samples = this._renderTarget.setSamples(value);
- }
- else {
- // In case samples are set with 0 textures created, we must save the desired samples value
- this._samples = value;
- }
- }
- /**
- * Resize all the textures in the multi render target.
- * Be careful as it will recreate all the data in the new texture.
- * @param size Define the new size
- */
- resize(size) {
- this._processSizeParameter(size, false);
- this._rebuild(false, undefined, this._textureNames);
- }
- /**
- * Changes the number of render targets in this MRT
- * Be careful as it will recreate all the data in the new texture.
- * @param count new texture count
- * @param options Specifies texture types and sampling modes for new textures
- * @param textureNames Specifies the names of the textures (optional)
- */
- updateCount(count, options, textureNames) {
- this._multiRenderTargetOptions.textureCount = count;
- this._count = count;
- const types = [];
- const samplingModes = [];
- const useSRGBBuffers = [];
- const formats = [];
- const targetTypes = [];
- const faceIndex = [];
- const layerIndex = [];
- const layerCounts = [];
- this._textureNames = textureNames;
- this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options);
- this._multiRenderTargetOptions.types = types;
- this._multiRenderTargetOptions.samplingModes = samplingModes;
- this._multiRenderTargetOptions.useSRGBBuffers = useSRGBBuffers;
- this._multiRenderTargetOptions.formats = formats;
- this._multiRenderTargetOptions.targetTypes = targetTypes;
- this._multiRenderTargetOptions.faceIndex = faceIndex;
- this._multiRenderTargetOptions.layerIndex = layerIndex;
- this._multiRenderTargetOptions.layerCounts = layerCounts;
- this._multiRenderTargetOptions.labels = textureNames;
- this._rebuild(false, true, textureNames);
- }
- _unbindFrameBuffer(engine, faceIndex) {
- if (this._renderTarget) {
- engine.unBindMultiColorAttachmentFramebuffer(this._renderTarget, this.isCube, () => {
- this.onAfterRenderObservable.notifyObservers(faceIndex);
- });
- }
- }
- /**
- * Dispose the render targets and their associated resources
- * @param doNotDisposeInternalTextures if set to true, internal textures won't be disposed (default: false).
- */
- dispose(doNotDisposeInternalTextures = false) {
- this._releaseTextures();
- if (!doNotDisposeInternalTextures) {
- this.releaseInternalTextures();
- }
- else {
- // Prevent internal texture dispose in super.dispose
- this._texture = null;
- }
- super.dispose();
- }
- /**
- * Release all the underlying texture used as draw buffers (render textures).
- */
- releaseInternalTextures() {
- const internalTextures = this._renderTarget?.textures;
- if (!internalTextures) {
- return;
- }
- for (let i = internalTextures.length - 1; i >= 0; i--) {
- this._textures[i]._texture = null;
- }
- this._renderTarget?.dispose();
- this._renderTarget = null;
- }
- }
- //# sourceMappingURL=multiRenderTarget.js.map
|