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
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
@@ -16,8 +16,10 @@ import {
CompressedTexture,
CompressedArrayTexture,
CompressedCubeTexture,
Data3DTexture,
DataArrayTexture,
DataCubeTexture,
DataTexture,
Data3DTexture,
FileLoader,
FloatType,
HalfFloatType,
@@ -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 );
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
@@ -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',
@@ -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 = {
@@ -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 );
@@ -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 }` );
@@ -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>
1 change: 1 addition & 0 deletions src/Three.core.js
Original file line number Diff line number Diff line change
@@ -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';
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 };