Buckets:
| import { | |
| GPUTextureFormat, GPUAddressMode, GPUFilterMode, GPUTextureDimension, GPUFeatureName, GPUTextureViewDimension | |
| } from './WebGPUConstants.js'; | |
| import WebGPUTexturePassUtils from './WebGPUTexturePassUtils.js'; | |
| import { | |
| ByteType, ShortType, | |
| NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, | |
| RepeatWrapping, MirroredRepeatWrapping, | |
| RGB_ETC2_Format, RGBA_ETC2_EAC_Format, | |
| RGBAFormat, RGBFormat, RedFormat, RGFormat, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, UnsignedByteType, FloatType, HalfFloatType, SRGBColorSpace, DepthFormat, DepthStencilFormat, | |
| RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, | |
| RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, UnsignedIntType, UnsignedShortType, UnsignedInt248Type, UnsignedInt5999Type, | |
| NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, IntType, RedIntegerFormat, RGIntegerFormat, RGBAIntegerFormat, | |
| CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping | |
| } from '../../../constants.js'; | |
| import { CubeTexture } from '../../../textures/CubeTexture.js'; | |
| import { DepthTexture } from '../../../textures/DepthTexture.js'; | |
| import { Texture } from '../../../textures/Texture.js'; | |
| const _compareToWebGPU = { | |
| [ NeverCompare ]: 'never', | |
| [ LessCompare ]: 'less', | |
| [ EqualCompare ]: 'equal', | |
| [ LessEqualCompare ]: 'less-equal', | |
| [ GreaterCompare ]: 'greater', | |
| [ GreaterEqualCompare ]: 'greater-equal', | |
| [ AlwaysCompare ]: 'always', | |
| [ NotEqualCompare ]: 'not-equal' | |
| }; | |
| const _flipMap = [ 0, 1, 3, 2, 4, 5 ]; | |
| /** | |
| * A WebGPU backend utility module for managing textures. | |
| * | |
| * @private | |
| */ | |
| class WebGPUTextureUtils { | |
| /** | |
| * Constructs a new utility object. | |
| * | |
| * @param {WebGPUBackend} backend - The WebGPU backend. | |
| */ | |
| constructor( backend ) { | |
| /** | |
| * A reference to the WebGPU backend. | |
| * | |
| * @type {WebGPUBackend} | |
| */ | |
| this.backend = backend; | |
| /** | |
| * A reference to the pass utils. | |
| * | |
| * @type {?WebGPUTexturePassUtils} | |
| * @default null | |
| */ | |
| this._passUtils = null; | |
| /** | |
| * A dictionary for managing default textures. The key | |
| * is the texture format, the value the texture object. | |
| * | |
| * @type {Object<string,Texture>} | |
| */ | |
| this.defaultTexture = {}; | |
| /** | |
| * A dictionary for managing default cube textures. The key | |
| * is the texture format, the value the texture object. | |
| * | |
| * @type {Object<string,CubeTexture>} | |
| */ | |
| this.defaultCubeTexture = {}; | |
| /** | |
| * A default video frame. | |
| * | |
| * @type {?VideoFrame} | |
| * @default null | |
| */ | |
| this.defaultVideoFrame = null; | |
| /** | |
| * Represents the color attachment of the default framebuffer. | |
| * | |
| * @type {?GPUTexture} | |
| * @default null | |
| */ | |
| this.colorBuffer = null; | |
| /** | |
| * Represents the depth attachment of the default framebuffer. | |
| * | |
| * @type {DepthTexture} | |
| */ | |
| this.depthTexture = new DepthTexture(); | |
| this.depthTexture.name = 'depthBuffer'; | |
| } | |
| /** | |
| * Creates a GPU sampler for the given texture. | |
| * | |
| * @param {Texture} texture - The texture to create the sampler for. | |
| */ | |
| createSampler( texture ) { | |
| const backend = this.backend; | |
| const device = backend.device; | |
| const textureGPU = backend.get( texture ); | |
| const samplerDescriptorGPU = { | |
| addressModeU: this._convertAddressMode( texture.wrapS ), | |
| addressModeV: this._convertAddressMode( texture.wrapT ), | |
| addressModeW: this._convertAddressMode( texture.wrapR ), | |
| magFilter: this._convertFilterMode( texture.magFilter ), | |
| minFilter: this._convertFilterMode( texture.minFilter ), | |
| mipmapFilter: this._convertFilterMode( texture.minFilter ), | |
| maxAnisotropy: 1 | |
| }; | |
| // anisotropy can only be used when all filter modes are set to linear. | |
| if ( samplerDescriptorGPU.magFilter === GPUFilterMode.Linear && samplerDescriptorGPU.minFilter === GPUFilterMode.Linear && samplerDescriptorGPU.mipmapFilter === GPUFilterMode.Linear ) { | |
| samplerDescriptorGPU.maxAnisotropy = texture.anisotropy; | |
| } | |
| if ( texture.isDepthTexture && texture.compareFunction !== null ) { | |
| samplerDescriptorGPU.compare = _compareToWebGPU[ texture.compareFunction ]; | |
| } | |
| textureGPU.sampler = device.createSampler( samplerDescriptorGPU ); | |
| } | |
| /** | |
| * Creates a default texture for the given texture that can be used | |
| * as a placeholder until the actual texture is ready for usage. | |
| * | |
| * @param {Texture} texture - The texture to create a default texture for. | |
| */ | |
| createDefaultTexture( texture ) { | |
| let textureGPU; | |
| const format = getFormat( texture ); | |
| if ( texture.isCubeTexture ) { | |
| textureGPU = this._getDefaultCubeTextureGPU( format ); | |
| } else if ( texture.isVideoTexture ) { | |
| this.backend.get( texture ).externalTexture = this._getDefaultVideoFrame(); | |
| } else { | |
| textureGPU = this._getDefaultTextureGPU( format ); | |
| } | |
| this.backend.get( texture ).texture = textureGPU; | |
| } | |
| /** | |
| * Defines a texture on the GPU for the given texture object. | |
| * | |
| * @param {Texture} texture - The texture. | |
| * @param {Object} [options={}] - Optional configuration parameter. | |
| */ | |
| createTexture( texture, options = {} ) { | |
| const backend = this.backend; | |
| const textureData = backend.get( texture ); | |
| if ( textureData.initialized ) { | |
| throw new Error( 'WebGPUTextureUtils: Texture already initialized.' ); | |
| } | |
| if ( options.needsMipmaps === undefined ) options.needsMipmaps = false; | |
| if ( options.levels === undefined ) options.levels = 1; | |
| if ( options.depth === undefined ) options.depth = 1; | |
| const { width, height, depth, levels } = options; | |
| if ( texture.isFramebufferTexture ) { | |
| if ( options.renderTarget ) { | |
| options.format = this.backend.utils.getCurrentColorFormat( options.renderTarget ); | |
| } else { | |
| options.format = this.backend.utils.getPreferredCanvasFormat(); | |
| } | |
| } | |
| const dimension = this._getDimension( texture ); | |
| const format = texture.internalFormat || options.format || getFormat( texture, backend.device ); | |
| textureData.format = format; | |
| const { samples, primarySamples, isMSAA } = backend.utils.getTextureSampleData( texture ); | |
| let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC; | |
| if ( texture.isStorageTexture === true ) { | |
| usage |= GPUTextureUsage.STORAGE_BINDING; | |
| } | |
| if ( texture.isCompressedTexture !== true && texture.isCompressedArrayTexture !== true ) { | |
| usage |= GPUTextureUsage.RENDER_ATTACHMENT; | |
| } | |
| const textureDescriptorGPU = { | |
| label: texture.name, | |
| size: { | |
| width: width, | |
| height: height, | |
| depthOrArrayLayers: depth, | |
| }, | |
| mipLevelCount: levels, | |
| sampleCount: primarySamples, | |
| dimension: dimension, | |
| format: format, | |
| usage: usage | |
| }; | |
| // texture creation | |
| if ( texture.isVideoTexture ) { | |
| const video = texture.source.data; | |
| const videoFrame = new VideoFrame( video ); | |
| textureDescriptorGPU.size.width = videoFrame.displayWidth; | |
| textureDescriptorGPU.size.height = videoFrame.displayHeight; | |
| videoFrame.close(); | |
| textureData.externalTexture = video; | |
| } else { | |
| if ( format === undefined ) { | |
| console.warn( 'WebGPURenderer: Texture format not supported.' ); | |
| this.createDefaultTexture( texture ); | |
| return; | |
| } | |
| if ( texture.isCubeTexture ) { | |
| textureDescriptorGPU.textureBindingViewDimension = GPUTextureViewDimension.Cube; | |
| } | |
| textureData.texture = backend.device.createTexture( textureDescriptorGPU ); | |
| } | |
| if ( isMSAA ) { | |
| const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU ); | |
| msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa'; | |
| msaaTextureDescriptorGPU.sampleCount = samples; | |
| textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU ); | |
| } | |
| textureData.initialized = true; | |
| textureData.textureDescriptorGPU = textureDescriptorGPU; | |
| } | |
| /** | |
| * Destroys the GPU data for the given texture object. | |
| * | |
| * @param {Texture} texture - The texture. | |
| */ | |
| destroyTexture( texture ) { | |
| const backend = this.backend; | |
| const textureData = backend.get( texture ); | |
| if ( textureData.texture !== undefined ) textureData.texture.destroy(); | |
| if ( textureData.msaaTexture !== undefined ) textureData.msaaTexture.destroy(); | |
| backend.delete( texture ); | |
| } | |
| /** | |
| * Destroys the GPU sampler for the given texture. | |
| * | |
| * @param {Texture} texture - The texture to destroy the sampler for. | |
| */ | |
| destroySampler( texture ) { | |
| const backend = this.backend; | |
| const textureData = backend.get( texture ); | |
| delete textureData.sampler; | |
| } | |
| /** | |
| * Generates mipmaps for the given texture. | |
| * | |
| * @param {Texture} texture - The texture. | |
| */ | |
| generateMipmaps( texture ) { | |
| const textureData = this.backend.get( texture ); | |
| if ( texture.isCubeTexture ) { | |
| for ( let i = 0; i < 6; i ++ ) { | |
| this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); | |
| } | |
| } else { | |
| const depth = texture.image.depth || 1; | |
| for ( let i = 0; i < depth; i ++ ) { | |
| this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); | |
| } | |
| } | |
| } | |
| /** | |
| * Returns the color buffer representing the color | |
| * attachment of the default framebuffer. | |
| * | |
| * @return {GPUTexture} The color buffer. | |
| */ | |
| getColorBuffer() { | |
| if ( this.colorBuffer ) this.colorBuffer.destroy(); | |
| const backend = this.backend; | |
| const { width, height } = backend.getDrawingBufferSize(); | |
| this.colorBuffer = backend.device.createTexture( { | |
| label: 'colorBuffer', | |
| size: { | |
| width: width, | |
| height: height, | |
| depthOrArrayLayers: 1 | |
| }, | |
| sampleCount: backend.utils.getSampleCount( backend.renderer.samples ), | |
| format: backend.utils.getPreferredCanvasFormat(), | |
| usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC | |
| } ); | |
| return this.colorBuffer; | |
| } | |
| /** | |
| * Returns the depth buffer representing the depth | |
| * attachment of the default framebuffer. | |
| * | |
| * @param {boolean} [depth=true] - Whether depth is enabled or not. | |
| * @param {boolean} [stencil=false] - Whether stencil is enabled or not. | |
| * @return {GPUTexture} The depth buffer. | |
| */ | |
| getDepthBuffer( depth = true, stencil = false ) { | |
| const backend = this.backend; | |
| const { width, height } = backend.getDrawingBufferSize(); | |
| const depthTexture = this.depthTexture; | |
| const depthTextureGPU = backend.get( depthTexture ).texture; | |
| let format, type; | |
| if ( stencil ) { | |
| format = DepthStencilFormat; | |
| type = UnsignedInt248Type; | |
| } else if ( depth ) { | |
| format = DepthFormat; | |
| type = UnsignedIntType; | |
| } | |
| if ( depthTextureGPU !== undefined ) { | |
| if ( depthTexture.image.width === width && depthTexture.image.height === height && depthTexture.format === format && depthTexture.type === type ) { | |
| return depthTextureGPU; | |
| } | |
| this.destroyTexture( depthTexture ); | |
| } | |
| depthTexture.name = 'depthBuffer'; | |
| depthTexture.format = format; | |
| depthTexture.type = type; | |
| depthTexture.image.width = width; | |
| depthTexture.image.height = height; | |
| this.createTexture( depthTexture, { width, height } ); | |
| return backend.get( depthTexture ).texture; | |
| } | |
| /** | |
| * Uploads the updated texture data to the GPU. | |
| * | |
| * @param {Texture} texture - The texture. | |
| * @param {Object} [options={}] - Optional configuration parameter. | |
| */ | |
| updateTexture( texture, options ) { | |
| const textureData = this.backend.get( texture ); | |
| const { textureDescriptorGPU } = textureData; | |
| if ( texture.isRenderTargetTexture || ( textureDescriptorGPU === undefined /* unsupported texture format */ ) ) | |
| return; | |
| // transfer texture data | |
| if ( texture.isDataTexture ) { | |
| this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY ); | |
| } else if ( texture.isDataArrayTexture || texture.isDepthArrayTexture || texture.isData3DTexture ) { | |
| for ( let i = 0; i < options.image.depth; i ++ ) { | |
| this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, i, texture.flipY, i ); | |
| } | |
| } else if ( texture.isCompressedTexture || texture.isCompressedArrayTexture ) { | |
| this._copyCompressedBufferToTexture( texture.mipmaps, textureData.texture, textureDescriptorGPU ); | |
| } else if ( texture.isCubeTexture ) { | |
| this._copyCubeMapToTexture( options.images, textureData.texture, textureDescriptorGPU, texture.flipY ); | |
| } else if ( texture.isVideoTexture ) { | |
| const video = texture.source.data; | |
| textureData.externalTexture = video; | |
| } else { | |
| this._copyImageToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY ); | |
| } | |
| // | |
| textureData.version = texture.version; | |
| if ( texture.onUpdate ) texture.onUpdate( texture ); | |
| } | |
| /** | |
| * Returns texture data as a typed array. | |
| * | |
| * @async | |
| * @param {Texture} texture - The texture to copy. | |
| * @param {number} x - The x coordinate of the copy origin. | |
| * @param {number} y - The y coordinate of the copy origin. | |
| * @param {number} width - The width of the copy. | |
| * @param {number} height - The height of the copy. | |
| * @param {number} faceIndex - The face index. | |
| * @return {Promise<TypedArray>} A Promise that resolves with a typed array when the copy operation has finished. | |
| */ | |
| async copyTextureToBuffer( texture, x, y, width, height, faceIndex ) { | |
| const device = this.backend.device; | |
| const textureData = this.backend.get( texture ); | |
| const textureGPU = textureData.texture; | |
| const format = textureData.textureDescriptorGPU.format; | |
| const bytesPerTexel = this._getBytesPerTexel( format ); | |
| let bytesPerRow = width * bytesPerTexel; | |
| bytesPerRow = Math.ceil( bytesPerRow / 256 ) * 256; // Align to 256 bytes | |
| const readBuffer = device.createBuffer( | |
| { | |
| size: width * height * bytesPerTexel, | |
| usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ | |
| } | |
| ); | |
| const encoder = device.createCommandEncoder(); | |
| encoder.copyTextureToBuffer( | |
| { | |
| texture: textureGPU, | |
| origin: { x, y, z: faceIndex }, | |
| }, | |
| { | |
| buffer: readBuffer, | |
| bytesPerRow: bytesPerRow | |
| }, | |
| { | |
| width: width, | |
| height: height | |
| } | |
| ); | |
| const typedArrayType = this._getTypedArrayType( format ); | |
| device.queue.submit( [ encoder.finish() ] ); | |
| await readBuffer.mapAsync( GPUMapMode.READ ); | |
| const buffer = readBuffer.getMappedRange(); | |
| return new typedArrayType( buffer ); | |
| } | |
| /** | |
| * Returns `true` if the given texture is an environment map. | |
| * | |
| * @private | |
| * @param {Texture} texture - The texture. | |
| * @return {boolean} Whether the given texture is an environment map or not. | |
| */ | |
| _isEnvironmentTexture( texture ) { | |
| const mapping = texture.mapping; | |
| return ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) || ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping ); | |
| } | |
| /** | |
| * Returns the default GPU texture for the given format. | |
| * | |
| * @private | |
| * @param {string} format - The GPU format. | |
| * @return {GPUTexture} The GPU texture. | |
| */ | |
| _getDefaultTextureGPU( format ) { | |
| let defaultTexture = this.defaultTexture[ format ]; | |
| if ( defaultTexture === undefined ) { | |
| const texture = new Texture(); | |
| texture.minFilter = NearestFilter; | |
| texture.magFilter = NearestFilter; | |
| this.createTexture( texture, { width: 1, height: 1, format } ); | |
| this.defaultTexture[ format ] = defaultTexture = texture; | |
| } | |
| return this.backend.get( defaultTexture ).texture; | |
| } | |
| /** | |
| * Returns the default GPU cube texture for the given format. | |
| * | |
| * @private | |
| * @param {string} format - The GPU format. | |
| * @return {GPUTexture} The GPU texture. | |
| */ | |
| _getDefaultCubeTextureGPU( format ) { | |
| let defaultCubeTexture = this.defaultTexture[ format ]; | |
| if ( defaultCubeTexture === undefined ) { | |
| const texture = new CubeTexture(); | |
| texture.minFilter = NearestFilter; | |
| texture.magFilter = NearestFilter; | |
| this.createTexture( texture, { width: 1, height: 1, depth: 6 } ); | |
| this.defaultCubeTexture[ format ] = defaultCubeTexture = texture; | |
| } | |
| return this.backend.get( defaultCubeTexture ).texture; | |
| } | |
| /** | |
| * Returns the default video frame used as default data in context of video textures. | |
| * | |
| * @private | |
| * @return {VideoFrame} The video frame. | |
| */ | |
| _getDefaultVideoFrame() { | |
| let defaultVideoFrame = this.defaultVideoFrame; | |
| if ( defaultVideoFrame === null ) { | |
| const init = { | |
| timestamp: 0, | |
| codedWidth: 1, | |
| codedHeight: 1, | |
| format: 'RGBA', | |
| }; | |
| this.defaultVideoFrame = defaultVideoFrame = new VideoFrame( new Uint8Array( [ 0, 0, 0, 0xff ] ), init ); | |
| } | |
| return defaultVideoFrame; | |
| } | |
| /** | |
| * Uploads cube texture image data to the GPU memory. | |
| * | |
| * @private | |
| * @param {Array} images - The cube image data. | |
| * @param {GPUTexture} textureGPU - The GPU texture. | |
| * @param {Object} textureDescriptorGPU - The GPU texture descriptor. | |
| * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. | |
| */ | |
| _copyCubeMapToTexture( images, textureGPU, textureDescriptorGPU, flipY ) { | |
| for ( let i = 0; i < 6; i ++ ) { | |
| const image = images[ i ]; | |
| const flipIndex = flipY === true ? _flipMap[ i ] : i; | |
| if ( image.isDataTexture ) { | |
| this._copyBufferToTexture( image.image, textureGPU, textureDescriptorGPU, flipIndex, flipY ); | |
| } else { | |
| this._copyImageToTexture( image, textureGPU, textureDescriptorGPU, flipIndex, flipY ); | |
| } | |
| } | |
| } | |
| /** | |
| * Uploads texture image data to the GPU memory. | |
| * | |
| * @private | |
| * @param {HTMLImageElement|ImageBitmap|HTMLCanvasElement} image - The image data. | |
| * @param {GPUTexture} textureGPU - The GPU texture. | |
| * @param {Object} textureDescriptorGPU - The GPU texture descriptor. | |
| * @param {number} originDepth - The origin depth. | |
| * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. | |
| */ | |
| _copyImageToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY ) { | |
| const device = this.backend.device; | |
| device.queue.copyExternalImageToTexture( | |
| { | |
| source: image, | |
| flipY: flipY | |
| }, { | |
| texture: textureGPU, | |
| mipLevel: 0, | |
| origin: { x: 0, y: 0, z: originDepth } | |
| }, { | |
| width: image.width, | |
| height: image.height, | |
| depthOrArrayLayers: 1 | |
| } | |
| ); | |
| } | |
| /** | |
| * Returns the pass utils singleton. | |
| * | |
| * @private | |
| * @return {WebGPUTexturePassUtils} The utils instance. | |
| */ | |
| _getPassUtils() { | |
| let passUtils = this._passUtils; | |
| if ( passUtils === null ) { | |
| this._passUtils = passUtils = new WebGPUTexturePassUtils( this.backend.device ); | |
| } | |
| return passUtils; | |
| } | |
| /** | |
| * Generates mipmaps for the given GPU texture. | |
| * | |
| * @private | |
| * @param {GPUTexture} textureGPU - The GPU texture object. | |
| * @param {Object} textureDescriptorGPU - The texture descriptor. | |
| * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. | |
| */ | |
| _generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer = 0 ) { | |
| this._getPassUtils().generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer ); | |
| } | |
| /** | |
| * Flip the contents of the given GPU texture along its vertical axis. | |
| * | |
| * @private | |
| * @param {GPUTexture} textureGPU - The GPU texture object. | |
| * @param {Object} textureDescriptorGPU - The texture descriptor. | |
| * @param {number} [originDepth=0] - The origin depth. | |
| */ | |
| _flipY( textureGPU, textureDescriptorGPU, originDepth = 0 ) { | |
| this._getPassUtils().flipY( textureGPU, textureDescriptorGPU, originDepth ); | |
| } | |
| /** | |
| * Uploads texture buffer data to the GPU memory. | |
| * | |
| * @private | |
| * @param {Object} image - An object defining the image buffer data. | |
| * @param {GPUTexture} textureGPU - The GPU texture. | |
| * @param {Object} textureDescriptorGPU - The GPU texture descriptor. | |
| * @param {number} originDepth - The origin depth. | |
| * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. | |
| * @param {number} [depth=0] - TODO. | |
| */ | |
| _copyBufferToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY, depth = 0 ) { | |
| // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() | |
| // @TODO: Consider to support valid buffer layouts with other formats like RGB | |
| const device = this.backend.device; | |
| const data = image.data; | |
| const bytesPerTexel = this._getBytesPerTexel( textureDescriptorGPU.format ); | |
| const bytesPerRow = image.width * bytesPerTexel; | |
| device.queue.writeTexture( | |
| { | |
| texture: textureGPU, | |
| mipLevel: 0, | |
| origin: { x: 0, y: 0, z: originDepth } | |
| }, | |
| data, | |
| { | |
| offset: image.width * image.height * bytesPerTexel * depth, | |
| bytesPerRow | |
| }, | |
| { | |
| width: image.width, | |
| height: image.height, | |
| depthOrArrayLayers: 1 | |
| } ); | |
| if ( flipY === true ) { | |
| this._flipY( textureGPU, textureDescriptorGPU, originDepth ); | |
| } | |
| } | |
| /** | |
| * Uploads compressed texture data to the GPU memory. | |
| * | |
| * @private | |
| * @param {Array<Object>} mipmaps - An array with mipmap data. | |
| * @param {GPUTexture} textureGPU - The GPU texture. | |
| * @param {Object} textureDescriptorGPU - The GPU texture descriptor. | |
| */ | |
| _copyCompressedBufferToTexture( mipmaps, textureGPU, textureDescriptorGPU ) { | |
| // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() | |
| const device = this.backend.device; | |
| const blockData = this._getBlockData( textureDescriptorGPU.format ); | |
| const isTextureArray = textureDescriptorGPU.size.depthOrArrayLayers > 1; | |
| for ( let i = 0; i < mipmaps.length; i ++ ) { | |
| const mipmap = mipmaps[ i ]; | |
| const width = mipmap.width; | |
| const height = mipmap.height; | |
| const depth = isTextureArray ? textureDescriptorGPU.size.depthOrArrayLayers : 1; | |
| const bytesPerRow = Math.ceil( width / blockData.width ) * blockData.byteLength; | |
| const bytesPerImage = bytesPerRow * Math.ceil( height / blockData.height ); | |
| for ( let j = 0; j < depth; j ++ ) { | |
| device.queue.writeTexture( | |
| { | |
| texture: textureGPU, | |
| mipLevel: i, | |
| origin: { x: 0, y: 0, z: j } | |
| }, | |
| mipmap.data, | |
| { | |
| offset: j * bytesPerImage, | |
| bytesPerRow, | |
| rowsPerImage: Math.ceil( height / blockData.height ) | |
| }, | |
| { | |
| width: Math.ceil( width / blockData.width ) * blockData.width, | |
| height: Math.ceil( height / blockData.height ) * blockData.height, | |
| depthOrArrayLayers: 1 | |
| } | |
| ); | |
| } | |
| } | |
| } | |
| /** | |
| * This method is only relevant for compressed texture formats. It returns a block | |
| * data descriptor for the given GPU compressed texture format. | |
| * | |
| * @private | |
| * @param {string} format - The GPU compressed texture format. | |
| * @return {Object} The block data descriptor. | |
| */ | |
| _getBlockData( format ) { | |
| if ( format === GPUTextureFormat.BC1RGBAUnorm || format === GPUTextureFormat.BC1RGBAUnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; // DXT1 | |
| if ( format === GPUTextureFormat.BC2RGBAUnorm || format === GPUTextureFormat.BC2RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT3 | |
| if ( format === GPUTextureFormat.BC3RGBAUnorm || format === GPUTextureFormat.BC3RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT5 | |
| if ( format === GPUTextureFormat.BC4RUnorm || format === GPUTextureFormat.BC4RSnorm ) return { byteLength: 8, width: 4, height: 4 }; // RGTC1 | |
| if ( format === GPUTextureFormat.BC5RGUnorm || format === GPUTextureFormat.BC5RGSnorm ) return { byteLength: 16, width: 4, height: 4 }; // RGTC2 | |
| if ( format === GPUTextureFormat.BC6HRGBUFloat || format === GPUTextureFormat.BC6HRGBFloat ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (float) | |
| if ( format === GPUTextureFormat.BC7RGBAUnorm || format === GPUTextureFormat.BC7RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (unorm) | |
| if ( format === GPUTextureFormat.ETC2RGB8Unorm || format === GPUTextureFormat.ETC2RGB8UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.ETC2RGB8A1Unorm || format === GPUTextureFormat.ETC2RGB8A1UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.ETC2RGBA8Unorm || format === GPUTextureFormat.ETC2RGBA8UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.EACR11Unorm ) return { byteLength: 8, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.EACR11Snorm ) return { byteLength: 8, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.EACRG11Unorm ) return { byteLength: 16, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.EACRG11Snorm ) return { byteLength: 16, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.ASTC4x4Unorm || format === GPUTextureFormat.ASTC4x4UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; | |
| if ( format === GPUTextureFormat.ASTC5x4Unorm || format === GPUTextureFormat.ASTC5x4UnormSRGB ) return { byteLength: 16, width: 5, height: 4 }; | |
| if ( format === GPUTextureFormat.ASTC5x5Unorm || format === GPUTextureFormat.ASTC5x5UnormSRGB ) return { byteLength: 16, width: 5, height: 5 }; | |
| if ( format === GPUTextureFormat.ASTC6x5Unorm || format === GPUTextureFormat.ASTC6x5UnormSRGB ) return { byteLength: 16, width: 6, height: 5 }; | |
| if ( format === GPUTextureFormat.ASTC6x6Unorm || format === GPUTextureFormat.ASTC6x6UnormSRGB ) return { byteLength: 16, width: 6, height: 6 }; | |
| if ( format === GPUTextureFormat.ASTC8x5Unorm || format === GPUTextureFormat.ASTC8x5UnormSRGB ) return { byteLength: 16, width: 8, height: 5 }; | |
| if ( format === GPUTextureFormat.ASTC8x6Unorm || format === GPUTextureFormat.ASTC8x6UnormSRGB ) return { byteLength: 16, width: 8, height: 6 }; | |
| if ( format === GPUTextureFormat.ASTC8x8Unorm || format === GPUTextureFormat.ASTC8x8UnormSRGB ) return { byteLength: 16, width: 8, height: 8 }; | |
| if ( format === GPUTextureFormat.ASTC10x5Unorm || format === GPUTextureFormat.ASTC10x5UnormSRGB ) return { byteLength: 16, width: 10, height: 5 }; | |
| if ( format === GPUTextureFormat.ASTC10x6Unorm || format === GPUTextureFormat.ASTC10x6UnormSRGB ) return { byteLength: 16, width: 10, height: 6 }; | |
| if ( format === GPUTextureFormat.ASTC10x8Unorm || format === GPUTextureFormat.ASTC10x8UnormSRGB ) return { byteLength: 16, width: 10, height: 8 }; | |
| if ( format === GPUTextureFormat.ASTC10x10Unorm || format === GPUTextureFormat.ASTC10x10UnormSRGB ) return { byteLength: 16, width: 10, height: 10 }; | |
| if ( format === GPUTextureFormat.ASTC12x10Unorm || format === GPUTextureFormat.ASTC12x10UnormSRGB ) return { byteLength: 16, width: 12, height: 10 }; | |
| if ( format === GPUTextureFormat.ASTC12x12Unorm || format === GPUTextureFormat.ASTC12x12UnormSRGB ) return { byteLength: 16, width: 12, height: 12 }; | |
| } | |
| /** | |
| * Converts the three.js uv wrapping constants to GPU address mode constants. | |
| * | |
| * @private | |
| * @param {number} value - The three.js constant defining a uv wrapping mode. | |
| * @return {string} The GPU address mode. | |
| */ | |
| _convertAddressMode( value ) { | |
| let addressMode = GPUAddressMode.ClampToEdge; | |
| if ( value === RepeatWrapping ) { | |
| addressMode = GPUAddressMode.Repeat; | |
| } else if ( value === MirroredRepeatWrapping ) { | |
| addressMode = GPUAddressMode.MirrorRepeat; | |
| } | |
| return addressMode; | |
| } | |
| /** | |
| * Converts the three.js filter constants to GPU filter constants. | |
| * | |
| * @private | |
| * @param {number} value - The three.js constant defining a filter mode. | |
| * @return {string} The GPU filter mode. | |
| */ | |
| _convertFilterMode( value ) { | |
| let filterMode = GPUFilterMode.Linear; | |
| if ( value === NearestFilter || value === NearestMipmapNearestFilter || value === NearestMipmapLinearFilter ) { | |
| filterMode = GPUFilterMode.Nearest; | |
| } | |
| return filterMode; | |
| } | |
| /** | |
| * Returns the bytes-per-texel value for the given GPU texture format. | |
| * | |
| * @private | |
| * @param {string} format - The GPU texture format. | |
| * @return {number} The bytes-per-texel. | |
| */ | |
| _getBytesPerTexel( format ) { | |
| // 8-bit formats | |
| if ( format === GPUTextureFormat.R8Unorm || | |
| format === GPUTextureFormat.R8Snorm || | |
| format === GPUTextureFormat.R8Uint || | |
| format === GPUTextureFormat.R8Sint ) return 1; | |
| // 16-bit formats | |
| if ( format === GPUTextureFormat.R16Uint || | |
| format === GPUTextureFormat.R16Sint || | |
| format === GPUTextureFormat.R16Float || | |
| format === GPUTextureFormat.RG8Unorm || | |
| format === GPUTextureFormat.RG8Snorm || | |
| format === GPUTextureFormat.RG8Uint || | |
| format === GPUTextureFormat.RG8Sint ) return 2; | |
| // 32-bit formats | |
| if ( format === GPUTextureFormat.R32Uint || | |
| format === GPUTextureFormat.R32Sint || | |
| format === GPUTextureFormat.R32Float || | |
| format === GPUTextureFormat.RG16Uint || | |
| format === GPUTextureFormat.RG16Sint || | |
| format === GPUTextureFormat.RG16Float || | |
| format === GPUTextureFormat.RGBA8Unorm || | |
| format === GPUTextureFormat.RGBA8UnormSRGB || | |
| format === GPUTextureFormat.RGBA8Snorm || | |
| format === GPUTextureFormat.RGBA8Uint || | |
| format === GPUTextureFormat.RGBA8Sint || | |
| format === GPUTextureFormat.BGRA8Unorm || | |
| format === GPUTextureFormat.BGRA8UnormSRGB || | |
| // Packed 32-bit formats | |
| format === GPUTextureFormat.RGB9E5UFloat || | |
| format === GPUTextureFormat.RGB10A2Unorm || | |
| format === GPUTextureFormat.RG11B10UFloat || | |
| format === GPUTextureFormat.Depth32Float || | |
| format === GPUTextureFormat.Depth24Plus || | |
| format === GPUTextureFormat.Depth24PlusStencil8 || | |
| format === GPUTextureFormat.Depth32FloatStencil8 ) return 4; | |
| // 64-bit formats | |
| if ( format === GPUTextureFormat.RG32Uint || | |
| format === GPUTextureFormat.RG32Sint || | |
| format === GPUTextureFormat.RG32Float || | |
| format === GPUTextureFormat.RGBA16Uint || | |
| format === GPUTextureFormat.RGBA16Sint || | |
| format === GPUTextureFormat.RGBA16Float ) return 8; | |
| // 128-bit formats | |
| if ( format === GPUTextureFormat.RGBA32Uint || | |
| format === GPUTextureFormat.RGBA32Sint || | |
| format === GPUTextureFormat.RGBA32Float ) return 16; | |
| } | |
| /** | |
| * Returns the corresponding typed array type for the given GPU texture format. | |
| * | |
| * @private | |
| * @param {string} format - The GPU texture format. | |
| * @return {TypedArray.constructor} The typed array type. | |
| */ | |
| _getTypedArrayType( format ) { | |
| if ( format === GPUTextureFormat.R8Uint ) return Uint8Array; | |
| if ( format === GPUTextureFormat.R8Sint ) return Int8Array; | |
| if ( format === GPUTextureFormat.R8Unorm ) return Uint8Array; | |
| if ( format === GPUTextureFormat.R8Snorm ) return Int8Array; | |
| if ( format === GPUTextureFormat.RG8Uint ) return Uint8Array; | |
| if ( format === GPUTextureFormat.RG8Sint ) return Int8Array; | |
| if ( format === GPUTextureFormat.RG8Unorm ) return Uint8Array; | |
| if ( format === GPUTextureFormat.RG8Snorm ) return Int8Array; | |
| if ( format === GPUTextureFormat.RGBA8Uint ) return Uint8Array; | |
| if ( format === GPUTextureFormat.RGBA8Sint ) return Int8Array; | |
| if ( format === GPUTextureFormat.RGBA8Unorm ) return Uint8Array; | |
| if ( format === GPUTextureFormat.RGBA8Snorm ) return Int8Array; | |
| if ( format === GPUTextureFormat.R16Uint ) return Uint16Array; | |
| if ( format === GPUTextureFormat.R16Sint ) return Int16Array; | |
| if ( format === GPUTextureFormat.RG16Uint ) return Uint16Array; | |
| if ( format === GPUTextureFormat.RG16Sint ) return Int16Array; | |
| if ( format === GPUTextureFormat.RGBA16Uint ) return Uint16Array; | |
| if ( format === GPUTextureFormat.RGBA16Sint ) return Int16Array; | |
| if ( format === GPUTextureFormat.R16Float ) return Uint16Array; | |
| if ( format === GPUTextureFormat.RG16Float ) return Uint16Array; | |
| if ( format === GPUTextureFormat.RGBA16Float ) return Uint16Array; | |
| if ( format === GPUTextureFormat.R32Uint ) return Uint32Array; | |
| if ( format === GPUTextureFormat.R32Sint ) return Int32Array; | |
| if ( format === GPUTextureFormat.R32Float ) return Float32Array; | |
| if ( format === GPUTextureFormat.RG32Uint ) return Uint32Array; | |
| if ( format === GPUTextureFormat.RG32Sint ) return Int32Array; | |
| if ( format === GPUTextureFormat.RG32Float ) return Float32Array; | |
| if ( format === GPUTextureFormat.RGBA32Uint ) return Uint32Array; | |
| if ( format === GPUTextureFormat.RGBA32Sint ) return Int32Array; | |
| if ( format === GPUTextureFormat.RGBA32Float ) return Float32Array; | |
| if ( format === GPUTextureFormat.BGRA8Unorm ) return Uint8Array; | |
| if ( format === GPUTextureFormat.BGRA8UnormSRGB ) return Uint8Array; | |
| if ( format === GPUTextureFormat.RGB10A2Unorm ) return Uint32Array; | |
| if ( format === GPUTextureFormat.RGB9E5UFloat ) return Uint32Array; | |
| if ( format === GPUTextureFormat.RG11B10UFloat ) return Uint32Array; | |
| if ( format === GPUTextureFormat.Depth32Float ) return Float32Array; | |
| if ( format === GPUTextureFormat.Depth24Plus ) return Uint32Array; | |
| if ( format === GPUTextureFormat.Depth24PlusStencil8 ) return Uint32Array; | |
| if ( format === GPUTextureFormat.Depth32FloatStencil8 ) return Float32Array; | |
| } | |
| /** | |
| * Returns the GPU dimensions for the given texture. | |
| * | |
| * @private | |
| * @param {Texture} texture - The texture. | |
| * @return {string} The GPU dimension. | |
| */ | |
| _getDimension( texture ) { | |
| let dimension; | |
| if ( texture.isData3DTexture ) { | |
| dimension = GPUTextureDimension.ThreeD; | |
| } else { | |
| dimension = GPUTextureDimension.TwoD; | |
| } | |
| return dimension; | |
| } | |
| } | |
| /** | |
| * Returns the GPU format for the given texture. | |
| * | |
| * @param {Texture} texture - The texture. | |
| * @param {?GPUDevice} [device=null] - The GPU device which is used for feature detection. | |
| * It is not necessary to apply the device for most formats. | |
| * @return {string} The GPU format. | |
| */ | |
| export function getFormat( texture, device = null ) { | |
| const format = texture.format; | |
| const type = texture.type; | |
| const colorSpace = texture.colorSpace; | |
| let formatGPU; | |
| if ( texture.isCompressedTexture === true || texture.isCompressedArrayTexture === true ) { | |
| switch ( format ) { | |
| case RGBA_S3TC_DXT1_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm; | |
| break; | |
| case RGBA_S3TC_DXT3_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm; | |
| break; | |
| case RGBA_S3TC_DXT5_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm; | |
| break; | |
| case RGB_ETC2_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm; | |
| break; | |
| case RGBA_ETC2_EAC_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm; | |
| break; | |
| case RGBA_ASTC_4x4_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm; | |
| break; | |
| case RGBA_ASTC_5x4_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm; | |
| break; | |
| case RGBA_ASTC_5x5_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm; | |
| break; | |
| case RGBA_ASTC_6x5_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm; | |
| break; | |
| case RGBA_ASTC_6x6_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm; | |
| break; | |
| case RGBA_ASTC_8x5_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm; | |
| break; | |
| case RGBA_ASTC_8x6_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm; | |
| break; | |
| case RGBA_ASTC_8x8_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm; | |
| break; | |
| case RGBA_ASTC_10x5_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm; | |
| break; | |
| case RGBA_ASTC_10x6_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm; | |
| break; | |
| case RGBA_ASTC_10x8_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm; | |
| break; | |
| case RGBA_ASTC_10x10_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm; | |
| break; | |
| case RGBA_ASTC_12x10_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm; | |
| break; | |
| case RGBA_ASTC_12x12_Format: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm; | |
| break; | |
| case RGBAFormat: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture format.', format ); | |
| } | |
| } else { | |
| switch ( format ) { | |
| case RGBAFormat: | |
| switch ( type ) { | |
| case ByteType: | |
| formatGPU = GPUTextureFormat.RGBA8Snorm; | |
| break; | |
| case ShortType: | |
| formatGPU = GPUTextureFormat.RGBA16Sint; | |
| break; | |
| case UnsignedShortType: | |
| formatGPU = GPUTextureFormat.RGBA16Uint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.RGBA32Uint; | |
| break; | |
| case IntType: | |
| formatGPU = GPUTextureFormat.RGBA32Sint; | |
| break; | |
| case UnsignedByteType: | |
| formatGPU = ( colorSpace === SRGBColorSpace ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; | |
| break; | |
| case HalfFloatType: | |
| formatGPU = GPUTextureFormat.RGBA16Float; | |
| break; | |
| case FloatType: | |
| formatGPU = GPUTextureFormat.RGBA32Float; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type ); | |
| } | |
| break; | |
| case RGBFormat: | |
| switch ( type ) { | |
| case UnsignedInt5999Type: | |
| formatGPU = GPUTextureFormat.RGB9E5UFloat; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RGBFormat.', type ); | |
| } | |
| break; | |
| case RedFormat: | |
| switch ( type ) { | |
| case ByteType: | |
| formatGPU = GPUTextureFormat.R8Snorm; | |
| break; | |
| case ShortType: | |
| formatGPU = GPUTextureFormat.R16Sint; | |
| break; | |
| case UnsignedShortType: | |
| formatGPU = GPUTextureFormat.R16Uint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.R32Uint; | |
| break; | |
| case IntType: | |
| formatGPU = GPUTextureFormat.R32Sint; | |
| break; | |
| case UnsignedByteType: | |
| formatGPU = GPUTextureFormat.R8Unorm; | |
| break; | |
| case HalfFloatType: | |
| formatGPU = GPUTextureFormat.R16Float; | |
| break; | |
| case FloatType: | |
| formatGPU = GPUTextureFormat.R32Float; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type ); | |
| } | |
| break; | |
| case RGFormat: | |
| switch ( type ) { | |
| case ByteType: | |
| formatGPU = GPUTextureFormat.RG8Snorm; | |
| break; | |
| case ShortType: | |
| formatGPU = GPUTextureFormat.RG16Sint; | |
| break; | |
| case UnsignedShortType: | |
| formatGPU = GPUTextureFormat.RG16Uint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.RG32Uint; | |
| break; | |
| case IntType: | |
| formatGPU = GPUTextureFormat.RG32Sint; | |
| break; | |
| case UnsignedByteType: | |
| formatGPU = GPUTextureFormat.RG8Unorm; | |
| break; | |
| case HalfFloatType: | |
| formatGPU = GPUTextureFormat.RG16Float; | |
| break; | |
| case FloatType: | |
| formatGPU = GPUTextureFormat.RG32Float; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type ); | |
| } | |
| break; | |
| case DepthFormat: | |
| switch ( type ) { | |
| case UnsignedShortType: | |
| formatGPU = GPUTextureFormat.Depth16Unorm; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.Depth24Plus; | |
| break; | |
| case FloatType: | |
| formatGPU = GPUTextureFormat.Depth32Float; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type ); | |
| } | |
| break; | |
| case DepthStencilFormat: | |
| switch ( type ) { | |
| case UnsignedInt248Type: | |
| formatGPU = GPUTextureFormat.Depth24PlusStencil8; | |
| break; | |
| case FloatType: | |
| if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) { | |
| console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' ); | |
| } | |
| formatGPU = GPUTextureFormat.Depth32FloatStencil8; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type ); | |
| } | |
| break; | |
| case RedIntegerFormat: | |
| switch ( type ) { | |
| case IntType: | |
| formatGPU = GPUTextureFormat.R32Sint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.R32Uint; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RedIntegerFormat.', type ); | |
| } | |
| break; | |
| case RGIntegerFormat: | |
| switch ( type ) { | |
| case IntType: | |
| formatGPU = GPUTextureFormat.RG32Sint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.RG32Uint; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RGIntegerFormat.', type ); | |
| } | |
| break; | |
| case RGBAIntegerFormat: | |
| switch ( type ) { | |
| case IntType: | |
| formatGPU = GPUTextureFormat.RGBA32Sint; | |
| break; | |
| case UnsignedIntType: | |
| formatGPU = GPUTextureFormat.RGBA32Uint; | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.', type ); | |
| } | |
| break; | |
| default: | |
| console.error( 'WebGPURenderer: Unsupported texture format.', format ); | |
| } | |
| } | |
| return formatGPU; | |
| } | |
| export default WebGPUTextureUtils; | |
Xet Storage Details
- Size:
- 42.3 kB
- Xet hash:
- 307844214c01d6e09aef5f356942d0fea73c25cd0e39b76819e76d3de3ddf535
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.