binomialllc / basis_universal Goto Github PK
View Code? Open in Web Editor NEWBasis Universal GPU Texture Codec
License: Apache License 2.0
Basis Universal GPU Texture Codec
License: Apache License 2.0
Greetings basis_universal developers and contributors,
We’re reaching out because your project is an important part of the open source ecosystem, and we’d like to invite you to integrate with our fuzzing service, OSS-Fuzz. OSS-Fuzz is a free fuzzing infrastructure you can use to identify security vulnerabilities and stability bugs in your project. OSS-Fuzz will:
Many widely used open source projects like OpenSSL, FFmpeg, LibreOffice, and ImageMagick are fuzzing via OSS-Fuzz, which helps them find and remediate critical issues.
Even though typical integrations can be done in < 100 LoC, we have a reward program in place which aims to recognize folks who are not just contributing to open source, but are also working hard to make it more secure.
We want to stress that anyone who meets the eligibility criteria and integrates a project with OSS-Fuzz is eligible for a reward.
If you're not interested in integrating with OSS-Fuzz, it would be helpful for us to understand why—lack of interest, lack of time, or something else—so we can better support projects like yours in the future.
If we’ve missed your question in our FAQ, feel free to reply or reach out to us at [email protected].
Thanks!
Julien,
OSS-Fuzz Team
Per PVRTC extension spec https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc.txt:
6) How is the imageSize argument calculated for the CompressedTexImage2D and CompressedTexSubImage2D functions. Resolution: For PVRTC 4BPP formats the imageSize is calculated as: ( max(width, 8) * max(height, 8) * 4 + 7) / 8
Width and height are clamped to 8 before computing the imageSize. However, transcoder computes a smaller size - instead of 32 bytes for 4x4 image, it assumes it's just one 8-byte block and returns 8 - which leads to glCompressedTexImage2D generating an error on iOS:
INVALID_VALUE: compressedTexImage2D: length of ArrayBufferView is not correct for dimensions.
I'm not sure if this is just padding - that is, if the workaround of transcoding the first 8 bytes in a 32-byte buffer and passing the resulting buffer to GL is correct, or if the remaining bytes need to be filled with meaningful information.
AFAICT tell there no infomation about wether the texture is in sRGB space or SNORM (for BC4/BC5).
Essentially we have to keep that metadata in the file name or some where else.
Would be good to store that data in the basis file itself
Hello everyone,
I'm trying to pack my texture to basis format with following option get best quality
basisu x.png -level 5 -max_endpoints 16128 -max_selectors 16128 -no_selector_rdo -no_endpoint_rdo
My original texture
Here is unpacked texture for ETC1 format
As you can see, there is big different on unpacked texture, the color pixel doesn't smooth as original texture.
Any suggestion to get better quanlity texture please?
Thank you.
Coudnt find this option, currently the .basis is create from where the command is call, it would be great to add this feature.
I'm not sure what exactly is wrong but I can't seem to get ETC1 transcoding to work on device inside any demo programs.
This is using Moto E4, Android 7.1.
Here's how it looks like, using https://basis-universal-webgl.now.sh/gltf/:
I suspect the issue isn't with ETC1 transcoding per se and it's instead with loader/texture setup/etc. Curious, does this generally work on Android - is it just my device that's broken, or is it a more widespread issue?
The readme (https://github.com/BinomialLLC/basis_universal/tree/master/webgl) states that Firefox does not support BC1 format. It does and has for some time now with the extension "WEBGL_compressed_texture_s3tc" as opposed to "WEBKIT_WEBGL_compressed_texture_s3tc" which the demo tests.
https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_compressed_texture_s3tc
Hey!
Great to see this open source! I was just wondering (and maybe there is already support for this) but for very large .basis files, will there be support for the scenario of memory-mapping the .basis file and being able to transcode image slices to memory? I'm thinking about virtual texture scenarios here where each image is a tile/page to load into a physical texture, but you don't want all the compressed files in memory. Maybe it is as easy as passing in an mmap pointer, I haven't tried yet...
Cheers!
Hey Rich!
We're working on an integration for the Unity Engine. The WebGL sample creates an instance of basisu_transcoder per texture, but as far as I can tell we only need one basisu_transcoder in our entire dll.
We're also looking into multithreading, but we can't quite tell if a single basisu_transcoder for the entire library would be thread safe. Nearly all functions in basisu_transcoder seem to be pure functions. In the readme you've mentioned that transcode_image_level
and transcode_slice
are thread safe.
That leaves start_transcoding
, which I can't tell right away if it's thread safe, because it interacts with the low level decoder.
More details of our investigation are here: atteneder/KtxUnity#1
Hi,
It would be nice to add support for more input image types.
Adding stb_image.h would allow support for tga, hdr and more!
Cheers,
Mihai
In the generate_hierarchical_codebook_threaded
function, an std::unordered_map
is used for counting unique training vectors.
Lines 1598 to 1608 in 6002320
Iteration over the unordered map is implementation-dependent, so this code builds group_quant
differently on MSVC and GCC/Clang.
Lines 1634 to 1638 in 6002320
As a result, the encoder produces different selectors and codebooks on different platforms.
After switching group_hash
to be an ordered map, files produced on different platforms are the same (likely with some performance cost):
diff --git a/basisu_enc.h b/basisu_enc.h
index 7d42121..7946c76 100644
--- a/basisu_enc.h
+++ b/basisu_enc.h
@@ -21,7 +21,7 @@
#include <condition_variable>
#include <functional>
#include <thread>
-#include <unordered_map>
+#include <map>
#ifndef _WIN32
#include <libgen.h>
@@ -1602,8 +1602,7 @@ namespace basisu
uint32_t max_threads, job_pool *pJob_pool)
{
typedef bit_hasher<typename Quantizer::training_vec_type> training_vec_bit_hasher;
- typedef std::unordered_map < typename Quantizer::training_vec_type, weighted_block_group,
- training_vec_bit_hasher> group_hash;
+ typedef std::map < typename Quantizer::training_vec_type, weighted_block_group> group_hash;
group_hash unique_vecs;
Maybe, there is a better way to achieve deterministic results.
I'm a bit weak on compressed formats and how they are supported across various API's.. apologies in advance if I've missed the mark
What I think I know... (in OpenGL speak)..
BC1 --> GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
BC2 --> GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
BC3 --> GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
BC5 --> GL_COMPRESSED_SIGNED_RG_RGTC2
What confuses me, is this part of the README:
Devices/API's supporting BC1-5, BC6H, BC7: Transcode to a single BC5 textures, which used to be called "ATI 3DC". It has two high quality BC4 blocks in there, so it'll look great. Once BC7 alpha support comes online that will be the better option.
I think maybe I have misunderstood the intent of the above.
From what I understand BC5 is a two-channel texture format. Is there some additional magic to make that work for RGBA? Rendering a BC5 transcode using GL_COMPRESSED_SIGNED_RG_RGTC2 shows major artefacts.
For now I'm using BC3 and getting good results for RGBA textures.
Incidentally - and probably off-topic... is there documentation that indicates a mapping between each of the available transcode formats and their corresponding format/enum usage in OpenGL / Vulkan / Metal / etc?
I used the Open Folder feature in VS2019 to open the CMake project. The build fails with:
Severity Code Description Project File Line Suppression State
Error D8021 invalid numeric argument '/Wextra'
It would be nice if the project features CMakeSettings.json
There are 2 regular printfs
in basisu_comp.cpp
one at line 496 that prints "Total basis file slices" and one, a couple of lines later, that prints all the information about each slice. Is it intentional that these are NOT debug_printf
?
In my use of the compressor from within a library, I'd prefer it did not print anything.
Lots of unsuppressed warnings that should be fixed in the source or explicitly suppressed in the CMakeLists.txt:
-Wc++98-compat -Wc++98-compat-pedantic
-Wfloat-conversion -Wdouble-promotion -Wfloat-equal
-Wsign-conversion -Wimplicit-int-conversion -Wshift-sign-overflow
-Wglobal-constructors -Wmissing-prototypes -Wmissing-variable-declarations
-Wcovered-switch-default -Wswitch-enum
-Wreserved-id-macro -Wgnu-anonymous-struct -Wnested-anon-types
-Wshadow-field -Wunused-macros
-Wzero-as-null-pointer-constant -Wold-style-cast -Wcast-qual -Wcast-align
-Wcomma -Wextra-semi -Wextra-semi-stmt
-Wunreachable-code-break -Wdeprecated -Wmissing-noreturn
-Wformat-nonliteral
-Wnewline-eof -Wnonportable-system-include-path
Also, it would be nice to replace the -std=c++11
switch with the following in CMakeLists.txt:
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
And lastly, the following switches generate -Wunknown-argument
on clang for Windows 8:
fvisibility=hidden -fvisibility-inlines-hidden -fPIC
For easier integration in existing pipelines it would be nice if the transcoder and the compressor were provided as libraries and the tool would link with the 2 libraries.
for this i propose to
Cheers
Mihai
I've tried to add a slider to test if quick switching between video frames would work, unfortunately, this generates fatal error very quickly and some frames look damaged as well, probably the API is used incorrectly. Would it be possible to support this kind of fast switching between frames or what do I miss in the API? I'm trying to evaluate if basis can be used to keep videos with satellite images instead of webm, to have a faster way to inspect them. Or maybe at least encode webm>basis locally to support faster inspection and editing locally.
Here is a code snippet built on top of webgl_videotest: https://codesandbox.io/s/static-0g1o9?fontsize=14.
I use dracoloader loading to appear
[.WebGL-0000023A9FD93560]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
Can we ensure that Basis is supported on all devices (like jpeg, png)?
Or should I prepare fallback to jpeg, png in case some devices does not support any compressed texture formats (Is there any device like that?)
Was interested into adding this for the Godot Engine.
How difficult is it to remove the OpenMP dependency and keep multithreading?
Thoughts on Basis for Godot Engine? Best uses?
[Edited] Currently Godot defaults to S3TC.
[Edited] Godot can't use OpenMP.
Low priority question, feel free to answer whenever, or point me to resources to help me answer the questions... 😀
Pretty much all the documentation discusses transcoder support using wasm for the web, which the browser then handles a lot of the heavy lifting with via wasm, the transcoder and webgl.
However, I have a possible different use case, and I could be completely wrong on this idea. Can this code be easily be used naively to decode images into the gpu w/o a browser/wasm. Using XCode & Android NDX to build the code on iOS & Android. Do I just have to setup a OpenGL 2.x+ session and then point the trancoder to it somehow? I assume we need the OpenGL session so that it has access to the GPU; correct?
Is it possible to support browser without WASM support?
According to the wasm compatibility chart, there're still majority of devices doesn't support WASM yet (like Safari below iOS 11).
I think to be more "Universal", Basis should provide some kind of polyfill for browser without WASM support (I guess decoding could be slower, but slower is still better than none right?)
Would you accept a pull request that replaces <vector>
with stripped down non-stdlib code? Needing to link in the C++ standard library to decode basis files is kind of unfortunate
The README is very long, dry and boring to read. I think we could use a chunked, HTML styled tutorial like docs with a TOC and hyperlinks too with some examples, so that relevant information could be searched easily.
It would be nice to see some statistics about what overhead could we expect when using the transcoding over native compression.
Also having some version number at the top of the README would be helpful to notify that a new milestone was released/something has changed.
Hi,
I know this is on the todo list, I'm just filing this here in case someone has time to work on it.
@richgel999 could you comment a bit with what would be needed for this and how would we go about implementing it ?
One thing my organization has done with it's use of KTX is ensure that each KTX uses the key/value area to store a hash of the original uncompressed image. This then ends up becoming the primary key into an in-memory runtime cache of KTX files. This way if a user is using some kind of asset with embedded images (like an FBX or GLB with inline PNG images), then we can recognize multiple instances of the same input image regardless of their source. It would be handy if this was a standard field in the binomial format, or the contents of a standard key if arbitrary key/value pairs are supported.
It is a bit difficult to use BU in a workflow that expects portable RGTC cupport for normalmaps, which are supported fine by both BC5 on desktop and ETC2RG on mobile. If transcoding to EAC is supported, i don't get why this does not work.
The example are great but it would be nice to include in the README the complete list of the options we can use with the basisu command.
line 4934: calling function ucvector_init() to initialize 'data'
Line 4934 in 21ab9be
in function ucvector_init()
line 245, 'data' may be assigned as null pointer.
Line 245 in 21ab9be
line 4936: 'data' is used as argument while calling function ucvector_push_back()
Line 4936 in 21ab9be
while calling function ucvector_push_back()
line 263: dereference 'p->data' without checking whether it is a null pointer.
Line 263 in 21ab9be
(Our tool also found that in line 220 there is a check for 'data' which is the return value of calling function 'lodepng_realloc()', and assume that the value (data) is null. Even if this case will hardly happen, it is better to add an 'assert(p->data)' as a better software engineering perspective)
Comments in basisu_file_headers.h about the _ofs fields being "file offset(s) relative to the header" are incorrect. Looking at transcoder.cpp they are obviously relative to the start of the file.
While the README is quite extensive, perhaps it should have near the top a section for the impatient which gives the steps for compiling and using it from the command line. Something like
cmake CMakeLists.txt
make
bin/basisu samples/kodim20.png # to convert to basis format
bin/basisu samples/kodim20.basis # to extract images from basis
basisu x.png
basisu x.basis
basisu -file x.png -mipmap -y_flip
basisu -validate -file x.basis
basisu -unpack -file x.basis
basisu -q 255 -file x.png -mipmap -debug -stats
basisu -linear -max_endpoints 16128 -max_selectors 16128 -file x.png
basisu -linear -global_sel_pal -no_hybrid_sel_cb -file x.png
basisu -linear -global_sel_pal -file x.png
basisu -tex_type video -framerate 20 -multifile_printf "x%02u.png" -multifile_first 1 -multifile_count 20
P.S. Saw this on Stephanie Hurlburt's twitter and thought I'd take the future for a spin. Looks great so far!
Hi there,
Thanks so much for trying to solve this problem, which everyone tries to fix in various way.
Apparently alpha support is currently missing, and I wonder if there's any sort of ETA on supporting this. Is that very hard to support ? What would be a good way to start contributing helping here ?
Thanks !
There's either a problem with my understanding and use of the tools or a problem with the KTX output by basis.
I am trying to use basis to convert six images into KTX files each containing a cubemap.
I have the six images (files from here https://github.com/ARM-software/opengl-es-sdk-for-android/tree/master/samples/advanced_samples/Skybox/assets converted into PNGs with imagemagick).
I run
basisu greenhouse_skybox-*.png -tex_type cubemap -output_file cubemap.basis
The output is:
Basis Universal GPU Texture Compressor Reference Encoder v1.07.00, Copyright (C) 2017-2019 Binomial LLC, All rights reserved
Processing 6 total files
Read source image "greenhouse_skybox-0.png", 1024x1024
Read source image "greenhouse_skybox-1.png", 1024x1024
Read source image "greenhouse_skybox-2.png", 1024x1024
Read source image "greenhouse_skybox-3.png", 1024x1024
Read source image "greenhouse_skybox-4.png", 1024x1024
Read source image "greenhouse_skybox-5.png", 1024x1024
Total basis file slices: 6
Slice: 0, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 0, image_index: 0, mip_level: 0
Slice: 1, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 65536, image_index: 1, mip_level: 0
Slice: 2, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 131072, image_index: 2, mip_level: 0
Slice: 3, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 196608, image_index: 3, mip_level: 0
Slice: 4, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 262144, image_index: 4, mip_level: 0
Slice: 5, alpha: 0, orig width/height: 1024x1024, width/height: 1024x1024, first_block: 327680, image_index: 5, mip_level: 0
Wrote output .basis file "cubemap.basis"
Compression succeeded to file "cubemap.basis" in 8.616 secs
I then run basis to unpack the file
basisu cubemap.basis
Output:
Basis Universal GPU Texture Compressor Reference Encoder v1.07.00, Copyright (C) 2017-2019 Binomial LLC, All rights reserved
Input file "cubemap.basis"
File version and CRC checks succeeded
File info:
Version: 13
Total header size: 215
Total selectors: 2646
Selector codebook size: 5055
Total endpoints: 1359
Endpoint codebook size: 2270
Tables size: 1326
Slices size: 473232
Texture type: cubemap array
us per frame: 0 (0.000000 fps)
Total slices: 6
Total images: 6
Y Flipped: 0, Has alpha slices: 0
userdata0: 0x0 userdata1: 0x0
Per-image mipmap levels: 1 1 1 1 1 1
Image info:
Image 0: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 0, HasAlpha: 0
Image 1: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 1, HasAlpha: 0
Image 2: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 2, HasAlpha: 0
Image 3: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 3, HasAlpha: 0
Image 4: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 4, HasAlpha: 0
Image 5: MipLevels: 1 OrigDim: 1024x1024, BlockDim: 256x256, FirstSlice: 5, HasAlpha: 0
Transcode of image 0 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 0 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 0 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 0 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 0 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 0 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 0 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 0 level 0 res 1024x1024 format BC5 succeeded
Transcode of image 1 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 1 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 1 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 1 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 1 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 1 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 1 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 1 level 0 res 1024x1024 format BC5 succeeded
Transcode of image 2 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 2 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 2 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 2 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 2 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 2 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 2 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 2 level 0 res 1024x1024 format BC5 succeeded
Transcode of image 3 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 3 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 3 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 3 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 3 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 3 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 3 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 3 level 0 res 1024x1024 format BC5 succeeded
Transcode of image 4 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 4 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 4 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 4 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 4 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 4 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 4 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 4 level 0 res 1024x1024 format BC5 succeeded
Transcode of image 5 level 0 res 1024x1024 format ETC1 succeeded
Transcode of image 5 level 0 res 1024x1024 format BC1 succeeded
Transcode of image 5 level 0 res 1024x1024 format BC4 succeeded
Transcode of image 5 level 0 res 1024x1024 format PVRTC1_4_OPAQUE_ONLY succeeded
Transcode of image 5 level 0 res 1024x1024 format BC7_M6_OPAQUE_ONLY succeeded
Transcode of image 5 level 0 res 1024x1024 format ETC2 succeeded
Transcode of image 5 level 0 res 1024x1024 format BC3 succeeded
Transcode of image 5 level 0 res 1024x1024 format BC5 succeeded
Wrote KTX file "cubemap_transcoded_cubemap_ETC1_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC1_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_BC1_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_BC1_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC1_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC1_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC1_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC1_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC1_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_BC4_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_BC4_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC4_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC4_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC4_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC4_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC4_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_PVRTC1_4_OPAQUE_ONLY_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_PVRTC1_4_OPAQUE_ONLY_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_BC7_M6_OPAQUE_ONLY_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC7_M6_OPAQUE_ONLY_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_ETC2_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_0_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_1_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_2_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_3_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_4_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_ETC2_5_0.png"
Wrote PNG file "cubemap_unpacked_a_ETC2_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_BC3_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_BC3_0_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC3_1_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC3_2_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC3_3_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC3_4_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC3_5_0.png"
Wrote PNG file "cubemap_unpacked_a_BC3_5_0.png"
Wrote KTX file "cubemap_transcoded_cubemap_BC5_0.ktx"
Wrote PNG file "cubemap_unpacked_rgb_BC5_0_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC5_1_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC5_2_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC5_3_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC5_4_0.png"
Wrote PNG file "cubemap_unpacked_rgb_BC5_5_0.png"
Success
However if I load one of the KTX files (e.g. cubemap_transcoded_cubemap_ETC2_0.ktx
) using libktx, ktxTexture_CreateFromNamedFile
with KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT
, libktx returns KTX_FILE_UNEXPECTED_EOF
.
On inspection it appears as if, despite “numFaces” being 6 in the KTX file, only a single face image is present in the file. Similar results are seen using ktxTexture_GLUpload
.
I have tried adding -tex_type cubemap
to the unpack call but that didn't change the output.
Output from a libktx-based tool run on cubemap_transcoded_cubemap_ETC2_0.ktx
shows the following header data. dataSize does imply there’s just one face image in the KTX.
----------------------------------------------------------------
| Field | Dec | Hex | Enum |
----------------------------------------------------------------
| glFormat | 0 | 0x0 | <unknown> |
| glInternalformat | 36196 | 0x8d64 | GL_ETC1_RGB8_OES |
| glBaseInternalformat | 6407 | 0x1907 | GL_RGB |
| glType | 0 | 0x0 | <unknown> |
| isArray | 0 | 0x0 | |
| isCubemap | 1 | 0x1 | |
| isCompressed | 1 | 0x1 | |
| generateMipmaps | 0 | 0x0 | |
| baseWidth | 1024 | 0x400 | |
| baseHeight | 1024 | 0x400 | |
| baseDepth | 1 | 0x1 | |
| numDimensions | 2 | 0x2 | |
| numLevels | 1 | 0x1 | |
| numLayers | 1 | 0x1 | |
| numFaces | 6 | 0x6 | |
| kvDataLen | 0 | 0x0 | |
| dataSize | 3145728 | 0x300000 | |
----------------------------------------------------------------
Could you either check my use of the tool, or comment on the suggestion there might be a problem with basisu generating KTX files with numFaces set to 6 but only one face image in the file.
Jim
With the nice contribution in #7 , the WASM version of the Basis Universal transcoder is now practical to deploy along with web apps and libraries. Performance measurements (thanks @austinEng) show that it's within about 50% of the performance of the native version if compiled directly into the Chrome browser.
It would be beneficial to the community if a small harness could be written which would instantiate a web worker, load the WASM module on it, and define an API on the calling thread (and associated messages back and forth to the worker) so that the transcoder can easily be invoked without blocking the main thread.
Another thing to consider is whether fetch functionality should be incorporated, so that the worker can both fetch a Basis file and transcode slices out of it on demand, without bouncing all of the Basis file's data back to the main thread. (Only the transcoded data would be, and it would be transferred.)
If I have a single-file C wrapper and a single-file C# binding for part of Basis, is that something you'd be open to having in this repo? Or would you rather just link to it wherever I have it?
Silly little thing, but our corporate firewall thinks the http://binomial.biz/TextureVideoTest/
demo is malicious because http://binomial.biz
is just a default parked domain page.
There's a few cases where it would be useful to have the transcoder output uncompressed data (similar to the output of the command line tool with -unpack
). Specifically, on systems that don't support any alpha-enabled compressed formats (unfortunately common on the web) it may be less disruptive to the existing render pipeline to choose to transcode those images to uncompressed RGBA and use that instead of restructuring the shaders to sample a separate color and alpha image on some platforms.
Obviously that's not optimal from a memory/performance perspective, and you'd get higher quality by using an uncompressed image in the first place, but it would allow more applications to fully switch over to using Basis for ~all their textures without compatibility concerns. Doing so would yield immediate benefits in terms of asset size in almost all cases, and since opaque textures are very common only a small portion of textures would need to use this path.
In addition, it could be a useful debugging tool in some situations (such as if the application's compressed texture rendering path is not functioning as expected.)
Understanding that all GPU compression formats are lossy, and so some quality reduction is always to be expected, it seems that certain textures get hit significantly harder than others, often if they heavily consist of a single color (such as red). For example, this flag from Quake 3 (live demo w/ Basis textures)
Encoding was done with the following command line to try and get maximum quality:
basisu banner_strgg.png -level 5 -max_endpoints 16128 -max_selectors 16128 -no_selector_rdo -no_endpoint_rdo
The encoding effects are best observed in the upper left of the image, especially along highlights. Is this within the expected error margin of the encoder? Obviously the source image is fairly small which undoubtedly has an effect on the perceived output quality, but I'm curious if the heavy use of a single color is also expected to have a detrimental effect here, and if there's steps that could be taken while encoding that would minimize the artifacts?
Using Draco Loader is normal for Android. It can't be displayed in apple, it can't be parsed correctly
Hello everyone, I'm trying integrate Basis Universal to my app. My data has many basis files (each basis contains many images). My approach is use only one transcoder, then call transcoder->start_transcoding (...) each time I want to get the texturefrom different Basis file but the transcoder only work with the first Basis data which i set to it via start_transcoding method.
So the question is:
Thank you for support.
What are the supported input file formats? PNG only?
No BMP?
When compressing https://github.com/KhronosGroup/glTF-Sample-Models/blob/master/2.0/FlightHelmet/glTF/FlightHelmet_baseColor.png the assertion at line 1070 in basisu_enc.h fires.
assert(node.m_var == var_heap.get_top_priority());
However if basisu is compiled without assertions the resulting file appears to be okay at least to casual inspection.
Note that the CMake build, even with CMAKE_BUILD_TYPE
set to Debug does not appear to include assertions. I verified this by adding assert(false);
just before line 1070. It doesn't fire. Only in my Xcode Debug build are asserts present.
When compressing this testcard image with -comp_level 5 -global_sel_pal -no_hybrid_sel_cb
:
The resulting output (created with -unpack
) is full of black dots in the grey areas:
The .basis
file is here: testcard.zip (it's not possible to attach without placing it in a zip). The artefacts are better with the default quality (whereby the dots become a ringing in the grey squares).
Hello. Where can I find API documentation or examples on how to use the library for importing and transcoding images? I need to do specifically 2 operations:
Thanks!
//step1 init
basisu_transcoder_init();
if (!g_pGlobal_codebook)
g_pGlobal_codebook = new basist::etc1_global_selector_codebook(g_global_selector_cb_size, g_global_selector_cb);
basisu_transcoder *m_transcoder = new basisu_transcoder(g_pGlobal_codebook);
//step2 get data from java
jbyte *bytedata = env->GetByteArrayElements(data, NULL);
jsize oldsize = env->GetArrayLength(data);
//step3 transcoding
uint32_t bytes_per_block = basis_get_bytes_per_block(cTFETC1);
uint32_t orig_width, orig_height, total_blocks;
if (!m_transcoder->get_image_level_desc(bytedata, oldsize, 0, 0, orig_width, orig_height, total_blocks))
return env->NewByteArray(0);
m_transcoder->start_transcoding(bytedata, oldsize);
//step4 output to java
uint32_t required_size = total_blocks * bytes_per_block;
jbyteArray jbarray = env->NewByteArray(required_size);
jbyte *outdata = env->GetByteArrayElements(jbarray, NULL);
//logcat : b == true
bool b = m_transcoder->transcode_image_level(bytedata, oldsize, 0, 0, outdata, required_size / bytes_per_block , cTFETC1);
return jbarray;
transcode_image_level return true, but error when i use this etc byte[]
java.io.IOException: Not a PKM file.
W/System.err: at android.opengl.ETC1Util.createTexture(ETC1Util.java:164)
W/System.err: at android.opengl.ETC1Util.loadTexture(ETC1Util.java:48)
However when i use a normal ect file, everything ok
I'd like to be able to convert existing (compressed or uncompressed) KTX files to basis files using this tool. However, it appears that the tool only accepts PNG as an input file type
Whats the difference between -q & -level options ?
From the README they both increase the quality of the output but whats their exact function and are they compatibles ?
Thanks!
Line 17 in 087198f
This MIME type is referenced in webgl/gltf/assets/AgiHqSmall.gltf - is this a strawman example or is it/will it be registered as an official MIME type?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.