I created a simple 3D scene written in JavaScript. The scene renders a THREE.SphereGeometry
with a THREE.MeshNormalMaterial
. The only thing I need is a text layer located over Three.js
scene.
Question
: How to place a 2D text over rendered Three.js scene?
<html>
<head>
<title>First page.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="/errordocs/style/general.css" rel="stylesheet" type="text/css">
<script src=".js" crossorigin="anonymous"></script>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script>
var scene, camera, renderer;
var geometry, material, mesh;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 100 );
camera.position.z = 1;
geometry = new THREE.SphereGeometry( 0.1, 20, 20 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
</script>
</body>
</html>
I created a simple 3D scene written in JavaScript. The scene renders a THREE.SphereGeometry
with a THREE.MeshNormalMaterial
. The only thing I need is a text layer located over Three.js
scene.
Question
: How to place a 2D text over rendered Three.js scene?
<html>
<head>
<title>First page.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="/errordocs/style/general.css" rel="stylesheet" type="text/css">
<script src="https://threejs/build/three.js" crossorigin="anonymous"></script>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script>
var scene, camera, renderer;
var geometry, material, mesh;
init();
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x222222 );
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 100 );
camera.position.z = 1;
geometry = new THREE.SphereGeometry( 0.1, 20, 20 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
</script>
</body>
</html>
Share
Improve this question
edited Aug 30, 2023 at 17:49
Andy Jazz
asked Oct 19, 2020 at 8:02
Andy JazzAndy Jazz
58.6k18 gold badges160 silver badges254 bronze badges
1
- 2 Hey, sorry, I thought that was your problem, that the code does not work. My mistake. Feel free to revert it back if you want, or even better → make it work. An executable snippet is a good way to get more answers. – MauriceNino Commented Oct 19, 2020 at 8:19
3 Answers
Reset to default 6There is more than one way to achieve the intended result.
For most cases, using THREE.CSS2DRenderer as a label or annotation renderer gives proper results. The good thing is that you can easily style your texts with CSS. The renderer is used e.g. in this example: https://threejs/examples/css2d_label
Another way is to render text on a canvas and then use it as a texture for an instance of THREE.Sprite. Using sprites makes it possible to blend or hide labels behind other 3D objects which does not work with a HTML/CSS based solution.
I know you specifically asked for 2D text but for 3D text you could use TextGeometry to generate a mesh.
I've chosen THREE.TextSprite solution. It's as simple as that:
import TextSprite from '@seregpie/three.text-sprite';
let sprite = new THREE.TextSprite( {
text: 'Text must be rendered here...',
alignment: 'center',
fontFamily: 'Arial, Helvetica, sans-serif',
fontSize: 28,
color: '#ffffff' } );
scene.add(sprite);
If you're using React
, you can use the Text
ponent from @react-three/drei
import { Text } from '@react-three/drei'
<Text
scale={[4, 4, 4]}
color="black"
anchorX="center"
anchorY="bottom"
position={[0, 0, 0]}
rotation={[0, 0, 0]}
>
Your Text
</Text>