threejs实现贴花效果

引用:官方源码
在官方给出的源码中采用的模型格式是tfgl格式,查看源码可知新建DecalGeometry对象时,传入的参数为mesh, position, orientation, size,因此对obj文件不可以直接操作,需要遍历obj中的children,在这里采用drc格式(drc为使用Draco压缩后的格式)的模型实现贴花效果。
DecalGeometry源码中传入的参数:

function DecalGeometry( mesh, position, orientation, size ){...}

实现贴花效果,需要借助DecalGeometry.js,因此要其进行引入:

<script src="js/geometries/DecalGeometry.js"></script>

接着新建贴花时需要的参数,raycaster用于拾取鼠标点击的对象,intersection中有intersect、point、normal,intersect为boolean用于判断鼠标点击的位置是否属于模型表面,point与normal用于存储鼠标点击模型时的point与normal。

var mouse=new THREE.Vector2();
var moved;//
var line;//跟随鼠标
var raycaster;//拾取射线
var intersection;//相交线
var decalPosition;//贴花位置
var decalOrientation;//贴花方向
var decalMaterial;//贴花材质
var decals;//贴花数组
var decalSize;//贴花数组
var mouseHelper;

对参数进行初始化,首先在场景中添加line,若物体表面出现线条,则表明当前位置允许进行贴花操作,通过textureLoader加载所需要的贴花纹理:

function initDecalData(){
	let geometry=new THREE.BufferGeometry();
	geometry.setFromPoints([new THREE.Vector3(),new THREE.Vector3()]);
	line=new THREE.Line(geometry,new THREE.LineBasicMaterial({color:0xff0000}));
	scene.add(line);

	decalSize=new THREE.Vector3( 10, 10, 10 );
	decalPosition=new THREE.Vector3();
	decalOrientation=new THREE.Euler();
	decals=[];

	mouseHelper = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 10 ), new THREE.MeshNormalMaterial() );
	mouseHelper.visible = false;
	scene.add( mouseHelper );//

	let textureLoader=new THREE.TextureLoader();
	let decalDiffuse=textureLoader.load( 'textures/decal/decal-diffuse.png' );//贴花 
	let decalNormal=textureLoader.load( 'textures/decal/decal-normal.jpg' );

	decalMaterial=new THREE.MeshLambertMaterial( {
		pecular: 0x444444,
			map: decalDiffuse,//贴花图
			normalMap: decalNormal,//法向量纹理
			normalScale: new THREE.Vector2( 1, 1 ),
			shininess: 30,
			transparent: true,//透明度
			depthTest: true,
			depthWrite: false,
			polygonOffset: true,
			polygonOffsetFactor: - 4,
			wireframe: false
	} );

	intersection={//相交线
		intersects:false,
		point:new THREE.Vector3(),
		normal:new THREE.Vector3()
	};
	
}

通过拾取射线对选取的贴花的位置进行判断,是否位于模型表面。当位于模型表面时,获取点击模型时的point:

function checkIntersection(){
	
	if(!model) return;
	raycaster=new THREE.Raycaster();//拾取射线
	raycaster.setFromCamera(mouse,camera);
	let intersects=raycaster.intersectObjects([model]);
     //console.log(intersects);
	if(intersects.length>0){//在模型表面
		let modelPoint=intersects[0].point;//获取模型的point
		mouseHelper.position.copy(modelPoint);
		intersection.point.copy(modelPoint);

		let modelNormal=intersects[0].face.normal;//.clone();
		modelNormal.transformDire
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值