diff --git a/rollup.config.js b/rollup.config.js index 440ab7c7467e6203fe0a5dacc38f2572064ca750..d7789cf266cabfd249b1229db152d4fd24b5239d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -117,6 +117,7 @@ function glconstants() { ACTIVE_ATTRIBUTES: 35721, IMPLEMENTATION_COLOR_READ_TYPE: 35738, IMPLEMENTATION_COLOR_READ_FORMAT: 35739, + TEXTURE_2D_ARRAY: 35866, DEPTH_COMPONENT32F: 36012, COLOR_ATTACHMENT0: 36064, FRAMEBUFFER_COMPLETE: 36053, diff --git a/src/Three.js b/src/Three.js index 96ddb0302257313eeb8d5646093644224dfdede6..e787618ae359c12569e8d388040f104b4389de5b 100644 --- a/src/Three.js +++ b/src/Three.js @@ -24,6 +24,7 @@ export { Points } from './objects/Points.js'; export { Group } from './objects/Group.js'; export { VideoTexture } from './textures/VideoTexture.js'; export { DataTexture } from './textures/DataTexture.js'; +export { DataTexture2DArray } from './textures/DataTexture2DArray.js'; export { DataTexture3D } from './textures/DataTexture3D.js'; export { CompressedTexture } from './textures/CompressedTexture.js'; export { CubeTexture } from './textures/CubeTexture.js'; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 5d1c41c3b51cdd635d95deb6ccd4b3cd793b2a62..0a5d2a820381007754b53eef9152ae454aecb226 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -2462,6 +2462,12 @@ function WebGLRenderer( parameters ) { }() ); + this.setTexture2DArray = function ( texture, slot ) { + + textures.setTexture2DArray( texture, slot ); + + }; + this.setTexture3D = ( function () { // backwards compatibility: peel texture.texture diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 32b92cc89441dd11e6670f41a017d16425edd20a..c101119dac22102c941e7df4cef22250a8931d7f 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -297,6 +297,22 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } + function setTexture2DArray( texture, slot ) { + + var textureProperties = properties.get( texture ); + + if ( texture.version > 0 && textureProperties.__version !== texture.version ) { + + uploadTexture( textureProperties, texture, slot ); + return; + + } + + state.activeTexture( _gl.TEXTURE0 + slot ); + state.bindTexture( _gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture ); + + } + function setTexture3D( texture, slot ) { var textureProperties = properties.get( texture ); @@ -449,7 +465,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, utils.convert( texture.wrapS ) ); _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, utils.convert( texture.wrapT ) ); - if ( textureType === _gl.TEXTURE_3D ) { + if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) { _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, utils.convert( texture.wrapR ) ); @@ -463,7 +479,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE ); _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE ); - if ( textureType === _gl.TEXTURE_3D ) { + if ( textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY ) { _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE ); @@ -522,7 +538,10 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, function uploadTexture( textureProperties, texture, slot ) { - var textureType = ( texture.isDataTexture3D ) ? _gl.TEXTURE_3D : _gl.TEXTURE_2D; + var textureType = _gl.TEXTURE_2D; + + if ( texture.isDataTexture2DArray ) textureType = _gl.TEXTURE_2D_ARRAY; + if ( texture.isDataTexture3D ) textureType = _gl.TEXTURE_3D; initTexture( textureProperties, texture ); @@ -654,6 +673,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, textureProperties.__maxMipLevel = mipmaps.length - 1; + } else if ( texture.isDataTexture2DArray ) { + + state.texImage3D( _gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); + textureProperties.__maxMipLevel = 0; + } else if ( texture.isDataTexture3D ) { state.texImage3D( _gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data ); @@ -1052,6 +1076,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, } this.setTexture2D = setTexture2D; + this.setTexture2DArray = setTexture2DArray; this.setTexture3D = setTexture3D; this.setTextureCube = setTextureCube; this.setTextureCubeDynamic = setTextureCubeDynamic; diff --git a/src/renderers/webgl/WebGLUniforms.js b/src/renderers/webgl/WebGLUniforms.js index 4bdd1bd34b5c6f1a84f9ec88cd38572e1ac0ca16..aa25ccf257e9c62c5114525c988aa1913f85e365 100644 --- a/src/renderers/webgl/WebGLUniforms.js +++ b/src/renderers/webgl/WebGLUniforms.js @@ -390,6 +390,22 @@ function setValueT1( gl, v, renderer ) { } +function setValueT2DArray1( gl, v, renderer ) { + + var cache = this.cache; + var unit = renderer.allocTextureUnit(); + + if ( cache[ 0 ] !== unit ) { + + gl.uniform1i( this.addr, unit ); + cache[ 0 ] = unit; + + } + + renderer.setTexture2DArray( v || emptyTexture2dArray, unit ); + +} + function setValueT3D1( gl, v, renderer ) { var cache = this.cache; @@ -478,6 +494,7 @@ function getSingularSetter( type ) { case 0x8b5e: case 0x8d66: return setValueT1; // SAMPLER_2D, SAMPLER_EXTERNAL_OES case 0x8B5F: return setValueT3D1; // SAMPLER_3D case 0x8b60: return setValueT6; // SAMPLER_CUBE + case 0x8DC1: return setValueT2DArray1; // SAMPLER_2D_ARRAY case 0x1404: case 0x8b56: return setValue1i; // INT, BOOL case 0x8b53: case 0x8b57: return setValue2iv; // _VEC2 diff --git a/src/textures/DataTexture2DArray.d.ts b/src/textures/DataTexture2DArray.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..a722d8451d7586cf5389346cad2d328c615cf6ed --- /dev/null +++ b/src/textures/DataTexture2DArray.d.ts @@ -0,0 +1,12 @@ +import { Texture } from './Texture'; +import { NearestFilter } from '../constants'; +import { TypedArray } from '../polyfills'; + +export class DataTexture2DArray extends Texture { + constructor( + data: ArrayBuffer | TypedArray, + width: number, + height: number, + depth: number + ); +} diff --git a/src/textures/DataTexture2DArray.js b/src/textures/DataTexture2DArray.js new file mode 100644 index 0000000000000000000000000000000000000000..2a90d4cc4f9972b36fa04379d9347795d0f5c54e --- /dev/null +++ b/src/textures/DataTexture2DArray.js @@ -0,0 +1,28 @@ +/** + * @author Takahiro https://github.com/takahirox + */ + +import { Texture } from './Texture.js'; +import { ClampToEdgeWrapping, NearestFilter } from '../constants.js'; + +function DataTexture2DArray( data, width, height, depth ) { + + Texture.call( this, null ); + + this.image = { data: data, width: width, height: height, depth: depth }; + + this.magFilter = NearestFilter; + this.minFilter = NearestFilter; + + this.wrapR = ClampToEdgeWrapping; + + this.generateMipmaps = false; + this.flipY = false; + +} + +DataTexture2DArray.prototype = Object.create( Texture.prototype ); +DataTexture2DArray.prototype.constructor = DataTexture2DArray; +DataTexture2DArray.prototype.isDataTexture2DArray = true; + +export { DataTexture2DArray };