简体   繁体   English

尝试添加 3D 文本时 Three.js gltf 加载器的奇怪行为

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

The idea was to load the prebuilt gltf scene made in Blender.这个想法是加载在 Blender 中制作的预构建 gltf 场景。 Then to add some 3D text using ttf loader and manipulate it.然后使用 ttf 加载器添加一些 3D 文本并对其进行操作。 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.当我先添加 gltf 场景,然后添加 3D 文本时,文本神奇地消失了。 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.当我在 gltf 之后加载文本时,gltf 的内容消失,唯一的文本保持可见。 Screenshot:截屏:

奇怪的 gltf 加载器行为

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.通过逐一排除项目,我发现只有当 gltf 中有多个 3D 几何对象时才会发生这种情况。 When there's only one geometry object in gltf everything works fine.当 gltf 中只有一个几何对象时,一切正常。 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 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 );
camera.zoom=1.5;
cameraTarget = new THREE.Vector3( 0, 0, 0 );
camera.lookAt( cameraTarget );
scene.add( camera );
camera.updateProjectionMatrix();



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 );
    createText();
} );



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 ); 
render();

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

function render() {
    requestAnimationFrame(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
    } );

    textGeo.computeBoundingBox();
    textGeo.computeVertexNormals();
    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 );
}

html: html:

<!DOCTYPE html>
<html>
<head>
    <title>!!!TEST!!!</title>
    <style type="text/css">
        html, body {margin: 0; padding: 0; overflow: hidden}
    </style>


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

project files 项目文件

Solved!解决了! I imported from libs/three.module.js while GLTFLoader and TTFLoader both depend on the copy in build/three.module.js.我从 libs/three.module.js 导入,而 GLTFLoader 和 TTFLoader 都依赖于 build/three.module.js 中的副本。 Replaced已更换

import * as THREE from './libs/three.module.js';

with

import * as THREE from './build/three.module.js';

(thanks @donmccurdy from the official Three.js forum) (感谢来自 Three.js 官方论坛的@donmccurdy)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM