Javascript 使用THREE.LineBasicMaterial的线条厚度
我正在使用下面的代码在我的three.js场景中创建数百行代码Javascript 使用THREE.LineBasicMaterial的线条厚度,javascript,webgl,three.js,Javascript,Webgl,Three.js,我正在使用下面的代码在我的three.js场景中创建数百行代码 edgeGeometry[i] = new THREE.Geometry(); edgeGeometry[i].vertices[0] = v(x1,y1,z1); edgeGeometry[i].vertices[1] = v(x2,y2,z2); edgesMat[i] = new THREE.LineBasicMaterial({ color: 0x6699FF, linewidth: 1, fog:true}); e
edgeGeometry[i] = new THREE.Geometry();
edgeGeometry[i].vertices[0] = v(x1,y1,z1);
edgeGeometry[i].vertices[1] = v(x2,y2,z2);
edgesMat[i] = new THREE.LineBasicMaterial({
color: 0x6699FF, linewidth: 1, fog:true});
edge[i] = new THREE.Line(edgeGeometry[i], edgesMat[i]);
edge[i].type = THREE.Lines;
scene2.add(edge[i]);
它工作正常,但当我将“线宽”的值更改为更大或更小的值时,我在场景中看不到任何差异。我应该如何更改线条的厚度?有什么想法吗?
谢谢,Dimitris你在用Windows吗?
我记得这在Windows上不起作用,因为它没有在中实现。这发生在Windows Chrome和Firefox中,两者都使用ANGLE(WebGL到DirectX包装器) 这个问题仍然没有通过ANGLE项目解决。您可以在此处启动该问题,以获得更高的优先级,并在将要实施时获得通知: 1)使用本机OpenGL 通过将浏览器设置为使用本机OpenGL而不是ANGLE,可以通过一种变通方法实现线厚度的渲染。 请记住,如果切换到本机OpenGL,您将体验到性能差异 编辑: 杜布先生本人。 注意:第一个选项不再是有效的解决方案,因为最新的OpenGL版本也不再支持线条厚度。检查。这意味着,如果要使用线厚度,第二个选项是可行的
2) 使用
THREE.MeshLine
class
还有另一个解决办法;这是一个很好的解决办法。它带有一个特殊的THREE.MeshLineMaterial
。根据文档,它非常简单:
- 创建并填充几何图形
- 创建一个
并指定几何图形THREE.MeshLine
- 创建一个
3.MeshLineMaterial
- 使用
和THREE.MeshLine
创建THREE.MeshLineMaterial
THREE.Mesh
您可以使用CanvasRenderer而不是Webglrenderer。查看正式文档,其中每个形状都有一个线宽为10的边框 这不再只是一个角度上的问题,而是所有平台上的问题。浏览器需要切换到OpenGL 4+核心配置文件以支持WebGL2,并且OpenGL 4+核心配置文件不支持大于1的线宽。来自OpenGL 4.0+规范,第E.2.1节 E.2.1已弃用但仍受支持的功能 以下功能已弃用,但仍存在于核心配置文件中。它们可以从OpenGL的未来版本中删除,并在实现核心概要文件的前向兼容上下文中删除
- 宽线-大于1.0的线宽值将生成无效的_值错误
您可以使用为加厚(多边形)线生成网格并将其转换为three.js网格来实现相同的效果:
const THREE = require('three');
const extrudePolyline = require('extrude-polyline');
const Complex = require('three-simplicial-complex')(THREE);
function thickPolyline(points, lineWidth) {
const simplicialComplex = extrudePolyline({
// Adjust to taste!
thickness: lineWidth,
cap: 'square', // or 'butt'
join: 'bevel', // or 'miter',
miterLimit: 10,
}).build(points);
// Add a z-coordinate.
for (const position of simplicialComplex.positions) {
position[2] = 0;
}
return Complex(simplicialComplex);
}
const vertices = [[0, 0], [10, 0], [10, 10], [20, 10], [30, 00]];
const geometry = thickPolyline(vertices, 10);
const material = new THREE.MeshBasicMaterial({
color: 0x009900,
side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
如果要对多段线进行纹理贴图,事情会变得更复杂。我使用TubeGeometry在两点之间创建一条粗线: 请参见螺旋中的绿线 谢谢你给我指出了正确的方向 这可能比他们想象的要稍微复杂一些,但是。。。下面是我的解决方案,非常仔细地遵循他们的文档和代码。。。(假设已经包含了三个和网格线):
renderer=new THREE.WebGLRenderer({canvas});
//...
函数createCircle(分辨率){
设圆几何=新的三点几何();
对于(让rotation=0;rotation是的,我使用的是Windows 7。既然你提到了它,那一定是因为我一个月前在Ubuntu上运行了我的应用程序,宽度发生了完美的变化。我怎样才能让它在Windows中也能工作呢?嗯,不确定……这是一个角度限制。我不知道他们是否可以添加它。至少现在可以快速回复Thanx我知道这不是我的代码中的错误导致的问题…很遗憾。无论我尝试什么,我在一开始总是遇到麻烦,我可能需要成为一名QA。我尝试过实现简单的时钟映像,现在我必须覆盖线宽问题)我想我们可以尝试使用矩形代替线(2倍宽的矩形)这也发生在我的OS X Chrome上,我刚刚发现了这个报告:虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生变化,只有链接的答案可能会无效。-@Serafeim link只是一个例子。答案是使用canvasRenderer。使用本机OpenGL不再是一个解决方案-也许你想更新你的答案?@gman谢谢你的评论。你能添加一些关于此信息来源的参考资料吗。然后我可以更新我的问题并添加对该来源的参考资料。是的,请参阅我的答案。三。网格线不支持buffergeometry。有人知道我可以如何让它与buffergeometry一起工作?不是最好的选项,不受三个参数的影响。您可能会感兴趣。该PR使用着色器生成恒定厚度的线。如果您希望生成在世界坐标中确实具有特定厚度的多段线(例如,从其中心线生成道路),那么这种方法就更有意义了。截至今天(26 Frb 2018),Safari实际上仍然正确地渲染线宽>1,而最新的Chrome没有;是的,我在那里使用了一个不正确的词。它真的很糟糕,规格更改了,但这就是生活;)。可能会使用github的THREE.LineMesh。WebGL规范没有改变,实现了。规范一直说1是所有必须支持的,而在windows上对大多数人来说,这是所有支持的。如果你想要lines>1,并且你想让你的应用程序在任何地方都能工作,那么你就必须始终实现像这样的解决方案THREE.MeshLine.是的,我现在使用THREE.MeshLine:)。干杯。我有超过10k条线,所以THREE.MeshLine对我来说不够。我能做什么?在服务器上将线挤出到网格?您好,根据THREE.JS:“由于限制
// line material
var lineMaterial = new THREE.LineBasicMaterial({ color: 0x00ff00 });
let startVector = new THREE.Vector3(
RADI * Math.cos(t),
RADI * Math.sin(t),
3 * t
);
let endVector = new THREE.Vector3(
RADI * Math.cos(t + 10),
RADI * Math.sin(t + 10),
3 * t
);
let linePoints = [];
linePoints.push(startVector, endVector);
// Create Tube Geometry
var tubeGeometry = new THREE.TubeGeometry(
new THREE.CatmullRomCurve3(linePoints),
512,// path segments
0.5,// THICKNESS
8, //Roundness of Tube
false //closed
);
let line = new THREE.Line(tubeGeometry, lineMaterial);
scene.add(line);
renderer = new THREE.WebGLRenderer({ canvas });
//...
function createCircle(resolution) {
let circleGeometry = new THREE.Geometry();
for (let rotation = 0; rotation <= Math.PI * 2.0; rotation += Math.PI * 0.1) {
circleGeometry.vertices.push(
new THREE.Vector3(Math.cos(rotation), Math.sin(rotation), 0));
}
let circleLine = new MeshLine();
circleLine.setGeometry(circleGeometry);
//Bonus: parabolic width! (See Z rotation below.)
//circleLine.setGeometry(circleGeometry, function(point) {
//return Math.pow(4 * point * (1 - point), 1);
//});
//Note: resolution is *required*!
return new THREE.Mesh(circleLine.geometry,
new MeshLineMaterial({
color: 'blue',
resolution,
sizeAttenuation: 0,
lineWidth: 5.0,
side: THREE.DoubleSide
}));
}
let circle = createCircle(new THREE.Vector2(canvas.width, canvas.height));
circle.rotation.x = Math.PI * 0.5;
circle.position.y = 20.0;
scene.add(circle);
//In update, to rotate the circle (e.g. if using parabola above):
world.circle.rotation.z += 0.05;