废话开篇:对于three.js的了解处于入门还未见门阶段,光看three.js www.webgl3d.cn/threejs/exa… 官网不如试着写下简单的demo。可以从官网里把全部的demo文件下载下来,然后根据自身的开发业务逻辑去分析对应的 demo 文件。
步骤一、如何利用从官网下载下来的examples
这里需要说明一下,three.js 加载3D模型需要开启服务,所以,将下载好的全部的文件放在了 ‘/Library/WebServer/Documents/’ 路径下(这里是Mac电脑),然后启动一下apache 服务,在终端 执行 sudo apachectl start ,这样,本地的服务就开启成功了。
这里看到本地服务已经开启了。
那么,怎么利用这些demo进行开发?比如,demo里面的卡车是obj格式的,那么,就需要在例子文件里找到如何加载obj格式的three.js的api。
找到 example 文件夹。
找到 webgl_loader_obj_mtl.html 文件
obj是3D模型文件格式,mtl是纹理渲染文件格式,二者是配套的。
好了,打开它,然后根据本地的网页例子展示来剖析里面的three.js api,这样是不是更容易上手一些?
步骤二、初始化相机、场景、渲染器
引入所需的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();
}
步骤三、代码展示如何加载天空盒、公路、卡车
天空盒
天空盒就是建立一个正方体,然后进行纹理反面渲染,再将相机放在盒子里面,这个时候再给盒子加上沿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;
} );
加载 obj格式模型回调函数里面有两个“方法参数.
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 );
}
步骤四、设置相机旋,查看路况
其实就是监听键盘 ← ↑ → ↓,直接上代码
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);
}
}
好了,极其简单的 卡车跑跑 demo 就完成了,代码拙劣,大神无笑。
今天的文章超简单的Three.js 卡车跑跑demo分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/13736.html