Супер простая демонстрация запуска грузовика Three.js

внешний интерфейс JavaScript
Супер простая демонстрация запуска грузовика Three.js

Начало бреда: Понимание three.js находится в стадии становления и пока не видно, просто посмотрите на three.jsWoohoo.Веб-менеджмент 3. Талант/три JS/отвратительно...Официальный сайт может также попытаться написать простую демонстрацию. Вы можете загрузить все демо-файлы с официального сайта, а затем проанализировать соответствующие демо-файлы в соответствии с собственной бизнес-логикой разработки.

屏幕录制2021-10-13 下午3.01.16.gif

Шаг 1. Как использовать примеры, скачанные с официального сайта

Здесь необходимо пояснить, что сервис three.js должен запускать для загрузки 3D-модели, поэтому поместите все загруженные файлы в путь «/Library/WebServer/Documents/» (здесь компьютер Mac), а затем запустите служба apache, выполните sudo apachectl start в терминале, таким образом, локальная служба будет успешно запущена.

Здесь вы можете видеть, что локальная служба включена.

image.png

Итак, как использовать эти демонстрации для разработки? Например, грузовик в демо в формате obj, тогда вам нужно узнать, как загрузить API three.js в формате obj в файле примера.

Найдите папку примера.image.png

Найдите файл webgl_loader_obj_mtl.html.

obj — формат файла 3D-модели, mtl — формат файла рендеринга текстуры, они совпадают.

image.png

Хорошо, откройте его, а затем проанализируйте API three.js внутри в соответствии с примером отображения локальной веб-страницы, проще ли начать?

Шаг 2. Инициализируйте камеру, сцену, рендерер

Импортируйте необходимые файлы js

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

//下面的是不同模型类型加载功能模块
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';

Инициализировать камеру, сцену, рендерер

let camera, scene, renderer;

const container = document.createElement( 'div' );
document.body.appendChild( container );
//相机
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 );

Метод обновления по времени

function animate() {
   requestAnimationFrame( animate );
      render();
}

Шаг 3. Код показывает, как загрузить скайбокс, дорогу, грузовик

скайбокс

Блок неба должен создать куб, а затем визуализировать обратную сторону текстуры, а затем поместить камеру в блок.В это время добавьте вращение блока по оси Z, чтобы сформировать динамику преобразования голубого неба. эффект.

//天空
let flieSize = 5;
const path = "textures/cube/skyboxsun25deg/";'
const format = '.jpg';
const urls = [
  path + 'px' + format,//右面
  path + 'nx' + format,//左面
  path + 'pz' + format,//后面 
  path + 'nz' + format,//前面 
  path + 'ny' + format,//地面
  path + 'py' + format,//顶面
];
				
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 );
//纹理反面渲染
cube.geometry.scale( 1, 1, -1 );
//全局变量保存天空正方体
sky = cube;

вращение скайбокса

function render() {
  //卡车移动
  if(truck != null && sky != null && camera != null){
     let speed = 1;
     truck.position.y += speed;
     camera.position.y += speed;
     sky.position.y += speed;
    }
  //天空旋转
  if(sky != null){
     sky.rotation.z += - Math.PI / 10500;
  }
  renderer.render( scene, camera );
}

шоссе

//加载图片纹理
const highwayTexture = new THREE.TextureLoader().load( 'textures/highway.jpg' );
//设置平铺重复
highwayTexture.wrapS = THREE.RepeatWrapping;
highwayTexture.wrapT = THREE.RepeatWrapping;
//设置重复次数(这里x轴重复1次,y轴重复500次)
highwayTexture.repeat.set(1, 500);

//创建盒子模型
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 );

грузовик

Грузовик должен загрузить сюда файл формата obj, а текстура должна загрузить файл формата mtl.

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 ) {
    //位移
    object.position.y = 90;
    object.position.z = 10;
    object.position.x = 12;
   
   //旋转						
   object.rotation.z = - Math.PI;
   //按比例缩小			
   object.scale.set(0.05,0.05,0.05);
   //全局保存truck对象
   truck = object;
   scene.add( object );
   }, onProgress, onError );
} );

Объект MTLLoader загружает текстуру в формате mtl.После завершения загрузки загружается модель формата obj.Финальная функция обратного вызова возвращает "спрайт-объект".

Конечно, если вы не хотите использовать текстуру в формате mtl, вы также можете загрузить модель формата obj и установить текстуру отдельно.

//object obj格式模型对象
object.traverse( function ( child ) {
	if ( child.isMesh ) child.material.map = textureRabbit;
} );

Есть два "параметра метода.

1. Ход загрузки 2. Ошибка загрузки

// model 加载模型进度回调
const onProgress = function ( xhr ) {
      if ( xhr.lengthComputable ) {
      const percentComplete = xhr.loaded / xhr.total * 100;
      //console.log( Math.round( percentComplete, 2 ) + '% downloaded');
      }
};
// model 加载模型出错回调
const onError = function () { };

Анимация движения грузовика также помещается в метод обратного вызова рендеринга экрана.

function render() {
 //卡车移动 
 if(truck != null && sky != null && camera != null){
    let speed = 1;
    truck.position.y += speed;
    camera.position.y += speed;
    sky.position.y += speed;
   }
  //天空旋转
  if(sky != null){
	sky.rotation.z += - Math.PI / 10500;
  }
  renderer.render( scene, camera );
}

Шаг 4. Установите вращение камеры для проверки дорожных условий

屏幕录制2021-10-13 下午4.39.41.gif

По сути, это следить за клавиатурой ← ↑ → ↓, прямо по коду


document.onkeydown = function whichButton(event)
{
  //console.log(event.keyCode)
  if(event.keyCode == 37){
    //左
    camera.rotateY(0.009);
   } else if(event.keyCode == 38){
    //上
    camera.rotateX(0.005);
   } else if(event.keyCode == 39){
    //右
    camera.rotateY(-0.009);
   } else if(event.keyCode == 40){
    //下
    camera.rotateX(-0.005);
   }
 }

хорошо, предельно простогрузовик работаетДемо завершено, код плохой, а боги такие смеются.