Three.js gltf loader strange behavior when trying to add 3D text

The idea was to load the prebuilt gltf scene made in Blender. Then to add some 3D text using ttf loader and manipulate it. I tried to use a code from examples and each loader works perfectly when I use them separately. But when I combine them into a single script really strange stuff starts happening. When I add a gltf scene first and after that, I add 3D text, the text magically disappears. Console says nothing. I tried to change the order of loading. When I load text after gltf, the content of gltf disappears and the only text stays visible. Screenshot.
Console says:

three.module.js:16177 Uncaught TypeError: Cannot read property 'type' of undefined
    at WebGLIndexedBufferRenderer.setIndex (three.module.js:16177)
    at WebGLRenderer.renderBufferDirect (three.module.js:23910)
    at renderObject (three.module.js:24601)
    at renderObjects (three.module.js:24571)
    at WebGLRenderer.render (three.module.js:24350)
    at render (main.js:73)
    at onAnimationFrame (<anonymous>:116:3)
    at <anonymous>:85:5

By excluding one-by-one item I figured out that this happens only when there’s more than one 3D geometry object in gltf. When there’s only one geometry object in gltf everything works fine. I suggest there’s something with the internal order of the objects, but have no idea how to fix this. Can someone explain to me what did I do wrong?
Here’s the code:

import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
import * as THREE from './libs/three.module.js';
import { TTFLoader } from './jsm/loaders/TTFLoader.js';

var container;
var camera, cameraTarget, scene, renderer;
var mixer;
var clock = new THREE.Clock();

var group, textMesh1, textGeo, material;
var firstLetter = false;
var text = 'ttf',
    height = 0,
    size = 1,
    hover = 0,
    curveSegments = 4,
    bevelThickness = .1,
    bevelSize = 0;
var font = null;

container = document.createElement( 'div' );
document.body.appendChild( container );

scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1500 );
camera.position.set( 0, -10, 10 );
cameraTarget = new THREE.Vector3( 0, 0, 0 );
camera.lookAt( cameraTarget );
scene.add( camera );

var loader = new GLTFLoader();
//loader.load( './text.gltf' , function ( gltf ) { //this one works fine
loader.load( './text+cube.gltf' , function ( gltf ) { //this one acts very strange
    scene.add( gltf.scene );

var material = new THREE.MeshPhongMaterial({'color': '#cece00'});
var loader2 = new TTFLoader();
loader2.load( 'fonts/ttf/kenpixel.ttf', function ( json ) {
    font = new THREE.Font( json );
} );

var pointLight = new THREE.PointLight( 0xffffff, 2 );
pointLight.position.set( 0, -50, 90 );
scene.add( pointLight );

renderer = new THREE.WebGLRenderer( { antialias: true} );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false ); 

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize( window.innerWidth, window.innerHeight );

function render() {
    var delta = clock.getDelta();
    if (mixer != null) {mixer.update(delta);};
    renderer.render(scene, camera);

function createText() {
    textGeo = new THREE.TextBufferGeometry( text, {
        font: font,
        size: size,
        height: height,
        curveSegments: curveSegments,
        bevelThickness: bevelThickness,
        bevelSize: bevelSize,
        bevelEnabled: true
    } );

    var centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
    textMesh1 = new THREE.Mesh( textGeo, material );
    textMesh1.position.x = centerOffset;
    textMesh1.position.y = hover;
    textMesh1.position.z = 0;
    textMesh1.rotation.x = 0;
    textMesh1.rotation.y = 0;
    scene.add( textMesh1 );
<!DOCTYPE html>
    <style type="text/css">
        html, body {margin: 0; padding: 0; overflow: hidden}

    <script src="/libs/opentype.min.js"></script>
    <script src="./main.js" type="module"></script>

Full project with all dependencies is here

Can’t guarantee this is the cause, but you’re importing libs/three.module.js while GLTFLoader and TTFLoader both depend on the copy in build/three.module.js. That means you’ll have two copies of three.js on the page, and are adding objects loaded by one to a Scene created by the other, which could lead to lots of weird issues. Try importing THREE from build/ instead?

1 Like

Problem solved! Thank you very much!