Threejs MeshBasicMaterial材质改用LineMaterial材质,实现线条宽度自定义

threejs使用MeshBasicMaterial画矩形

let materail = new THREE.MeshBasicMaterial({
  color: currentcolor,
  side: THREE.DoubleSide,
});
let geometry = new THREE.Geometry();
let points = [[-1,0,0],[0,10,0],[10,0,0],[0,-1,0]];
for (let i = 0; i < points.length; i++) {
  geometry.vertices.push(new THREE.Vector3(points[i][0], points[i][1], points[i][2]));
}
let line = new THREE.LineLoop(geometry, materail);

引入LineMaterial 和 Line2,需要的文件如下:
在这里插入图片描述
改为LineMaterial材质的代码实现width加粗

let points = [[-1,0,0],[0,10,0],[10,0,0],[0,-1,0]];
let material = new THREE.LineMaterial({
    side: THREE.DoubleSide,
    color: this.draw.color,
    linewidth: 6,
    dashed: true,
    dashScale: 0.5,
    dashSize: 2,
    gapSize: 1,
})
material.resolution.set(this.canvas.width, this.canvas.height)
const geometry = new THREE.LineGeometry()
const pointArray = []
for (let i = 0; i < points.length; i++) {
	pointArray.push(points[i][0])
	pointArray.push(points[i][1])
	pointArray.push(points[i][2])
}
//添加起点,形成闭环
pointArray.push(points[0][0])
pointArray.push(points[0][1])
pointArray.push(points[0][2])
geometry.setPositions(pointArray)

const vertices = []
for (let i = 0; i < points.length; i++) {
vertices.push(new THREE.Vector3(points[i][0], points[i][1], points[i][2]))
}
//添加起点,形成闭环
vertices.push(new THREE.Vector3(points[0][0], points[0][1], points[0][2]))
geometry.vertices = vertices

const line = new THREE.Line2(geometry, material)
line.computeLineDistances()

遇到的问题:
1、引入LineMaterial材质,相关JS文件引用失败
一般项目使用如下es6语法引用,代码如下所示

import * as THREE from 'three'
import OrbitControls from 'three-orbitcontrols'
import { Line2 } from 'three/examples/jsm/lines/Line2'
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'
import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial'

但是,我当前使用的项目只支持ES5语法,所以需要将所有需要的文件都由ES6改成ES5。
以Line2.js文件为例,展示更改前后的对比

// 变更前
import LineSegments2 from "./LineSegments2.js";
import LineGeometry from "./LineGeometry.js";
import LineMaterial from "./LineMaterial.js";

class Line2 extends THREE.LineSegments2 {
    constructor(geometry = new LineGeometry(), material = new LineMaterial({
        color: Math.random() * 0xffffff
    })) {
        super(geometry, material);
        this.type = 'Line2';
    }

}
Line2.prototype.isLine2 = true;

export { Line2 }


// 变更后
(function() {
    class Line2 extends THREE.LineSegments2 {
        constructor(geometry = new LineGeometry(), material = new LineMaterial({
            color: Math.random() * 0xffffff
        })) {
            super(geometry, material);
            this.type = 'Line2';
        }
    }
    Line2.prototype.isLine2 = true;
    THREE.Line2 = Line2
})();

去除ES6 import和export,添加立即执行函数,并将值赋值给THREE

2、引入LineMaterial材质导致获取边界范围不正确

setFromObject( object: Object3D )
计算和世界轴对齐的一个对象 Object3D (含其子对象)的包围盒,计算对象和子对象的世界坐标变换。
var boxObject = new THREE.Mesh( new THREE.BoxGeometry(5, 5, 5), new THREE.MeshBasicMaterial({ color: 0xffaa00 }) );
var box = new THREE.Box3().setFromObject(boxObject);
把正方体网格作为参数,实际上是根据geometry.vertices的Vector3点集和computeBoundingBox()方法计算的。

setFromPoints( points: Vector3[] )
设置此包围盒的上边界和下边界,以包含数组 points 中的所有点。
var box = new THREE.Box3().setFromPoints([new THREE.Vector3(-2,-2,-2),
new THREE.Vector3(2,2,2)]);//返回的包围盒和上面的包围盒相同

参考: https://blog.csdn.net/m0_49399323/article/details/107461063

解决方案:
原来的:
box.setFromObject(child); //line 材质的边界值判断

更改为:
box.setFromPoints(child.geometry.vertices); //line2材质的边界值判断

相关技术点可以参考博文:

  • http://www.yanhuangxueyuan.com/doc/Three.js/lineWidth.html
  • https://segmentfault.com/a/1190000019456297
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值