The useTexture
composable allows you to load textures using the THREE.js texture loader. This composable provides a convenient way to load single or multiple textures with built-in loading state management.
import { useTexture } from '@tresjs/core'
const { data: texture } = useTexture('path/to/texture.png')
const { data: textures } = useTexture([
'path/to/albedo.png',
'path/to/normal.png',
'path/to/roughness.png'
])
// Access individual textures
const [albedo, normal, roughness] = textures.value
The composable can be awaited directly, making it compatible with Vue's Suspense component:
// In an async setup function
const { data: texture } = await useTexture('path/to/texture.png')
You can provide a THREE.js LoadingManager to track loading progress across multiple resources:
import { LoadingManager } from 'three'
const manager = new LoadingManager()
manager.onProgress = (url, loaded, total) => {
console.log(`Loading ${url}: ${loaded} of ${total} files.`)
}
const { data: texture } = useTexture('path/to/texture.png', manager)
The composable provides reactive references for tracking loading state:
const { data: texture, isLoading, error } = useTexture('path/to/texture.png')
watch(isLoading, (value) => {
if (value) {
console.log('Texture is loading...')
}
})
watch(error, (value) => {
if (value) {
console.error('Error loading texture:', value)
}
})
const { data: texture, load } = useTexture('path/to/initial-texture.png')
// Later, load a different texture
const newTexture = await load('path/to/new-texture.png')
// Or load multiple textures
const newTextures = await load([
'path/to/texture1.png',
'path/to/texture2.png'
])
const { data: textures } = useTexture([
'textures/wood/albedo.jpg',
'textures/wood/normal.jpg',
'textures/wood/roughness.jpg',
'textures/wood/ao.jpg'
])
// In your setup function
const material = computed(() => {
if (!textures.value) { return null }
const [albedo, normal, roughness, ao] = textures.value
return {
map: albedo,
normalMap: normal,
roughnessMap: roughness,
aoMap: ao
}
})
const { data: envMap } = useTexture('textures/environment.hdr')
// Use with a scene or material
const scene = computed(() => {
if (envMap.value) {
return {
background: envMap.value,
environment: envMap.value
}
}
return {}
})
const { data: atlas } = useTexture('textures/sprite-atlas.png')
// Configure texture for sprite use
watchEffect(() => {
if (atlas.value) {
atlas.value.wrapS = atlas.value.wrapT = THREE.RepeatWrapping
atlas.value.repeat.set(1 / 8, 1 / 8) // For an 8x8 grid
}
})
Parameter | Type | Description |
---|---|---|
path |
string \| string[] |
Path or array of paths to texture file(s) |
manager |
LoadingManager |
Optional THREE.js LoadingManager |
Property | Type | Description |
---|---|---|
data |
Ref<Texture \| Texture[] \| null> |
The loaded texture(s) |
isLoading |
Ref<boolean> |
Whether the texture is currently loading |
error |
Ref<Error \| null> |
Any error that occurred during loading |
promise |
Promise<Texture \| Texture[]> |
Promise that resolves when the texture is loaded |
load |
Function |
Method to manually load texture(s) |
shallowRef
for better performance when dealing with complex THREE.js objects.error
ref.The UseTexture
component provides a slot-based API for loading textures directly in your template:
<script setup lang="ts">
import { UseTexture } from '@tresjs/core'
const paths = [
'textures/black-rock/color.jpg',
'textures/black-rock/displacement.jpg',
]
</script>
<template>
<UseTexture v-slot="{ data: texture }" :path="paths">
<TresMesh :position="[-3, 1, 0]">
<TresSphereGeometry :args="[1, 32, 32]" />
<TresMeshStandardMaterial
v-if="texture"
:map="texture[0]"
:displacement-map="texture[1]"
:displacement-scale="0.1"
/>
</TresMesh>
</UseTexture>
</template>
The component provides the loaded texture(s) through its default slot prop. This approach is particularly useful when:
The slot provides the same properties as the composable (data
, isLoading
, error
).