|
@@ -21863,8 +21863,17 @@ function WebGLLights( extensions, capabilities ) {
|
|
|
|
|
|
// WebGL 2
|
|
|
|
|
|
- state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
|
|
|
- state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
|
|
|
+ if ( extensions.has( 'OES_texture_float_linear' ) === true ) {
|
|
|
+
|
|
|
+ state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
|
|
|
+ state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
|
|
|
+ state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -28113,57 +28122,62 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
|
|
|
|
|
|
for ( let i = 0, il = uniforms.length; i < il; i ++ ) {
|
|
|
|
|
|
- const uniform = uniforms[ i ];
|
|
|
+ const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
|
|
|
|
|
|
- // partly update the buffer if necessary
|
|
|
+ for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
|
|
|
|
|
|
- if ( hasUniformChanged( uniform, i, cache ) === true ) {
|
|
|
+ const uniform = uniformArray[ j ];
|
|
|
|
|
|
- const offset = uniform.__offset;
|
|
|
+ if ( hasUniformChanged( uniform, i, cache ) === true ) {
|
|
|
|
|
|
- const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
|
|
+ const offset = uniform.__offset;
|
|
|
|
|
|
- let arrayOffset = 0;
|
|
|
+ const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
|
|
|
|
|
- for ( let i = 0; i < values.length; i ++ ) {
|
|
|
+ let arrayOffset = 0;
|
|
|
|
|
|
- const value = values[ i ];
|
|
|
+ for ( let i = 0; i < values.length; i ++ ) {
|
|
|
|
|
|
- const info = getUniformSize( value );
|
|
|
+ const value = values[ i ];
|
|
|
|
|
|
- if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
|
|
+ const info = getUniformSize( value );
|
|
|
|
|
|
- uniform.__data[ 0 ] = value;
|
|
|
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
|
|
|
+ // TODO add integer and struct support
|
|
|
+ if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
|
|
|
|
|
- } else if ( value.isMatrix3 ) {
|
|
|
+ uniform.__data[ 0 ] = value;
|
|
|
+ gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
|
|
|
|
|
|
- // manually converting 3x3 to 3x4
|
|
|
+ } else if ( value.isMatrix3 ) {
|
|
|
|
|
|
- uniform.__data[ 0 ] = value.elements[ 0 ];
|
|
|
- uniform.__data[ 1 ] = value.elements[ 1 ];
|
|
|
- uniform.__data[ 2 ] = value.elements[ 2 ];
|
|
|
- uniform.__data[ 3 ] = 0;
|
|
|
- uniform.__data[ 4 ] = value.elements[ 3 ];
|
|
|
- uniform.__data[ 5 ] = value.elements[ 4 ];
|
|
|
- uniform.__data[ 6 ] = value.elements[ 5 ];
|
|
|
- uniform.__data[ 7 ] = 0;
|
|
|
- uniform.__data[ 8 ] = value.elements[ 6 ];
|
|
|
- uniform.__data[ 9 ] = value.elements[ 7 ];
|
|
|
- uniform.__data[ 10 ] = value.elements[ 8 ];
|
|
|
- uniform.__data[ 11 ] = 0;
|
|
|
+ // manually converting 3x3 to 3x4
|
|
|
|
|
|
- } else {
|
|
|
+ uniform.__data[ 0 ] = value.elements[ 0 ];
|
|
|
+ uniform.__data[ 1 ] = value.elements[ 1 ];
|
|
|
+ uniform.__data[ 2 ] = value.elements[ 2 ];
|
|
|
+ uniform.__data[ 3 ] = 0;
|
|
|
+ uniform.__data[ 4 ] = value.elements[ 3 ];
|
|
|
+ uniform.__data[ 5 ] = value.elements[ 4 ];
|
|
|
+ uniform.__data[ 6 ] = value.elements[ 5 ];
|
|
|
+ uniform.__data[ 7 ] = 0;
|
|
|
+ uniform.__data[ 8 ] = value.elements[ 6 ];
|
|
|
+ uniform.__data[ 9 ] = value.elements[ 7 ];
|
|
|
+ uniform.__data[ 10 ] = value.elements[ 8 ];
|
|
|
+ uniform.__data[ 11 ] = 0;
|
|
|
+
|
|
|
+ } else {
|
|
|
|
|
|
- value.toArray( uniform.__data, arrayOffset );
|
|
|
+ value.toArray( uniform.__data, arrayOffset );
|
|
|
|
|
|
- arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
|
|
|
+ arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- }
|
|
|
+ gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
|
|
|
|
|
|
- gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -28260,63 +28274,53 @@ function WebGLUniformsGroups( gl, info, capabilities, state ) {
|
|
|
|
|
|
let offset = 0; // global buffer offset in bytes
|
|
|
const chunkSize = 16; // size of a chunk in bytes
|
|
|
- let chunkOffset = 0; // offset within a single chunk in bytes
|
|
|
|
|
|
for ( let i = 0, l = uniforms.length; i < l; i ++ ) {
|
|
|
|
|
|
- const uniform = uniforms[ i ];
|
|
|
-
|
|
|
- const infos = {
|
|
|
- boundary: 0, // bytes
|
|
|
- storage: 0 // bytes
|
|
|
- };
|
|
|
+ const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
|
|
|
|
|
|
- const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
|
|
+ for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
|
|
|
|
|
|
- for ( let j = 0, jl = values.length; j < jl; j ++ ) {
|
|
|
+ const uniform = uniformArray[ j ];
|
|
|
|
|
|
- const value = values[ j ];
|
|
|
-
|
|
|
- const info = getUniformSize( value );
|
|
|
+ const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
|
|
|
|
|
- infos.boundary += info.boundary;
|
|
|
- infos.storage += info.storage;
|
|
|
+ for ( let k = 0, kl = values.length; k < kl; k ++ ) {
|
|
|
|
|
|
- }
|
|
|
+ const value = values[ k ];
|
|
|
|
|
|
- // the following two properties will be used for partial buffer updates
|
|
|
+ const info = getUniformSize( value );
|
|
|
|
|
|
- uniform.__data = new Float32Array( infos.storage / Float32Array.BYTES_PER_ELEMENT );
|
|
|
- uniform.__offset = offset;
|
|
|
+ // Calculate the chunk offset
|
|
|
+ const chunkOffsetUniform = offset % chunkSize;
|
|
|
|
|
|
- //
|
|
|
+ // Check for chunk overflow
|
|
|
+ if ( chunkOffsetUniform !== 0 && ( chunkSize - chunkOffsetUniform ) < info.boundary ) {
|
|
|
|
|
|
- if ( i > 0 ) {
|
|
|
+ // Add padding and adjust offset
|
|
|
+ offset += ( chunkSize - chunkOffsetUniform );
|
|
|
|
|
|
- chunkOffset = offset % chunkSize;
|
|
|
+ }
|
|
|
|
|
|
- const remainingSizeInChunk = chunkSize - chunkOffset;
|
|
|
+ // the following two properties will be used for partial buffer updates
|
|
|
|
|
|
- // check for chunk overflow
|
|
|
+ uniform.__data = new Float32Array( info.storage / Float32Array.BYTES_PER_ELEMENT );
|
|
|
+ uniform.__offset = offset;
|
|
|
|
|
|
- if ( chunkOffset !== 0 && ( remainingSizeInChunk - infos.boundary ) < 0 ) {
|
|
|
|
|
|
- // add padding and adjust offset
|
|
|
+ // Update the global offset
|
|
|
+ offset += info.storage;
|
|
|
|
|
|
- offset += ( chunkSize - chunkOffset );
|
|
|
- uniform.__offset = offset;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- offset += infos.storage;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
// ensure correct final padding
|
|
|
|
|
|
- chunkOffset = offset % chunkSize;
|
|
|
+ const chunkOffset = offset % chunkSize;
|
|
|
|
|
|
if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset );
|
|
|
|
|
@@ -30817,7 +30821,7 @@ class WebGLRenderer {
|
|
|
textures.setTexture3D( dstTexture, 0 );
|
|
|
glTarget = _gl.TEXTURE_3D;
|
|
|
|
|
|
- } else if ( dstTexture.isDataArrayTexture ) {
|
|
|
+ } else if ( dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture ) {
|
|
|
|
|
|
textures.setTexture2DArray( dstTexture, 0 );
|
|
|
glTarget = _gl.TEXTURE_2D_ARRAY;
|
|
@@ -30839,7 +30843,7 @@ class WebGLRenderer {
|
|
|
const unpackSkipRows = _gl.getParameter( _gl.UNPACK_SKIP_ROWS );
|
|
|
const unpackSkipImages = _gl.getParameter( _gl.UNPACK_SKIP_IMAGES );
|
|
|
|
|
|
- const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ 0 ] : srcTexture.image;
|
|
|
+ const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[ level ] : srcTexture.image;
|
|
|
|
|
|
_gl.pixelStorei( _gl.UNPACK_ROW_LENGTH, image.width );
|
|
|
_gl.pixelStorei( _gl.UNPACK_IMAGE_HEIGHT, image.height );
|
|
@@ -50798,7 +50802,13 @@ class UniformsGroup extends EventDispatcher {
|
|
|
|
|
|
for ( let i = 0, l = uniformsSource.length; i < l; i ++ ) {
|
|
|
|
|
|
- this.uniforms.push( uniformsSource[ i ].clone() );
|
|
|
+ const uniforms = Array.isArray( uniformsSource[ i ] ) ? uniformsSource[ i ] : [ uniformsSource[ i ] ];
|
|
|
+
|
|
|
+ for ( let j = 0; j < uniforms.length; j ++ ) {
|
|
|
+
|
|
|
+ this.uniforms.push( uniforms[ j ].clone() );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|