load-textures.md 5.5 KB


title: Load Textures description: Add texture maps to your TresJS objects. author: alvarosabu thumbnail: /recipes/load-textures.png

difficulty: 1

Load Textures

All textures used in this example are from ambientcg.

Three-dimensional (3D) textures are images that contain multiple layers of data, allowing them to represent volume or simulate three-dimensional structures. These textures are commonly used in 3D graphics and visual effects to enhance the realism and complexity of scenes and objects.

There are two ways of loading 3D textures in TresJS:

Using useLoader

The useLoader composable allows you to pass any type of three.js loader and a URL to load the resource from. It returns a Promise with the loaded resource.

For a detailed explanation of how to use useLoader, check out the useLoader documentation.

import { useLoader } from '@tresjs/core'
import { TextureLoader } from 'three'

const { state: texture } = useLoader(TextureLoader, '/Rock035_2K_Color.jpg')

Then you can pass the texture to a material:

::: code-group

<script setup lang="ts">
import TexturedSphere from './TexturedSphere.vue'
</script>

<template>
  <TresCanvas
    clear-color="#82DBC5"
    shadows
    alpha
  >
    <TexturedSphere />
  </TresCanvas>
</template>
<script setup lang="ts">
import { useLoader } from '@tresjs/core'
import { TextureLoader } from 'three'

const { state: texture, isLoading } = useLoader(TextureLoader, '/Rock035_2K_Color.jpg')
</script>

<template>
  <TresMesh>
    <TresSphereGeometry :args="[1, 32, 32]" />
    <TresMeshStandardMaterial :map="texture" />
  </TresMesh>
</template>

:::

Using useTexture

A more convenient way of loading textures is using the useTexture composable. It provides reactive state management and supports both single textures and arrays of textures.

To learn more about useTexture, check out the useTexture documentation.

Loading a Single Texture

import { useTexture } from '@tresjs/core'

const { state: texture, isLoading } = useTexture('/textures/black-rock/Rock035_2K_Color.jpg')

Loading Multiple Textures

import { useTexture } from '@tresjs/core'

const [albedo, normal, roughness] = useTexture([
  '/textures/black-rock/Rock035_2K_Color.jpg',
  '/textures/black-rock/Rock035_2K_NormalDX.jpg',
  '/textures/black-rock/Rock035_2K_Roughness.jpg'
])

Then you can use the textures in your material:

<template>
  <TresMesh>
    <TresSphereGeometry :args="[1, 32, 32]" />
    <TresMeshStandardMaterial
      :map="albedo.state.value"
      :normal-map="normal.state.value"
      :roughness-map="roughness.state.value"
    />
    <Html transform position-y="1.5">
      <span class="text-xs bg-white p-2 rounded-md">
        {{ albedo.isLoading.value ? 'Loading...' : 'Loaded' }}
      </span>
    </Html>
  </TresMesh>
</template>

Reactive Texture Loading

The composable supports reactive paths, allowing you to change textures dynamically:

const texturePath = ref('/textures/black-rock/Rock035_2K_Color.jpg')
const { state: texture, isLoading } = useTexture(texturePath)

// Later, change the texture
texturePath.value = '/textures/hexagonal-rock/Rocks_Hexagons_002_basecolor.jpg'

Using the UseTexture Component

For a more declarative approach, you can use the UseTexture component:

<script setup lang="ts">
import { UseTexture } from '@tresjs/core'

const paths = [
  '/textures/black-rock/Rock035_2K_Color.jpg',
  '/textures/black-rock/Rock035_2K_NormalDX.jpg',
  '/textures/black-rock/Rock035_2K_Roughness.jpg'
]
</script>

<template>
  <UseTexture v-slot="{ state: textures, isLoading }" :path="paths">
    <TresMesh>
      <TresSphereGeometry :args="[1, 32, 32]" />
      <TresMeshStandardMaterial
        v-if="!isLoading"
        :map="textures[0]"
        :normal-map="textures[1]"
        :roughness-map="textures[2]"
      />
    </TresMesh>
  </UseTexture>
</template>