react-three/fiber creating 3D text
Asked Answered
S

2

6

I'm trying to create 3d text using Threejs + react-three/fiber . I loaded the font using font loader like this :

const font = new FontLoader().parse('/Microsoft Tai Le_Regular.json');

After that I tried to use component inside the mesh , for some reason it didn't work, any other type of Geometry would work .

<mesh>
  <!--  This can't even be compiled (maybe it has to do with typescript) -->
  <textGeometry />
</mesh>

With that problem , I tried to create the textGeometry on js instead of jsx So I did this :

const textOptions = {
  font: font,
  size: props.size,
  height: props.height,
  curveSegments: 12,
  bevelEnabled: true,
  bevelThickness: 10,
  bevelSize: 8,
  bevelOffset: 0,
  bevelSegments: 5
};
  
const textGeo = new TextGeometry(props.text, textOptions);

and Passed 'textGeo' to mesh geometry prop:

<mesh geometry={textGeo}>

But it still didn't work and gave this error : can't access property "yMax", data.boundingBox is undefined

Thanks for your help,

Shauna answered 13/2, 2022 at 22:40 Comment(0)
S
10

So I'll preface this by saying that I'm still a student so I can't explain exactly why all these steps need to be done but here's what worked for me. It seems that your issue is with the path that you are using to parse. The file name itself seems inaccurate but even if the file path is valid, it still will not work, it must be imported. Make sure that your json file is inside of your src folder and import the json file using the relative path.

import myFont from '../relative_path'

Make sure to import extend from r3f

import { extend } from '@react-three/fiber'

Next, textGeometry does not come standard with r3f, so it needs to be imported like so

import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'

Then extend TextGeometry

extend({ TextGeometry })

This should work to get the textgeometry to compile. Take a look below for the full snippet.

import { extend } from '@react-three/fiber'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry'
import myFont from '../relative_path'

extend({ TextGeometry })

export default function Text() {
const font = new FontLoader().parse(myFont);

return(
<mesh position={[0,10,0]}>
    <textGeometry args={['test', {font, size:5, height: 1}]}/>
    <meshLambertMaterial attach='material' color={'gold'}/>
</mesh>
)

}

Obviously you can change the args and material to fit your needs.

Sacrarium answered 15/2, 2022 at 17:55 Comment(2)
thanks man , the font import solved the err problem , but the jsx textGeo problem is still there after extend ( it doesn't matter anyways ) . and about the results , it's random 2d shape colored with the ambient light color i used I played with the numbers but didn't seem to get anywhere close to 3d text ...Shauna
TextGeometry is not part of threejs, they have removed it. Now it lives in the examples folder, that's the reason it's not working ootb without extend, r3f has no knowledge of what threejs is, it translates jsx into three runtime by looking into its namespace + the extended namespace.Safranine
H
7

For anyone who is using Typescript and gets a
"Property 'textGeometry' does not exist on type 'JSX.IntrinsicElements'" error, here is how to fix that:

import { extend, Object3DNode } from "@react-three/fiber";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
extend({ TextGeometry });

declare module "@react-three/fiber" {
  interface ThreeElements {
    textGeometry: Object3DNode<TextGeometry, typeof TextGeometry>;
  }
}

This type textGeometry and attach it to the global JSX namespace.
Source:
https://docs.pmnd.rs/react-three-fiber/tutorials/typescript#extending-threeelements

Heterodoxy answered 1/4, 2023 at 9:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.