WebGL With Three.js – Lesson 6(转)

时间:2021-09-14 04:22:45

时间 2014-07-15 19:11:06

WebGL With Three.js – Lesson 6

Today we continue our webgl lessons for those who study it and who wants to enhance his knowledge. In today’s lesson we will look at the load process of ready three-dimensional objects. There are many websites where you can download these models, and moreover, if you have an editor of three-dimensional objects (like 3D Max, Maya, or even Blender), you can create your own models. There are also many file formats of three-dimensional objects, such as obj, collada (dae), obj, mtl, stl, vrml and so on. Most of them can be loaded into your three.js scenes using special loaders. And today we will consider how to load three-dimensional models using a variety of loaders.

Live Demo 1

Live Demo 2

Live Demo 3

Live Demo 4


OBJ

In order to load object files (.obj), we can use OBJLoader.js. It is rather easy to use this library, before all, we need to attach the library (in the section where we link all other necessary scripts):

<script src="js/three.min.js"></script>
<script src="js/OBJLoader.js"></script>
<script src="js/THREEx.WindowResize.js"></script>
<script src="js/OrbitControls.js"></script>
<script src="js/stats.min.js"></script>
<script src="js/script1.js"></script>

Now, let’s prepare a general skeleton (of all our demos):

var lesson6 = {
  scene: null,
  camera: null,
  renderer: null,
  container: null,
  controls: null,
  clock: null,
  stats: null,

  init: function() { // Initialization

  // create main scene
  this.scene = new THREE.Scene();
  this.scene.fog = new THREE.FogExp2(0xcce0ff, 0.0003);

  var SCREEN_WIDTH = window.innerWidth,
    SCREEN_HEIGHT = window.innerHeight;

  // prepare camera
  var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 2000;
  this.camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
  this.scene.add(this.camera);
  this.camera.position.set(0, 100, 300);
  this.camera.lookAt(new THREE.Vector3(0,0,0));

  // prepare renderer
  this.renderer = new THREE.WebGLRenderer({ antialias:true });
  this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
  this.renderer.setClearColor(this.scene.fog.color);
  this.renderer.shadowMapEnabled = true;
  this.renderer.shadowMapSoft = true;

  // prepare container
  this.container = document.createElement('div');
  document.body.appendChild(this.container);
  this.container.appendChild(this.renderer.domElement);

  // events
  THREEx.WindowResize(this.renderer, this.camera);

  // prepare controls (OrbitControls)
  this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
  this.controls.target = new THREE.Vector3(0, 0, 0);
  this.controls.maxDistance = 2000;

  // prepare clock
  this.clock = new THREE.Clock();

  // prepare stats
  this.stats = new Stats();
  this.stats.domElement.style.position = 'absolute';
  this.stats.domElement.style.left = '50px';
  this.stats.domElement.style.bottom = '50px';
  this.stats.domElement.style.zIndex = 1;
  this.container.appendChild( this.stats.domElement );

  // add spot light
  var spLight = new THREE.SpotLight(0xffffff, 1.75, 2000, Math.PI / 3);
  spLight.castShadow = true;
  spLight.position.set(-100, 300, -50);
  this.scene.add(spLight);

  // add simple ground
  var ground = new THREE.Mesh( new THREE.PlaneGeometry(200, 200, 10, 10), new THREE.MeshLambertMaterial({color:0x999999}) );
  ground.receiveShadow = true;
  ground.position.set(0, 0, 0);
  ground.rotation.x = -Math.PI / 2;
  this.scene.add(ground);

  // load a model
  this.loadModel();
  },
  loadModel: function() {

  ......
  }
};

// Animate the scene
function animate() {
  requestAnimationFrame(animate);
  render();
  update();
}

// Update controls and stats
function update() {
  lesson6.controls.update(lesson6.clock.getDelta());
  lesson6.stats.update();
}

// Render the scene
function render() {
  if (lesson6.renderer) {
  lesson6.renderer.render(lesson6.scene, lesson6.camera);
  }
}

