Начало бреда: Понимание three.js находится в стадии становления и пока не видно, просто посмотрите на three.jsWoohoo.Веб-менеджмент 3. Талант/три JS/отвратительно...Официальный сайт может также попытаться написать простую демонстрацию. Вы можете загрузить все демо-файлы с официального сайта, а затем проанализировать соответствующие демо-файлы в соответствии с собственной бизнес-логикой разработки.
Шаг 1. Как использовать примеры, скачанные с официального сайта
Здесь необходимо пояснить, что сервис three.js должен запускать для загрузки 3D-модели, поэтому поместите все загруженные файлы в путь «/Library/WebServer/Documents/» (здесь компьютер Mac), а затем запустите служба apache, выполните sudo apachectl start в терминале, таким образом, локальная служба будет успешно запущена.
Здесь вы можете видеть, что локальная служба включена.
Итак, как использовать эти демонстрации для разработки? Например, грузовик в демо в формате obj, тогда вам нужно узнать, как загрузить API three.js в формате obj в файле примера.
Найдите папку примера.
Найдите файл webgl_loader_obj_mtl.html.
obj — формат файла 3D-модели, mtl — формат файла рендеринга текстуры, они совпадают.
Хорошо, откройте его, а затем проанализируйте 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. Установите вращение камеры для проверки дорожных условий
По сути, это следить за клавиатурой ← ↑ → ↓, прямо по коду
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);
}
}
хорошо, предельно простогрузовик работаетДемо завершено, код плохой, а боги такие смеются.