-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
support all texture formats and types in DataTextureArray.addLayerUpdate and CompressedTextureArray.addLayerUpdate
#28654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
0c0389e
create TextureUtils
HunterLarco e0ee1bf
docs
HunterLarco 1b2f014
use tabs instead of spaces
HunterLarco 5697717
fix lint
HunterLarco 9578fc2
use a byte view
HunterLarco 2a53ea9
remove typo
HunterLarco 4adfd72
ensure the unit8array adheres to the byteLength of the input data source
HunterLarco 71003df
add example
HunterLarco eb9caba
update screenshot
HunterLarco cce0a8e
fix indentation
HunterLarco 6a0e8cd
convert more spaces to tabs
HunterLarco 7d9c6e5
generate screenshot
HunterLarco 8fa7408
generate screenshot
RenaudRohlinger e9088b2
test increase debounce and render in interval instead of loop
RenaudRohlinger fd80f3e
cleanup example
RenaudRohlinger 24a22f5
preserve parity between type and typedarray constructor
HunterLarco 24e188b
remove dependency on setInterval
HunterLarco e81ce45
update screenshot
HunterLarco 1a593c5
Merge branch 'dev' of https://github.com/mrdoob/three.js into hunter/…
HunterLarco File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <base href="../../../" /> | ||
| <script src="page.js"></script> | ||
| <link type="text/css" rel="stylesheet" href="page.css" /> | ||
| </head> | ||
| <body> | ||
| <h1>[name]</h1> | ||
|
|
||
| <p class="desc">A class containing utility functions for textures.</p> | ||
|
|
||
| <h2>Methods</h2> | ||
|
|
||
| <h3>[method:Number getByteLength]( [param:Number width], [param:Number height], [param:Number format], [param:Number type] )</h3> | ||
| <p> | ||
| Given the width, height, format, and type of a texture. Determines how | ||
| many bytes must be used to represent the texture. | ||
| </p> | ||
|
|
||
| <h2>Source</h2> | ||
|
|
||
| <p> | ||
| [link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js] | ||
| </p> | ||
| </body> | ||
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| import { AlphaFormat, LuminanceFormat, LuminanceAlphaFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBFormat, RGBAFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, 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, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, UnsignedByteType, ByteType, UnsignedShortType, ShortType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedIntType, IntType, FloatType, UnsignedInt5999Type } from '../constants.js'; | ||
|
|
||
| /** | ||
| * Given the width, height, format, and type of a texture. Determines how many | ||
| * bytes must be used to represent the texture. | ||
| */ | ||
| function getByteLength( width, height, format, type ) { | ||
|
|
||
| const typeByteLength = getTextureTypeByteLength( type ); | ||
|
|
||
| switch ( format ) { | ||
|
|
||
| // https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml | ||
| case AlphaFormat: | ||
| return width * height; | ||
| case LuminanceFormat: | ||
| return width * height; | ||
| case LuminanceAlphaFormat: | ||
| return width * height * 2; | ||
| case RedFormat: | ||
| return ( ( width * height ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RedIntegerFormat: | ||
| return ( ( width * height ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RGFormat: | ||
| return ( ( width * height * 2 ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RGIntegerFormat: | ||
| return ( ( width * height * 2 ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RGBFormat: | ||
| return ( ( width * height * 3 ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RGBAFormat: | ||
| return ( ( width * height * 4 ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
| case RGBAIntegerFormat: | ||
| return ( ( width * height * 4 ) / typeByteLength.components ) * typeByteLength.byteLength; | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/ | ||
| case RGB_S3TC_DXT1_Format: | ||
| case RGBA_S3TC_DXT1_Format: | ||
| return Math.floor( ( width + 3 ) / 4 ) * Math.floor( ( height + 3 ) / 4 ) * 8; | ||
| case RGBA_S3TC_DXT3_Format: | ||
| case RGBA_S3TC_DXT5_Format: | ||
| return Math.floor( ( width + 3 ) / 4 ) * Math.floor( ( height + 3 ) / 4 ) * 16; | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_pvrtc/ | ||
| case RGB_PVRTC_2BPPV1_Format: | ||
| case RGBA_PVRTC_2BPPV1_Format: | ||
| return ( Math.max( width, 16 ) * Math.max( height, 8 ) ) / 4; | ||
| case RGB_PVRTC_4BPPV1_Format: | ||
| case RGBA_PVRTC_4BPPV1_Format: | ||
| return ( Math.max( width, 8 ) * Math.max( height, 8 ) ) / 2; | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc/ | ||
| case RGB_ETC1_Format: | ||
| case RGB_ETC2_Format: | ||
| return Math.floor( ( width + 3 ) / 4 ) * Math.floor( ( height + 3 ) / 4 ) * 8; | ||
| case RGBA_ETC2_EAC_Format: | ||
| return Math.floor( ( width + 3 ) / 4 ) * Math.floor( ( height + 3 ) / 4 ) * 16; | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/ | ||
| case RGBA_ASTC_4x4_Format: | ||
| return Math.floor( ( width + 3 ) / 4 ) * Math.floor( ( height + 3 ) / 4 ) * 16; | ||
| case RGBA_ASTC_5x4_Format: | ||
| return Math.floor( ( width + 4 ) / 5 ) * Math.floor( ( height + 3 ) / 4 ) * 16; | ||
| case RGBA_ASTC_5x5_Format: | ||
| return Math.floor( ( width + 4 ) / 5 ) * Math.floor( ( height + 4 ) / 5 ) * 16; | ||
| case RGBA_ASTC_6x5_Format: | ||
| return Math.floor( ( width + 5 ) / 6 ) * Math.floor( ( height + 4 ) / 5 ) * 16; | ||
| case RGBA_ASTC_6x6_Format: | ||
| return Math.floor( ( width + 5 ) / 6 ) * Math.floor( ( height + 5 ) / 6 ) * 16; | ||
| case RGBA_ASTC_8x5_Format: | ||
| return Math.floor( ( width + 7 ) / 8 ) * Math.floor( ( height + 4 ) / 5 ) * 16; | ||
| case RGBA_ASTC_8x6_Format: | ||
| return Math.floor( ( width + 7 ) / 8 ) * Math.floor( ( height + 5 ) / 6 ) * 16; | ||
| case RGBA_ASTC_8x8_Format: | ||
| return Math.floor( ( width + 7 ) / 8 ) * Math.floor( ( height + 7 ) / 8 ) * 16; | ||
| case RGBA_ASTC_10x5_Format: | ||
| return Math.floor( ( width + 9 ) / 10 ) * Math.floor( ( height + 4 ) / 5 ) * 16; | ||
| case RGBA_ASTC_10x6_Format: | ||
| return Math.floor( ( width + 9 ) / 10 ) * Math.floor( ( height + 5 ) / 6 ) * 16; | ||
| case RGBA_ASTC_10x8_Format: | ||
| return Math.floor( ( width + 9 ) / 10 ) * Math.floor( ( height + 7 ) / 8 ) * 16; | ||
| case RGBA_ASTC_10x10_Format: | ||
| return Math.floor( ( width + 9 ) / 10 ) * Math.floor( ( height + 9 ) / 10 ) * 16; | ||
| case RGBA_ASTC_12x10_Format: | ||
| return Math.floor( ( width + 11 ) / 12 ) * Math.floor( ( height + 9 ) / 10 ) * 16; | ||
| case RGBA_ASTC_12x12_Format: | ||
| return ( | ||
| Math.floor( ( width + 11 ) / 12 ) * Math.floor( ( height + 11 ) / 12 ) * 16 | ||
| ); | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_bptc/ | ||
| case RGBA_BPTC_Format: | ||
| case RGB_BPTC_SIGNED_Format: | ||
| case RGB_BPTC_UNSIGNED_Format: | ||
| return Math.ceil( width / 4 ) * Math.ceil( height / 4 ) * 16; | ||
|
|
||
| // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_rgtc/ | ||
| case RED_RGTC1_Format: | ||
| case SIGNED_RED_RGTC1_Format: | ||
| return Math.ceil( width / 4 ) * Math.ceil( height / 4 ) * 8; | ||
| case RED_GREEN_RGTC2_Format: | ||
| case SIGNED_RED_GREEN_RGTC2_Format: | ||
| return Math.ceil( width / 4 ) * Math.ceil( height / 4 ) * 16; | ||
|
|
||
| } | ||
|
|
||
| throw new Error( | ||
| `Unable to determine texture byte length for ${format} format.`, | ||
| ); | ||
|
|
||
| } | ||
|
|
||
| function getTextureTypeByteLength( type ) { | ||
|
|
||
| switch ( type ) { | ||
|
|
||
| case UnsignedByteType: | ||
| case ByteType: | ||
| return { byteLength: 1, components: 1 }; | ||
| case UnsignedShortType: | ||
| case ShortType: | ||
| case HalfFloatType: | ||
| return { byteLength: 2, components: 1 }; | ||
| case UnsignedShort4444Type: | ||
| case UnsignedShort5551Type: | ||
| return { byteLength: 2, components: 4 }; | ||
| case UnsignedIntType: | ||
| case IntType: | ||
| case FloatType: | ||
| return { byteLength: 4, components: 1 }; | ||
| case UnsignedInt5999Type: | ||
| return { byteLength: 4, components: 3 }; | ||
|
|
||
| } | ||
|
|
||
| throw new Error( `Unknown texture type ${type}.` ); | ||
|
|
||
| } | ||
|
|
||
| const TextureUtils = { | ||
| getByteLength, | ||
| }; | ||
|
|
||
| export { getByteLength, TextureUtils }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this function be internal or is it required for the user to have access to it?
If possible, I would prefer to not expose it and move the logic to
WebGLUtilsinstead. In a different PR, there is the plan to addTextureUtilsas an addon inexamples/jsm(see #28512 (comment)). It is not ideal to have the same module in the core and as an addon.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, I see
getByteLength()is used in the new example...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is an advanced feature, I would probably not expose the helper for now and inline the size computation in the example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I think
addLayerUpdatehas limited value if three doesn't provide clients a way to know the byte bounds of a single layer. You needTextureUtils.getByteLengthto know which subarray within theCompressedArrayTexture's data to update. We could make this method internal, but then it would force clients to either implement this logic themselves or copy/paste it from the three repo.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And inlining would fail in the example because the KTX2Loader dynamically selects a format + type depending on the underlying WebGL context. There's no guarantee that the hard-coded byte length will be consistent on different devices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also thanks for the quick review)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's see how we can organize the code regarding #28512.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in #28512 is so compact so I think we can move it in
srcas well. That means there is no need to update this PR.It's definitely good that the layer size computation in
uploadTexture()is moved into a helper function.