And*_*rea 70 javascript three.js
我开始使用THREE.js,我正在尝试绘制一个带有纹理的矩形,由单个光源照亮.我认为这很简单(为简洁起见省略了HTML):
function loadScene() {
    var world = document.getElementById('world'),
        WIDTH = 1200,
        HEIGHT = 500,
        VIEW_ANGLE = 45,
        ASPECT = WIDTH / HEIGHT,
        NEAR = 0.1,
        FAR = 10000,
        renderer = new THREE.WebGLRenderer(),
        camera = new THREE.Camera(VIEW_ANGLE, ASPECT, NEAR, FAR),
        scene = new THREE.Scene(),
        texture = THREE.ImageUtils.loadTexture('crate.gif'),
        material = new THREE.MeshBasicMaterial({map: texture}),
        // material = new THREE.MeshPhongMaterial({color: 0xCC0000});
        geometry = new THREE.PlaneGeometry(100, 100),
        mesh = new THREE.Mesh(geometry, material),
        pointLight = new THREE.PointLight(0xFFFFFF);
    camera.position.z = 200;    
    renderer.setSize(WIDTH, HEIGHT);
    scene.addChild(mesh);
    world.appendChild(renderer.domElement);
    pointLight.position.x = 50;
    pointLight.position.y = 50;
    pointLight.position.z = 130;
    scene.addLight(pointLight); 
    renderer.render(scene, camera);
}
问题是,我看不到任何东西.如果我更改材料并使用注释的材料,则会出现正方形,如我所料.注意
我做错了什么?
And*_*rea 73
在加载图像时,渲染器已经绘制了场景,因此为时已晚.解决方案是改变
texture = THREE.ImageUtils.loadTexture('crate.gif'),
成
texture = THREE.ImageUtils.loadTexture('crate.gif', {}, function() {
    renderer.render(scene);
}),
Mus*_*fah 27
Andrea解决方案是绝对正确的,我将基于相同的想法编写另一个实现.如果您查看了THREE.ImageUtils.loadTexture()源代码,您会发现它使用了javascript Image对象.加载所有图像后触发$(window).load事件!所以在那个事件中我们可以用已经加载的纹理渲染我们的场景......
CoffeeScript的
$(document).ready ->
    material = new THREE.MeshLambertMaterial(map: THREE.ImageUtils.loadTexture("crate.gif"))
    sphere   = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), material)
    $(window).load ->
        renderer.render scene, camera
JavaScript的
$(document).ready(function() {
    material = new THREE.MeshLambertMaterial({ map: THREE.ImageUtils.loadTexture("crate.gif") });
    sphere = new THREE.Mesh(new THREE.SphereGeometry(radius, segments, rings), material);
    $(window).load(function() {
        renderer.render(scene, camera);
    });
});
谢谢...
Sky*_*Yip 21
在three.js的r75版本中,您应该使用:
var loader = new THREE.TextureLoader();
loader.load('texture.png', function ( texture ) {
  var geometry = new THREE.SphereGeometry(1000, 20, 20);
  var material = new THREE.MeshBasicMaterial({map: texture, overdraw: 0.5});
  var mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
});
在three.js所版本R82 TextureLoader是用来加载纹理的对象.
Extract(test.js):
var scene = new THREE.Scene();
var ratio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight,
  0.1, 50);
var renderer = ...
[...]
/**
 * Will be called when load completes.
 * The argument will be the loaded texture.
 */
var onLoad = function (texture) {
  var objGeometry = new THREE.BoxGeometry(20, 20, 20);
  var objMaterial = new THREE.MeshPhongMaterial({
    map: texture,
    shading: THREE.FlatShading
  });
  var mesh = new THREE.Mesh(objGeometry, objMaterial);
  scene.add(mesh);
  var render = function () {
    requestAnimationFrame(render);
    mesh.rotation.x += 0.010;
    mesh.rotation.y += 0.010;
    renderer.render(scene, camera);
  };
  render();
}
// Function called when download progresses
var onProgress = function (xhr) {
  console.log((xhr.loaded / xhr.total * 100) + '% loaded');
};
// Function called when download errors
var onError = function (xhr) {
  console.log('An error happened');
};
var loader = new THREE.TextureLoader();
loader.load('texture.jpg', onLoad, onProgress, onError);
在此示例中,纹理在网格的构造函数中加载,使用Promises加载多个纹理.
Extract(Globe.js):
使用Object3D在同一容器中具有两个网格来创建一个新容器:
var Globe = function (radius, segments) {
  THREE.Object3D.call(this);
  this.name = "Globe";
  var that = this;
  // instantiate a loader
  var loader = new THREE.TextureLoader();
一个地图textures,其中每个对象都包含url一个纹理文件,并val用于存储Three.js 纹理对象的值.
  // earth textures
  var textures = {
    'map': {
      url: 'relief.jpg',
      val: undefined
    },
    'bumpMap': {
      url: 'elev_bump_4k.jpg',
      val: undefined
    },
    'specularMap': {
      url: 'wateretopo.png',
      val: undefined
    }
  };
promises数组,对于map中的每个对象,textures在数组中推送一个新的Promise texturePromises,每个Promise都会调用loader.load.如果值entry.val是有效THREE.Texture对象,则解析promise.
  var texturePromises = [], path = './';
  for (var key in textures) {
    texturePromises.push(new Promise((resolve, reject) => {
      var entry = textures[key]
      var url = path + entry.url
      loader.load(url,
        texture => {
          entry.val = texture;
          if (entry.val instanceof THREE.Texture) resolve(entry);
        },
        xhr => {
          console.log(url + ' ' + (xhr.loaded / xhr.total * 100) +
            '% loaded');
        },
        xhr => {
          reject(new Error(xhr +
            'An error occurred loading while loading: ' +
            entry.url));
        }
      );
    }));
  }
Promise.all将promise数组texturePromises作为参数.这样做会使浏览器等待所有承诺解决,当他们这样做时,我们可以加载几何和材料.
  // load the geometry and the textures
  Promise.all(texturePromises).then(loadedTextures => {
    var geometry = new THREE.SphereGeometry(radius, segments, segments);
    var material = new THREE.MeshPhongMaterial({
      map: textures.map.val,
      bumpMap: textures.bumpMap.val,
      bumpScale: 0.005,
      specularMap: textures.specularMap.val,
      specular: new THREE.Color('grey')
    });
    var earth = that.earth = new THREE.Mesh(geometry, material);
    that.add(earth);
  });
对于云球体,只需要一个纹理:
  // clouds
  loader.load('n_amer_clouds.png', map => {
    var geometry = new THREE.SphereGeometry(radius + .05, segments, segments);
    var material = new THREE.MeshPhongMaterial({
      map: map,
      transparent: true
    });
    var clouds = that.clouds = new THREE.Mesh(geometry, material);
    that.add(clouds);
  });
}
Globe.prototype = Object.create(THREE.Object3D.prototype);
Globe.prototype.constructor = Globe;
| 归档时间: | 
 | 
| 查看次数: | 99320 次 | 
| 最近记录: |