Skip to content

Commit b4b6522

Browse files
committed
Add TextureHelper.
1 parent 99fd5d6 commit b4b6522

10 files changed

+139
-42
lines changed

examples/jsm/helpers/TextureHelper.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import {
2+
Mesh,
3+
ShaderMaterial,
4+
BoxGeometry
5+
} from 'three';
6+
7+
class TextureHelper extends Mesh {
8+
9+
constructor( texture, width = 1, height = 1, depth = 1 ) {
10+
11+
const material = new ShaderMaterial( {
12+
13+
type: 'TextureHelperMaterial',
14+
15+
uniforms: {
16+
17+
map: { value: texture },
18+
19+
},
20+
21+
vertexShader: [
22+
23+
'varying vec3 vUvw;',
24+
25+
'void main() {',
26+
27+
' vUvw = vec3( uv, 0.0 );', // TODO: Populate 'w' for cube, 3D, and array textures.
28+
29+
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
30+
31+
'}',
32+
33+
].join( '\n' ),
34+
35+
fragmentShader: [
36+
37+
'precision highp float;',
38+
39+
'precision highp sampler2DArray;',
40+
41+
'precision highp sampler3D;',
42+
43+
'uniform {samplerType} map;',
44+
45+
'varying vec3 vUvw;',
46+
47+
'vec4 textureHelper( in sampler2D map ) { return texture( map, vUvw.xy ); }',
48+
49+
'vec4 textureHelper( in sampler2DArray map ) { return texture( map, vUvw ); }',
50+
51+
'vec4 textureHelper( in sampler3D map ) { return texture( map, vUvw ); }',
52+
53+
'vec4 textureHelper( in samplerCube map ) { return texture( map, vUvw ); }',
54+
55+
'void main() {',
56+
57+
' gl_FragColor = linearToOutputTexel( textureHelper( map ) );',
58+
59+
'}'
60+
61+
].join( '\n' ).replace( '{samplerType}', getSamplerType( texture ) )
62+
63+
} );
64+
65+
// TODO: Display as stack of images.
66+
const geometry = new BoxGeometry( width, height, depth );
67+
if ( texture.flipY === false ) flipY( geometry );
68+
69+
super( geometry, material );
70+
71+
this.texture = texture;
72+
this.type = 'TextureHelper';
73+
74+
}
75+
76+
dispose() {
77+
78+
this.geometry.dispose();
79+
this.material.dispose();
80+
81+
}
82+
83+
}
84+
85+
function getSamplerType( texture ) {
86+
87+
if ( texture.isCubeTexture ) {
88+
89+
return 'samplerCube';
90+
91+
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
92+
93+
return 'sampler2DArray';
94+
95+
} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
96+
97+
return 'sampler3D';
98+
99+
} else {
100+
101+
return 'sampler2D';
102+
103+
}
104+
105+
}
106+
107+
/** Correct UVs to be compatible with `flipY=false` textures. */
108+
function flipY( geometry ) {
109+
110+
const uv = geometry.attributes.uv;
111+
112+
for ( let i = 0; i < uv.count; i ++ ) {
113+
114+
uv.setY( i, 1 - uv.getY( i ) );
115+
116+
}
117+
118+
return geometry;
119+
120+
}
121+
122+
export { TextureHelper };

