在画布中渲染 Three.js 场景

时间:2021-02-17 12:00:48

标签: javascript three.js

我已经尝试在画布中渲染下面的场景很多次了,但它仍然不起作用。
我试过用 var renderer = new THREE.WebGLRenderer({antialias: true}); 替换 var renderer = new THREE.WebGLRenderer({ canvas: canvas });,但不是渲染它只是开始无限加载。

完整的 HTML 页面:https://jsfiddle.net/1k04rwsx/替换 obj 模型以使其加载)

P.S.:我是新手,如果代码看起来有点奇怪,请见谅。
非常感谢任何可以提供帮助的人!

1 个答案:

答案 0 :(得分:2)

您的加载屏幕不会消失,因为您的小提琴从相对 URL 加载 OBJ(这对 jsFiddle 无效)。我已将一个 URL 替换为指向官方存储库的链接,然后一切正常。

/**
  * Generate a scene object with a background color
  **/

  function getScene() {
    var scene = new THREE.Scene();
    scene.background = new THREE.Color(0x111111);
    return scene;
  }

  /**
  * Generate the camera to be used in the scene. Camera args:
  *   [0] field of view: identifies the portion of the scene
  *     visible at any time (in degrees)
  *   [1] aspect ratio: identifies the aspect ratio of the
  *     scene in width/height
  *   [2] near clipping plane: objects closer than the near
  *     clipping plane are culled from the scene
  *   [3] far clipping plane: objects farther than the far
  *     clipping plane are culled from the scene
  **/

  function getCamera() {
    var aspectRatio = window.innerWidth / window.innerHeight;
    var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 1000);
    camera.position.set(0, 1, -10);
    return camera;
  }

  /**
  * Generate the light to be used in the scene. Light args:
  *   [0]: Hexadecimal color of the light
  *   [1]: Numeric value of the light's strength/intensity
  *   [2]: The distance from the light where the intensity is 0
  * @param {obj} scene: the current scene object
  **/

  function getLight(scene) {
    var light = new THREE.PointLight(0xffffff, 1, 0);
    light.position.set(1, 5, -2);
    scene.add(light);

    const lighta = new THREE.AmbientLight( 0x404040 ); // soft white light
    scene.add( lighta );

    var ambientLight = new THREE.AmbientLight(0x111111);
    scene.add(ambientLight);
    return light;
  }

  /**
  * Generate the renderer to be used in the scene
  **/

  function getRenderer() {
    // Create the canvas with a renderer
    var renderer = new THREE.WebGLRenderer({antialias: true}); //original
    // Add support for retina displays
    renderer.setPixelRatio(window.devicePixelRatio);
    // Specify the size of the canvas
    renderer.setSize(window.innerWidth, window.innerHeight);
    // Add the canvas to the DOM
    document.body.appendChild(renderer.domElement);
    return renderer;
  }

  /**
  * Generate the controls to be used in the scene
  * @param {obj} camera: the three.js camera for the scene
  * @param {obj} renderer: the three.js renderer for the scene
  **/

  function getControls(camera, renderer) {
    var controls = new THREE.TrackballControls(camera, renderer.domElement);
    controls.zoomSpeed = 0.4;
    controls.panSpeed = 0.4;
    return controls;
  }

  /**
  * Load Nimrud model
  **/

  function loadModel() {
    var loader = new THREE.OBJLoader();
    loader.load( 'https://threejs.org/examples/models/obj/tree.obj', function ( object ) { //this is just a character, can be replaced to test
      object.rotation.y = 1.5;
      object.scale.y = 0.7;
      object.scale.x = 0.7;
      object.scale.z = 0.7;
      scene.add( object );
      document.querySelector('h1').style.display = 'none';
    } );
  }

  /*function loadModel() {
    var loader = new THREE.OBJLoader();
    loader.load( 'avv.obj', function ( object ) {
      var box = new THREE.Box3().setFromObject( object );
  var center = new THREE.Vector3();
  box.getCenter( center );
  object.position.sub( center ); // center the model
  object.rotation.y = Math.PI;   // rotate the model
      scene.add( object );
      document.querySelector('h1').style.display = 'none';
    } );
  }*/

  /*function loadModel() {
    var loader = new THREE.OBJLoader();
    loader.load( 'avc.obj', function ( object ) {
      //object.rotation.y = 1.5;
      object.position.y = -18;
      object.position.x = -16;
      object.position.z = -2;
      scene.add( object );
      document.querySelector('h1').style.display = 'none';
    } );
  }*/

  /**
  * Render!
  **/

  function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
    //controls.update();
  };

  var scene = getScene();
  var camera = getCamera();
  var light = getLight(scene);
  var renderer = getRenderer();
  var controls = getControls(camera, renderer);

  loadModel()

  render();
  html, body { width: 100%; height: 100%; background: #000; color: #fff; }
  body { margin: 0; overflow: hidden; }
  canvas { width: 100%; height: 100%; }

  .lds-dual-ring {
  display: inline-block;
  width: 80px;
  height: 80px;
}
.lds-dual-ring:after {
  content: " ";
  display: block;
  width: 64px;
  height: 64px;
  margin: 8px;
  border-radius: 50%;
  border: 6px solid #fff;
  border-color: #fff transparent #fff transparent;
  animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
  <script src='https://cdn.jsdelivr.net/npm/three@0.88/build/three.min.js'></script>
  <script src='https://cdn.jsdelivr.net/npm/three@0.88/examples/js/controls/TrackballControls.js'></script>
  <script src='https://cdn.jsdelivr.net/npm/three@0.88/examples/js/loaders/OBJLoader.js'></script>
  <h1 style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);"><div class="lds-dual-ring"></div></h1>

顺便说一句:请不要混合来自不同版本的 three.js 类。始终确保像上面的代码一样坚持单一版本。