@threlte/extras
<MeshRefractionMaterial>
To use this component you need to install the seperate library three-mesh-bvh
, please run npm install three-mesh-bvh
before adding this component to your project.
This material may not work reliably on some devices or browsers. We’re investigating possible fixes.
This component is a port of drei’s <MeshRefractionMaterial>
component, a convincing Glass/Diamond refraction material.
<script lang="ts">
import { Canvas } from '@threlte/core'
import Scene from './Scene.svelte'
</script>
<div>
<Canvas>
<Scene />
</Canvas>
</div>
<style>
div {
height: 100%;
}
</style>
<script lang="ts">
import { Mesh } from 'three'
import { T, useLoader } from '@threlte/core'
import { useGltf, MeshRefractionMaterial } from '@threlte/extras'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
let { ...props } = $props()
type GLTFResult = {
nodes: {
Diamond_1_0: Mesh
}
materials: {}
}
const gltf = useGltf<GLTFResult>('/models/diamond/dflat.glb', { useDraco: true })
const env = useLoader(RGBELoader).load('/hdr/aerodynamics_workshop_1k.hdr')
</script>
{#await gltf then { nodes }}
<T.Mesh
castShadow
receiveShadow
geometry={nodes.Diamond_1_0.geometry}
{...props}
>
{#await env then e}
<MeshRefractionMaterial
envMap={e}
fresnel={0.5}
ior={2.75}
aberrationStrength={0.04}
bounces={3}
color={'#ffdddd'}
/>
{/await}
</T.Mesh>
{/await}
<script lang="ts">
import { T } from '@threlte/core'
import { OrbitControls, Grid, Float } from '@threlte/extras'
import Diamond from './Diamond.svelte'
</script>
<Float
floatIntensity={5}
rotationIntensity={1}
rotationSpeed={[0, 0, 0]}
>
<Diamond
scale={3}
position.y={2}
/>
</Float>
<T.PerspectiveCamera
makeDefault
position.y={7}
position.z={-8}
fov={90}
>
<OrbitControls
enableDamping
autoRotate
enablePan={false}
enableZoom={false}
/>
</T.PerspectiveCamera>
<Grid
cellColor={'#46536b'}
sectionThickness={0}
infiniteGrid
cellSize={5}
/>
Examples
Basic Example
You can either pass in a texture to use as the environment:
RefractionWithTexture.svelte
<script lang="ts">
import { T, useLoader } from '@threlte/core'
import { MeshRefractionMaterial } from '@threlte/extras'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
const env = useLoader(RGBELoader).load('/hdr/aerodynamics_workshop_1k.hdr')
</script>
{#await env then texture}
<T.Mesh>
<MeshRefractionMaterial envMap={texture} />
<T.IcosahedronGeometry args={[4, 0]} />
</T.Mesh>
{/await}
or you can use a cube camera to generate the environment:
RefractionWithCubeCamera.svelte
<script lang="ts">
import { T, useThrelte, useTask } from '@threlte/core'
import { MeshRefractionMaterial } from '@threlte/extras'
import { WebGLCubeRenderTarget, CubeCamera } from 'three'
let renderTarget: WebGLCubeRenderTarget = new WebGLCubeRenderTarget(128)
let cubeCamera: CubeCamera = new CubeCamera(0.1, 100, renderTarget)
const { scene, renderer } = useThrelte()
useTask(() => {
if (cubeCamera) {
cubeCamera.update(renderer, scene)
}
})
</script>
<T.Mesh>
<MeshRefractionMaterial envMap={renderTarget.texture} />
<T.IcosahedronGeometry args={[4, 0]} />
</T.Mesh>
Component Signature
<MeshRefractionMaterial>
extends
<T.ShaderMaterial>
and supports all its props, slot props, bindings and events.