examples/jsm/loaders/KTX2Loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ async function createRawTexture( container ) {
867867

868868
if ( container.faceCount === 6 ) {
869869

870-
texture = new DataCubeTexture( mipmaps[ 0 ].data );
870+
texture = new DataCubeTexture( mipmaps );
871871

872872
} else if ( container.layerCount > 1 ) {
873873

29.7 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
94.4 KB
Binary file not shown.
Binary file not shown.
72.7 KB
Binary file not shown.

examples/webgl_loader_texture_ktx2.html

Lines changed: 16 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@
3333

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

38-
let camera, scene, renderer, controls, loader, plane, cube, material;
39+
let camera, scene, renderer, controls, loader, helper;
3940

4041
const SAMPLES = {
4142
// 2D
@@ -48,6 +49,15 @@
4849
'2D / RGBA32 Linear': '2d_rgba32_linear.ktx2',
4950
'2D / ASTC 6x6 (mobile)': '2d_astc_6x6.ktx2',
5051

52+
// 3D
53+
'3D / BasisU ETC1S': '3d_etc1s.ktx2',
54+
'3D / BasisU UASTC': '3d_uastc.ktx2',
55+
'3D / RGBA8 sRGB': '3d_rgba8.ktx2',
56+
'3D / RGBA8 Linear': '3d_rgba8_linear.ktx2',
57+
'3D / RGBA16 Linear': '3d_rgba16_linear.ktx2',
58+
'3D / RGBA32 Linear': '3d_rgba32_linear.ktx2',
59+
'3D / RGBA32 LUT': '3d_rgba32_lut.ktx2',
60+
5161
// Cube
5262
'Cube / RGBA8 sRGB': 'cubemap_rgba8.ktx2',
5363
'Cube / RGBA8 Linear': 'cubemap_rgba8_linear.ktx2',
@@ -104,7 +114,6 @@
104114
window.addEventListener( 'resize', onWindowResize );
105115

106116
scene = new THREE.Scene();
107-
scene.background = new THREE.Color( 0x202020 );
108117

109118
camera = new THREE.PerspectiveCamera( 60, width / height, 0.1, 100 );
110119
camera.position.set( 0, 0, 2.5 );
@@ -113,20 +122,6 @@
113122

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

116-
// Default UVs assume flipY=true, which compressed textures don't support.
117-
const planeGeometry = flipY( new THREE.PlaneGeometry() );
118-
const cubeGeometry = flipY( new THREE.BoxGeometry() );
119-
material = new THREE.MeshBasicMaterial( {
120-
color: 0xFFFFFF,
121-
side: THREE.DoubleSide,
122-
transparent: true,
123-
} );
124-
plane = new THREE.Mesh( planeGeometry, material );
125-
cube = new THREE.Mesh( cubeGeometry, material );
126-
cube.visible = false;
127-
scene.add( plane );
128-
scene.add( cube );
129-
130125
loader = new KTX2Loader()
131126
.setTranscoderPath( 'jsm/libs/basis/' )
132127
.detectSupport( renderer );
@@ -169,19 +164,15 @@
169164
texture.minFilter = THREE.NearestMipmapNearestFilter;
170165
texture.needsUpdate = true;
171166

172-
if ( path.startsWith( 'cube' ) ) {
167+
if ( helper ) {
173168

174-
texture.mapping = THREE.CubeUVReflectionMapping;
169+
scene.remove( helper );
170+
helper.dispose();
175171

176172
}
177173

178-
scene.background = null;
179-
180-
material.map = texture;
181-
material.needsUpdate = true;
182-
183-
plane.visible = path.startsWith( '2d' );
184-
cube.visible = path.startsWith( 'cube' ) || path.startsWith( 'array' );
174+
helper = new TextureHelper( texture );
175+
scene.add( helper );
185176

186177
console.info( `class: ${ texture.constructor.name }` );
187178
console.info( `format: ${ FORMAT_LABELS[ texture.format ] }` );
@@ -196,22 +187,6 @@
196187

197188
// NOTE: Call `loader.dispose()` when finished loading textures.
198189

199-
200-
}
201-
202-
/** Correct UVs to be compatible with `flipY=false` textures. */
203-
function flipY( geometry ) {
204-
205-
const uv = geometry.attributes.uv;
206-
207-
for ( let i = 0; i < uv.count; i ++ ) {
208-
209-
uv.setY( i, 1 - uv.getY( i ) );
210-
211-
}
212-
213-
return geometry;
214-
215190
}
216191

217192
</script>

0 commit comments

Comments
 (0)