// Initialize lesson on page load
function initializeLesson() {
  lesson6.init();
  animate();
}

if (window.addEventListener)
  window.addEventListener('load', initializeLesson, false);
else if (window.attachEvent)
  window.attachEvent('onload', initializeLesson);
else window.onload = initializeLesson;

This code creates the empty scene with camera, rendererm control stats and light. Please pay attention to the empty ‘loadModel’ function – we will put here different codes to load models of different formats. Our first format is ‘obj’. Have a look to the following implementation:

// prepare loader and load the model
var oLoader = new THREE.OBJLoader();
oLoader.load('models/chair.obj', function(object, materials) {

  // var material = new THREE.MeshFaceMaterial(materials);
  var material2 = new THREE.MeshLambertMaterial({ color: 0xa65e00 });

  object.traverse( function(child) {
    if (child instanceof THREE.Mesh) {

      // apply custom material
      child.material = material2;

      // enable casting shadows
      child.castShadow = true;
      child.receiveShadow = true;
    }
  });
  
  object.position.x = 0;
  object.position.y = 0;
  object.position.z = 0;
  object.scale.set(1, 1, 1);
  lesson6.scene.add(object);
});

Firstly, we created a new instance of THREE.OBJLoader, and then – we loaded ‘chair.obj’ model file. In order to apply a custom material, we traversed through it’s children and applied the prepared material2 (THREE.MeshLambertMaterial). We also applied casting and receiving shadows. In the end – we set the position of the object and set scale value.

MTL

In short, this is an addition for the previously described OBJ format. Because MTL file is file that describes materials of OBJ file. To load OBJ files with support of MTL, we can use another loader: OBJMTLLoader. In order to use it, don’t forget to include necessary libraries:

<script src="js/MTLLoader.js"></script>
<script src="js/OBJMTLLoader.js"></script>

Now add the following code into our ‘loadModel’ function:

// prepare loader and load the model
var oLoader = new THREE.OBJMTLLoader();
oLoader.load('models/castle.obj', 'models/castle.mtl', function(object) {

  object.position.x = -200;
  object.position.y = 0;
  object.position.z = 100;
  object.scale.set(0.1, 0.1, 0.1);
  lesson6.scene.add(object);
});

As you can see, the load function accepts more params – we can point our ‘mtl’ file with materials. This method allows us to load model (obj) with textures!

DAE

Collada files (dae) are also popular among 3d designers. This format supports textures as well. In order to load this format, we can use another loader: ColladaLoader. To use it, don’t forget to include necessary libraries:

<script src="js/ColladaLoader.js"></script>

Now add the following code into our ‘loadModel’ function:

// prepare loader and load the model
var oLoader = new THREE.ColladaLoader();
oLoader.load('models/mlc.dae', function(collada) {

  var object = collada.scene;
  var skin = collada.skins[0];

  object.rotation.x = -Math.PI / 2;
  object.rotation.z = Math.PI / 2;
  object.position.x = -50;
  object.position.y = -100;
  object.position.z = 0;
  object.scale.set(0.025, 0.025, 0.025);
  object.updateMatrix();
  lesson6.scene.add(object);
});

JSON

This format is natively supported by three.js. It also support custom materials (with textures) that are described in the json file. In order to load this format, we can use another loader: JSONLoader:

// prepare loader and load the model
var oLoader = new THREE.JSONLoader();
oLoader.load('models/palm.js', function(geometry, materials) {

  // get original materials
  var material = new THREE.MeshFaceMaterial(materials);

  var mesh = new THREE.Mesh(geometry, material);

  mesh.position.x = -50;
  mesh.position.y = -80;
  mesh.position.z = 0;
  mesh.scale.set(10, 10, 10);
  lesson6.scene.add(mesh);
});

Live Demo 1

Live Demo 2

Live Demo 3

Live Demo 4


Conclusion

Next lesson we will continue our overview of various formats and loaders. Stay tuned for new lessons and you are sure to find something new and interesting for yourself.

参考:http://www.tuicool.com/articles/ERBJzqN