首页 > 解决方案 > Three.js + Angular:纹理加载失败

问题描述

Three.js 由于纹理加载而呈现黑色场景。

我在一个角度组件(角度版本 8)中使用了 three.js。

我试图按照旧的three.js 教程在WebGL 中渲染地球,现在不推荐使用该教程THREE.ImageUtils.loadTexture()来加载网格材质贴图的纹理。

它对我不起作用,所以我尝试使用modern THREE.TextureLoader().load(). 但是,由于某种原因,它从未对其回调采取行动。

所以我尝试使用THREE.TextureLoader().load()THREE.LoadingManager(). 虽然THREE.LoadingManager()的回调似乎有效,但它仍然只产生带有一些光线的黑色场景。

虽然我不熟悉使用three.js,但对我来说似乎我的代码:

  1. 是否包括灯光
  2. 似乎不仅渲染一次
  3. 不会向控制台抛出任何错误

代码

在我的 component.html 中:

...
<div #rendererContainer></div>
...

在我的 component.ts 中:

import {Component, OnInit, ViewChild, ElementRef, AfterViewInit} from '@angular/core';
import * as THREE from 'three';

export class MyComponent implements OnInit, AfterViewInit {

  @ViewChild('rendererContainer', {static: false}) rendererContainer: ElementRef;

  renderer = new THREE.WebGLRenderer();
  scene = null;
  camera = null;
  mesh = null;
  earthSurface = new THREE.MeshStandardMaterial({color: 0xaaaaaa});

  constructor() {
    // scene and camera
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
    this.camera.position.z = 1.5;

    // light
    this.scene.add(new THREE.AmbientLight(0x333333));
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(5, 3, 5);
    this.scene.add(light);

    const manager = new THREE.LoadingManager();
    const textureLoader = new THREE.TextureLoader(manager);
    this.earthSurface.map = textureLoader.load('planet.jpg');
    manager.onLoad = () => {
      // call back
      const geometry = new THREE.SphereGeometry(0.5, 32, 32);
      this.mesh = new THREE.Mesh(
        geometry,
        this.earthSurface
      );
      this.scene.add(this.mesh);
      this.rerender();
      console.log(this.earthSurface);
    };
  }

  ngOnInit() {}

  ngAfterViewInit() {
      this.renderer.setSize(window.innerWidth, window.innerHeight);
      this.rendererContainer.nativeElement.appendChild(this.renderer.domElement);
      this.animate();
      // setInterval(() => {this.rerender();}, 1.5 * 1000);
  }

  rerender() {
    this.renderer.render(this.scene, this.camera);
  }

  animate() {
    this.renderer.render(this.scene, this.camera);
    window.requestAnimationFrame(() => this.animate());
  }

}

标签: angulartypescriptthree.js

解决方案


我进行了测试,您的代码适用于一些建议

您可以完全放弃重新渲染功能,只需确保像这样加载场景的颜色:

this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xf5f5f5);

确保您加载的图像具有正确的路径,您可以尝试:

this.earthSurface.map = textureLoader.load('https://upload.wikimedia.org/wikipedia/commons/b/b8/Exploding_planet.jpg');

推荐阅读