关于Typescript:Three.js Angular:纹理加载失败

Three.js + Angular: texture loading fails

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

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

我试图遵循有关在WebGL中渲染地球的旧Three.js教程,该教程现在已弃用THREE.ImageUtils.loadTexture()来加载网格材质贴图的纹理。

它对我不起作用,因此我尝试使用现代的THREE.TextureLoader().load()。但是,由于某种原因,它从未对回调执行任何操作。

所以我尝试将THREE.TextureLoader().load()THREE.LoadingManager()配对使用。虽然THREE.LoadingManager()的回调似乎有效,但它仍然仅会产生带有某种光线的黑色场景。

虽然我刚开始使用Three.js,
在我看来,我的代码:

  • 不包括光
  • 似乎不仅渲染一次
  • 不会向控制台抛出任何错误
  • 代码:

    在我的component.html中:

    1
    2
    3
    ...

    ...

    在我的component.ts中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    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());
      }

    }

    我进行了测试,您的代码具有一些建议

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

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

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

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