Skip to content
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

(WIP) KTX2Loader: Return DataTexture when transcoding to uncompressed format #29926

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 38 additions & 8 deletions examples/jsm/loaders/KTX2Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import {
CompressedTexture,
CompressedArrayTexture,
CompressedCubeTexture,
Data3DTexture,
DataArrayTexture,
DataCubeTexture,
DataTexture,
Data3DTexture,
FileLoader,
FloatType,
HalfFloatType,
Expand Down Expand Up @@ -294,25 +296,53 @@ class KTX2Loader extends Loader {

if ( messageType === 'error' ) return Promise.reject( error );

const mipmaps = faces[ 0 ].mipmaps;

let texture;

if ( container.faceCount === 6 ) {
if ( format === RGBAFormat ) {

// THREE.DataTexture

if ( container.faceCount === 6 ) {

texture = new DataCubeTexture( mipmaps[ 0 ].data, format, type );
texture.mipmaps = mipmaps.map( ( mip ) => new DataCubeTexture( mip.data, mip.width, mip.height ) );

} else if ( container.layerCount > 1 ) {

texture = new DataArrayTexture( mipmaps[ 0 ].data, width, height, container.layerCount, format, type )
texture.mipmaps = mipmaps;

} else {

texture = new CompressedCubeTexture( faces, format, type );
texture = new DataTexture( mipmaps[ 0 ].data, width, height, format, type );
texture.mipmaps = mipmaps;

}

} else {

const mipmaps = faces[ 0 ].mipmaps;
// THREE.CompressedTexture

if ( container.faceCount === 6 ) {

texture = new CompressedCubeTexture( faces, format, type );

} else if ( container.layerCount > 1 ) {

texture = container.layerCount > 1
? new CompressedArrayTexture( mipmaps, width, height, container.layerCount, format, type )
: new CompressedTexture( mipmaps, width, height, format, type );
texture = new CompressedArrayTexture( mipmaps, width, height, container.layerCount, format, type )

} else {

texture = new CompressedTexture( mipmaps, width, height, format, type );

}

}

texture.minFilter = faces[ 0 ].mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
texture.magFilter = LinearFilter;
texture.generateMipmaps = false;

texture.needsUpdate = true;
texture.colorSpace = parseColorSpace( container );
Expand Down
Binary file added examples/textures/compressed/cubemap_etc1s.ktx2
Binary file not shown.
Binary file added examples/textures/compressed/cubemap_uastc.ktx2
Binary file not shown.
44 changes: 16 additions & 28 deletions examples/webgl_loader_texture_ktx2.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@

import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { TextureHelper } from 'three/addons/helpers/TextureHelper.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

let camera, scene, renderer, controls, loader, material;
let camera, scene, renderer, controls, loader, helper;

const SAMPLES = {
'BasisU ETC1S': '2d_etc1s.ktx2',
Expand All @@ -43,6 +44,10 @@
'RGBA16 Linear (UASTC HDR)': '2d_rgba16_uastc_hdr_linear.ktx2',
'RGBA32 Linear': '2d_rgba32_linear.ktx2',
'ASTC 6x6 (mobile)': '2d_astc_6x6.ktx2',

// Cube
'Cube / BasisU ETC1S': 'cubemap_etc1s.ktx2',
'Cube / BasisU UASTC': 'cubemap_uastc.ktx2',
};

const FORMAT_LABELS = {
Expand Down Expand Up @@ -99,16 +104,6 @@

controls = new OrbitControls( camera, renderer.domElement );

// PlaneGeometry UVs assume flipY=true, which compressed textures don't support.
const geometry = flipY( new THREE.PlaneGeometry() );
material = new THREE.MeshBasicMaterial( {
color: 0xFFFFFF,
side: THREE.DoubleSide,
transparent: true,
} );
const mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

loader = new KTX2Loader()
.setTranscoderPath( 'jsm/libs/basis/' )
.detectSupport( renderer );
Expand Down Expand Up @@ -149,9 +144,17 @@
const texture = await loader.loadAsync( `./textures/compressed/${path}` );
texture.minFilter = THREE.NearestMipmapNearestFilter;

material.map = texture;
material.needsUpdate = true;
if ( helper ) {

scene.remove( helper );
helper.dispose();

}

helper = new TextureHelper( texture );
scene.add( helper );

console.info( `class: ${ texture.constructor.name }` );
console.info( `format: ${ FORMAT_LABELS[ texture.format ] }` );
console.info( `type: ${ TYPE_LABELS[ texture.type ] }` );
console.info( `colorSpace: ${ texture.colorSpace }` );
Expand All @@ -167,21 +170,6 @@

}

/** Correct UVs to be compatible with `flipY=false` textures. */
function flipY( geometry ) {

const uv = geometry.attributes.uv;

for ( let i = 0; i < uv.count; i ++ ) {

uv.setY( i, 1 - uv.getY( i ) );

}

return geometry;

}

</script>

</body>
Expand Down
1 change: 1 addition & 0 deletions src/Three.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export { FramebufferTexture } from './textures/FramebufferTexture.js';
export { Source } from './textures/Source.js';
export { DataTexture } from './textures/DataTexture.js';
export { DataArrayTexture } from './textures/DataArrayTexture.js';
export { DataCubeTexture } from './textures/DataCubeTexture.js';
export { Data3DTexture } from './textures/Data3DTexture.js';
export { CompressedTexture } from './textures/CompressedTexture.js';
export { CompressedArrayTexture } from './textures/CompressedArrayTexture.js';
Expand Down
35 changes: 35 additions & 0 deletions src/textures/DataCubeTexture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Texture } from './Texture.js';
import { CubeReflectionMapping } from '../constants.js';

class DataCubeTexture extends Texture {

constructor( data, width, height ) {

super( data, CubeReflectionMapping );

this.isDataCubeTexture = true;
this.isCubeTexture = true;

this.image = { data: data, width: width, height: height };

this.generateMipmaps = false;
this.flipY = false;
this.unpackAlignment = 1;

}

get images() {

return this.image;

}

set images( value ) {

this.image = value;

}

}

export { DataCubeTexture };