Skip to content

Commit

Permalink
Improve TextureHelper, show slices.
Browse files Browse the repository at this point in the history
  • Loading branch information
donmccurdy committed Sep 6, 2023
1 parent b4b6522 commit 9a5bc75
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 14 deletions.
135 changes: 125 additions & 10 deletions examples/jsm/helpers/TextureHelper.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import {
BoxGeometry,
BufferAttribute,
DoubleSide,
Mesh,
PlaneGeometry,
ShaderMaterial,
BoxGeometry
Vector3,
} from 'three';
import { mergeGeometries } from '../utils/BufferGeometryUtils.js';

class TextureHelper extends Mesh {

Expand All @@ -12,19 +17,25 @@ class TextureHelper extends Mesh {

type: 'TextureHelperMaterial',

side: DoubleSide,
transparent: true,

uniforms: {

map: { value: texture },
alpha: { value: getAlpha( texture ) },

},

vertexShader: [

'attribute vec3 uvw;',

'varying vec3 vUvw;',

'void main() {',

' vUvw = vec3( uv, 0.0 );', // TODO: Populate 'w' for cube, 3D, and array textures.
' vUvw = uvw;',

' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',

Expand All @@ -42,6 +53,8 @@ class TextureHelper extends Mesh {

'uniform {samplerType} map;',

'uniform float alpha;',

'varying vec3 vUvw;',

'vec4 textureHelper( in sampler2D map ) { return texture( map, vUvw.xy ); }',
Expand All @@ -54,17 +67,17 @@ class TextureHelper extends Mesh {

'void main() {',

' gl_FragColor = linearToOutputTexel( textureHelper( map ) );',
' gl_FragColor = linearToOutputTexel( vec4( textureHelper( map ).xyz, alpha ) );',

'}'

].join( '\n' ).replace( '{samplerType}', getSamplerType( texture ) )

} );

// TODO: Display as stack of images.
const geometry = new BoxGeometry( width, height, depth );
if ( texture.flipY === false ) flipY( geometry );
const geometry = texture.isCubeTexture
? createCubeGeometry( width, height, depth )
: createSliceGeometry( texture, width, height, depth );

super( geometry, material );

Expand Down Expand Up @@ -104,19 +117,121 @@ function getSamplerType( texture ) {

}

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

if ( texture.isCubeTexture ) {

return 6;

} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {

return texture.image.depth;

} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {

return texture.image.depth;

} else {

return 1;

}

}

function getAlpha( texture ) {

if ( texture.isCubeTexture ) {

return 1;

} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {

return Math.max( 1 / texture.image.depth, 0.25 );

} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {

return Math.max( 1 / texture.image.depth, 0.25 );

} else {

return 1;

}

}

function createCubeGeometry( width, height, depth ) {

const geometry = new BoxGeometry( width, height, depth );

const position = geometry.attributes.position;
const uv = geometry.attributes.uv;
const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );

const _direction = new Vector3();

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

uv.setY( i, 1 - uv.getY( i ) );
_direction.fromBufferAttribute( position, j ).normalize();

const u = _direction.x;
const v = _direction.y;
const w = _direction.z;

uvw.setXYZ( j, u, v, w );

}

geometry.deleteAttribute( 'uv' );
geometry.setAttribute( 'uvw', uvw );

return geometry;

}

function createSliceGeometry( texture, width, height, depth ) {

const sliceCount = getImageCount( texture );

const geometries = [];

for ( let i = 0; i < sliceCount; ++ i ) {

const geometry = new PlaneGeometry( width, height );

if ( sliceCount > 1 ) {

geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );

}

const uv = geometry.attributes.uv;
const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );

for ( let j = 0, jl = uv.count; j < jl; ++ j ) {

const u = uv.getX( j );
const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
const w = sliceCount === 1
? 1
: texture.isDataArrayTexture || texture.isCompressedArrayTexture
? i
: i / ( sliceCount - 1 );

uvw.setXYZ( j, u, v, w );

}

geometry.deleteAttribute( 'uv' );
geometry.setAttribute( 'uvw', uvw );

geometries.push( geometry );

}

return mergeGeometries( geometries );

}

export { TextureHelper };
12 changes: 10 additions & 2 deletions examples/jsm/loaders/KTX2Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ async function createRawTexture( container ) {

if ( container.faceCount === 6 ) {

texture = new DataCubeTexture( mipmaps );
texture = new DataCubeTexture( mipmaps[ 0 ].data, container.pixelWidth, container.pixelHeight );

} else if ( container.layerCount > 1 ) {

Expand Down Expand Up @@ -905,7 +905,15 @@ async function createRawTexture( container ) {

}

texture.mipmaps = mipmaps;
if ( texture.isDataCubeTexture ) {

texture.mipmaps = mipmaps.map( ( mip ) => new DataCubeTexture( mip.data, mip.width, mip.height ) );

} else {

texture.mipmaps = mipmaps;

}

texture.type = TYPE_MAP[ vkFormat ];
texture.format = FORMAT_MAP[ vkFormat ];
Expand Down
4 changes: 4 additions & 0 deletions examples/webgl_loader_texture_ktx2.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,16 @@
'3D / RGBA32 LUT': '3d_rgba32_lut.ktx2',

// Cube
'Cube / BasisU ETC1S': 'cubemap_etc1s.ktx2',
'Cube / BasisU UASTC': 'cubemap_uastc.ktx2',
'Cube / RGBA8 sRGB': 'cubemap_rgba8.ktx2',
'Cube / RGBA8 Linear': 'cubemap_rgba8_linear.ktx2',
'Cube / RGBA16 Linear': 'cubemap_rgba16_linear.ktx2',
'Cube / RGBA32 Linear': 'cubemap_rgba32_linear.ktx2',

// Array
'Array / BasisU ETC1S': 'array_etc1s.ktx2',
'Array / BasisU UASTC': 'array_uastc.ktx2',
'Array / RGBA8 sRGB': 'array_rgba8.ktx2',
'Array / RGBA8 Linear': 'array_rgba8_linear.ktx2',
'Array / RGBA16 Linear': 'array_rgba16_linear.ktx2',
Expand Down
4 changes: 2 additions & 2 deletions src/textures/DataCubeTexture.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { CubeReflectionMapping } from '../constants.js';

class DataCubeTexture extends Texture {

constructor( data ) {
constructor( data, width, height ) {

super( data, CubeReflectionMapping );

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

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

this.generateMipmaps = false;
this.flipY = false;
Expand Down

0 comments on commit 9a5bc75

Please sign in to comment.