Bs: for three. Js understanding in the stage of introduction also did not see the door, see three light. Js www.webgl3d.cn/threejs/exa… Try writing a simple demo for the official website. You can download all the demo files from the official website, and then analyze the corresponding demo files according to their own development logic.

Step 1. How to use the examples downloaded from the official website

Need to explain here, three. Js to load the 3 d model need to open services, so that will be downloaded all the files in the ‘/ Library/WebServer/Documents/directory (here is the Mac), then start the apache service, Execute sudo apachectl start on the terminal, and the local service is successfully started.

Here you see that the local service is enabled.

So, how do you develop with these demos? For example, if the truck in the demo is in OBJ format, you need to find the API in the sample file for loading the obJ format three.js.

Find the example folder.

Find the webgl_loader_obj_mtl.html file

Obj is 3D model file format, MTL is texture render file format, the two are compatible.

Well, open it up and disentangle the three. Js API based on the local web demo. Wouldn’t that make it easier to get started?

Step 2: Initialize the camera, scene, and renderer

Import the required JS files

//three.js
import * as THREE from '.. /build/three.module.js';

// The following are the loading function modules of different model types
import { DDSLoader } from './jsm/loaders/DDSLoader.js';
import { MTLLoader } from './jsm/loaders/MTLLoader.js';
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
import { TGALoader } from './jsm/loaders/TGALoader.js';
Copy the code

Initialize the camera, scene, renderer

let camera, scene, renderer;

const container = document.createElement( 'div' );
document.body.appendChild( container );
/ / camera
camera = new THREE.PerspectiveCamera( 45.window.innerWidth / window.innerHeight, 1.2000 );
// scene
scene = new THREE.Scene();
//renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
Copy the code

Periodic Refresh method

function animate() {
   requestAnimationFrame( animate );
      render();
}
Copy the code

Step 3. Code display how to load skybox, road and truck

The sky box

Sky box is to build a cube, render the texture on the reverse side, and then put the camera inside the box. At this time, rotate the box along the Z axis to form the dynamic effect of blue sky transformation.

/ / the sky
let flieSize = 5;
const path = "textures/cube/skyboxsun25deg/";'
const format = '.jpg'; const urls = [ path + 'px' + format,//右面
  path + 'nx'+ format,// left path +'pz'+ format,// path +'nz'+ format,// path +'ny'+ format,// path +'py'+ format,// top]; const textureCube = new THREE.CubeTextureLoader().load( urls ); var length = flieSize * 500; var materials = []; for (var i = 0; i < urls.length; ++i) { materials.push(new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture(urls[i], {}, function() { renderer.render(scene, camera); }), overdraw: true })); } var geometry = new THREE.BoxBufferGeometry( length, length, length ); var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} ); var cube = new THREE.Mesh( geometry, materials ); Geometry. Scale (1, 1, -1); // global variable save sky cube sky = cube;Copy the code

Skybox rotation

function render() {
  // The truck moves
  if(truck ! =null&& sky ! =null&& camera ! =null) {let speed = 1;
     truck.position.y += speed;
     camera.position.y += speed;
     sky.position.y += speed;
    }
  // The sky rotates
  if(sky ! =null){
     sky.rotation.z += - Math.PI / 10500;
  }
  renderer.render( scene, camera );
}
Copy the code

highway

// Load the image texture
const highwayTexture = new THREE.TextureLoader().load( 'textures/highway.jpg' );
// Set tiling repeat
highwayTexture.wrapS = THREE.RepeatWrapping;
highwayTexture.wrapT = THREE.RepeatWrapping;
// Set the number of repetitions (x: 1, y: 500)
highwayTexture.repeat.set(1.500);

// Create a box model
const highwayGeometry = new THREE.BoxGeometry( 60.150000.1 );
const highwayMaterial = new THREE.MeshBasicMaterial( { map: highwayTexture } );
const highway = new THREE.Mesh( highwayGeometry, highwayMaterial );
highway.position.y = -100;
scene.add( highway );
Copy the code

The truck

For trucks, obJ files need to be loaded. For textures, MTL files need to be loaded.

new MTLLoader( manager )
  .setPath( 'models/obj/scania_obj/' )
  .load( 'scania.mtl'.function ( materials ) {
    materials.preload();
    new OBJLoader( manager )
    .setMaterials( materials )
    .setPath( 'models/obj/scania_obj/' )
    .load( 'scania.obj'.function ( object ) {
    / / displacement
    object.position.y = 90;
    object.position.z = 10;
    object.position.x = 12;
   
   / / rotation
   object.rotation.z = - Math.PI;
   // Scale down
   object.scale.set(0.05.0.05.0.05);
   // Save the truck object globallytruck = object; scene.add( object ); }, onProgress, onError ); });Copy the code

The MTLLoader object loads the MTL texture, then loads the OBJ model, and the final callback returns a “Sprite object”.

Of course, if you don’t want MTL textures, you can load the OBJ model and set the textures separately.

//object Model object in obj format
object.traverse( function ( child ) {
	if( child.isMesh ) child.material.map = textureRabbit; });Copy the code

The load OBJ format model callback has two “method arguments” inside it.

1. Loading progress 2

// model load model progress callback
const onProgress = function ( xhr ) {
      if ( xhr.lengthComputable ) {
      const percentComplete = xhr.loaded / xhr.total * 100;
      //console.log( Math.round( percentComplete, 2 ) + '% downloaded');}};// model load model error callback
const onError = function () {};Copy the code

The truck movement animation is also placed in the screen render callback method

function render() {
 // The truck moves
 if(truck ! =null&& sky ! =null&& camera ! =null) {let speed = 1;
    truck.position.y += speed;
    camera.position.y += speed;
    sky.position.y += speed;
   }
  // The sky rotates
  if(sky ! =null){
	sky.rotation.z += - Math.PI / 10500;
  }
  renderer.render( scene, camera );
}
Copy the code

Step 4. Set the camera rotation to check the road conditions

In fact, it is to monitor the keyboard ← ↑ → ↓ and directly enter the code


document.onkeydown = function whichButton(event)
{
  //console.log(event.keyCode)
  if(event.keyCode == 37) {/ / left
    camera.rotateY(0.009);
   } else if(event.keyCode == 38) {/ /
    camera.rotateX(0.005);
   } else if(event.keyCode == 39) {/ / right
    camera.rotateY(-0.009);
   } else if(event.keyCode == 40) {/ /
    camera.rotateX(-0.005); }}Copy the code

There you have it: a very simple truck running demo, bad code, no laughing matter.