已被阅读 5743 次 | 文章分类:javascript | 2022-05-26 00:25
介绍两种给OBJ模型添加材质的方法
1 加载obj模型
如何加载obj模型可以参考:加载obj模型
2 纹理方式(1):添加自带材质文件
这种方法适合由建模软件导出的模型;因为建模软件导出模型包含两个文件:obj文件和mtl文件
利用OBJLoader和MTLLoader加载器,分别加载他们才能保证模型跟纹理准确的显示;
第一步:引入库
import * as THREE from 'three'
import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
第二步:初始化变量
let scene,camera,gridHelper,axes,renderer;
第四步:初始化场景
initScene();
function initScene(){
// ---------------------------------------------------------------------
// 场景和相机
// ---------------------------------------------------------------------
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100000);
camera.position.set(1040, 250, 250 );
camera.lookAt(0,0,0);
// ---------------------------------------------------------------------
// 辅助网格
// ---------------------------------------------------------------------
gridHelper = new THREE.GridHelper(12000, 20, 0x888888, 0x444444 );
gridHelper.position.y = - 50;
gridHelper.name = "Grid";
scene.add(gridHelper);
// ---------------------------------------------------------------------
// 辅助坐标轴
// ---------------------------------------------------------------------
axes = new THREE.AxesHelper(50000);
axes.name = "AxesHelper";
scene.add(axes);
//光源一定要添加,负责模型没有光 肯定是黑色
var light = new THREE.DirectionalLight(0xffffff);//光源颜色
light.position.set(20, 10, 1305);//光源位置
scene.add(light);//光源添加到场景中
// ---------------------------------------------------------------------
// 渲染器
// ---------------------------------------------------------------------
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera,renderer.domElement);
controls.zoomSpeed=2.0;
controls.rotateSpeed=2.0;
animate();
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
}
第五步:初始化模型
let path="./statics/models/obj/IronMan/";
let objName="IronMan.obj";
let mtlName="IronMan.mtl";
initModel();
function initModel() {
try{
// 1 初始化纹理加载器
var mtlLoader=new MTLLoader();
// 2 设置mtl资源路径
mtlLoader.resourcePath=path;
mtlLoader.path=path;
// 3 加载材质
mtlLoader.load(mtlName,function(materials){
materials.preload();
// 4 加载模型
var objLoader=new OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath(path);
objLoader.load(objName,function(obj){
obj.position.y=10;
obj.scale.set(2, 2, 2);
scene.add(obj);
})
})
}catch(e){
console.error('解析失败',e);
}
}
这种方式添加纹理,简单规整;中间不需要去调整;能够将建模软件的模型一模一样在网页端显示即可
3 纹理方式(2):自定义模型材质
这种方式自由度比较高;可以对整个obj模型的子mesh元素设置材质;如下
情况1:给钢铁侠设置纯色材质
// 2 加载obj模型
loader.load("./statics/models/obj/IronMan/IronMan.obj",function (loadedMesh) {
var material = new THREE.MeshBasicMaterial({color:'red'});
//obj模型是有无数个mesh子元素组成,所以我们可以对单个child的mesh进行操作
loadedMesh.children.forEach(function (child,index) {
child.material=material
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
});
//模型放大一倍
loadedMesh.scale.set(1, 1, 1);
scene.add(loadedMesh);
});
情况2:给钢铁侠设置图片纹理
// 2 加载obj模型
loader.load("./statics/models/obj/IronMan/IronMan.obj",function (loadedMesh) {
var material=new THREE.MeshBasicMaterial({
map:new THREE.TextureLoader().load('./statics/imgs/floor.jpg'),
side:THREE.DoubleSide
});
//obj模型是有无数个mesh子元素组成,所以我们可以对单个child的mesh进行操作
loadedMesh.children.forEach(function (child,index) {
child.material=material
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
});
//模型放大一倍
loadedMesh.scale.set(1, 1, 1);
scene.add(loadedMesh);
});
情况3:给树模型设置图片纹理
情况4:给钢铁侠不同子元素设置不同纹理
// 2 加载obj模型
loader.load("./statics/models/obj/IronMan/IronMan.obj",function (loadedMesh) {
var material = new THREE.MeshBasicMaterial({color:'red'});
var material1=new THREE.MeshBasicMaterial({
map:new THREE.TextureLoader().load('./statics/imgs/floor.jpg'),
side:THREE.DoubleSide
});
//obj模型是有无数个mesh子元素组成,所以我们可以对单个child的mesh进行操作
loadedMesh.children.forEach(function (child,index) {
if(index%2===0){
child.material=material1
}else{
child.material=material
}
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
});
//模型放大一倍
loadedMesh.scale.set(1, 1, 1);
scene.add(loadedMesh);
});
根据子mesh的奇偶索引顺序设置不同材质:这场景适合根据某些属性过滤设置材质
QQ:3410192267 | 技术支持 微信:popstarqqsmall
Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号