You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js设置emissiveIntensity后场景消失问题咨询

Three.js修改代码后场景消失的原因

我是Three.js新手,跟着一份3D文本教程操作时遇到问题:添加textMesh.material[0].emissiveIntensity = glow;后首次编译正常,3D文本、发光效果及场景都能正常显示;但修改文本位置textMesh.position.x = 10再次编译后,整个场景(包括文本)消失,只剩空白屏幕。用VSCode的ctrl-z撤销位置修改后,问题还是存在。

移除动画函数中的textMesh.material[0].emissiveIntensity = glow;后,场景就能正常加载。

我的问题是:为什么首次运行正常,添加该行代码后场景会全部消失?


我的代码:

import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { TTFLoader } from 'three/examples/jsm/loaders/TTFLoader';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import { Reflector } from 'three/examples/jsm/objects/Reflector.js';


/* CREATE CAMERA */

  const camera = new THREE.PerspectiveCamera( 100, window.innerWidth / window.innerHeight, 0.01, 1000);
  camera.position.setZ(65);
  camera.position.setX(300);
  camera.position.setY(20);

/* END CAMERA */


/* CREATE SCENE & FOG */

  const scene = new THREE.Scene();
  var setcolor = 0x707070;

  //scene.fog = new THREE.Fog(setcolor, 1, 100);
  //scene.fog = new THREE.FogExp2(setcolor, 0.05);

/* END SCENE & FOG */



/* CREATE RENDERER */

  const renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
  renderer.setSize( window.innerWidth, window.innerHeight );
  renderer.setAnimationLoop( animation );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.shadowMap.enabled = true
  document.body.appendChild( renderer.domElement );

/* END RENDERER */


/* CREATE ORBIT CONTROLS */

const controls = new OrbitControls(camera, renderer.domElement);

/* END ORBIT CONTROLS */


/* CREATE LIGHTS */
  const ambientLight = new THREE.AmbientLight(0xaaaaaa)
  scene.add(ambientLight)

  const light1 = new THREE.PointLight()
  light1.position.set(10, 200, 10)
  light1.castShadow = true
  light1.shadow.bias = -0.0002
  light1.shadow.mapSize.height = 2048
  light1.shadow.mapSize.width = 2048
  scene.add(light1)

  let glow = 0.5;
  const textReactLight = new THREE.RectAreaLight( 0xf9d71c, glow, 150, 30);
  scene.add( textReactLight );
  textReactLight.position.set( 5, 23, 5 );
  textReactLight.lookAt( 0, 0, 120 );

/* END LIGHTS */


/* CREATE 3D FONT */
  let text = "B\nR\nY\nC\nE";
  let textMesh;

  const loader = new FontLoader();
  loader.load('node_modules/three/examples/fonts/droid/droid_serif_regular.typeface.json', function (font) {
    const textGeometry = new TextGeometry(text, {
      font: font,
      size: 12,
      height: 5,
      curveSegments: 12,
      bevelEnabled: true,
      bevelThickness: 5,
      bevelSize: 2,
      bevelOffset: 2,
      bevelSegments: 15
    });

    textMesh = new THREE.Mesh(textGeometry, [
      new THREE.MeshPhongMaterial({ emissive: 0xf9d71c, emissiveIntensity: glow }),
      new THREE.MeshPhongMaterial({ color: 0xffffff })
    ]);

    scene.add( textMesh );

    textMesh.position.y = 278;
    textMesh.position.x = 22
    textMesh.position.z = -10

    textMesh.rotation.y = Math.PI / 2

    textMesh.castShadow = true;
    textMesh.receiveShadow = true;

  })



/* CREATE CITY */

  // Floor
  const floorTexture = new THREE.TextureLoader().load('images/Concrete044B_2k_Color.jpg');
  const floorNormalTexture = new THREE.TextureLoader().load('images/Concrete044B_2k_NormalDX.jpg');
  const floor = new THREE.Mesh(
    new THREE.PlaneGeometry( 1000, 1000 ),
    new THREE.MeshBasicMaterial({
      map: floorTexture,
      normalMap: floorNormalTexture,
      })
  );
  floor.rotateX( - Math.PI / 2 );
  scene.add(floor);

  //Buildings
  const building1Texture = new THREE.TextureLoader().load('images/Facade002_4k_Color.jpg');
  const building1 = new THREE.Mesh(
    new THREE.BoxGeometry( 100, 70, 45 ),
    new THREE.MeshBasicMaterial({
      map: building1Texture,
    })
  );
  building1.position.y = 35
  building1.position.x = -50
  building1.position.z = -20
  //scene.add( building1 );

  const building2Texture = new THREE.TextureLoader().load('images/Facade005_4k_Color.jpg');
  const building2 = new THREE.Mesh(
    new THREE.BoxGeometry( 150, 500, 150 ),
    new THREE.MeshBasicMaterial({
      map: building2Texture,
    })
  );
  building2.position.y = 50
  building2.position.x = -50
  building2.position.z = -75
  scene.add( building2 );

  const building3Texture = new THREE.TextureLoader().load('images/Facade006_4k_Color.jpg');
  const building3 = new THREE.Mesh(
    new THREE.BoxGeometry( 35, 85, 35 ),
    new THREE.MeshBasicMaterial({
      map: building3Texture,
    })
  );
  building3.position.y = 35
  building3.position.x = -50
  building3.position.z = 35
  //scene.add( building3 );


/* END CITY CREATION */



// Window resize update
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    animation()
}

//Animation
function animation() {

  glow = Math.random() + 1;
  textMesh.material[0].emissiveIntensity = glow; //this is the line causing problems
  textReactLight.intensity = glow;


  controls.update();
    renderer.render( scene, camera );

}

问题原因及解决办法

核心问题是字体加载是异步操作,textMesh在页面初始化阶段是undefined。首次运行时,可能字体加载完成的时机刚好早于动画函数执行到那行代码的时间,所以没报错;但后续编译刷新时,动画函数会在字体加载完成前就尝试访问textMesh.material[0],导致JavaScript抛出Cannot read properties of undefined错误,中断整个渲染流程,场景因此显示空白。

解决办法:在动画函数中添加判断,确保textMesh已初始化后再修改材质属性:

function animation() {
  glow = Math.random() + 1;
  // 先判断textMesh是否存在,避免未初始化时报错
  if (textMesh) {
    textMesh.material[0].emissiveIntensity = glow;
  }
  textReactLight.intensity = glow;

  controls.update();
  renderer.render( scene, camera );
}

另外补充:你设置的textMesh.position.y = 278位置偏高,就算修复报错,可能也需要调整相机位置才能清晰看到文本,但这不是场景消失的直接原因。


内容的提问来源于stack exchange,提问作者john jacobs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:37:34