我正在使用下面的代码在我的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});
edge[i] = new THREE.Line(edgeGeometry[i], edgesMat[i]);
edge[i].type = THREE.Lines;
scene2.add(edge[i]);
它工作正常,但当我将“linewidth”的值更改为更大或更小的值时,我看到场景中没有区别。
我该如何改变线条的粗细?任何想法?
谢谢,迪米特里斯
答案 0 :(得分:21)
通过将浏览器设置为使用本机OpenGL而不是ANGLE,可以通过解决方法实现线条粗细的渲染。 You can read here on how to do this on Chrome。 请记住,如果您更换为原生OpenGL,您将遇到性能差异。
修改强>
主人MrDoob本人posted here how to do this for both Chrome and Firefox。
击>
注意: 第一个选项不再是有效的解决方案,因为最新的OpenGL版本也不再支持线宽。检查also @gman his answer。这意味着如果你想使用线条粗细,第二个选项就是你要去的地方。
THREE.MeshLine
class 还有另一种解决方案; this THREE.MeshLine
class on github是一个很好的解决方法。它带有一个特殊的THREE.MeshLineMaterial
。根据文档,它很简单:
- 创建并填充几何
- 创建
THREE.MeshLine
并指定几何- 创建
THREE.MeshLineMaterial
- 使用
THREE.MeshLine
和THREE.MeshLineMaterial
创建THREE.Mesh
答案 1 :(得分:18)
您使用的是Windows吗? 我记得这不适用于Windows,因为它没有在ANGLE中实现。
答案 2 :(得分:12)
这种情况发生在Windows Chrome和Firefox中,都使用ANGLE(WebGL到DirectX包装器)。
ANGLE项目仍然没有解决这个问题。你可以在这里解决问题,以获得更高的优先级,并获得通知,如果它将被实施:
答案 3 :(得分:3)
这已不再是ANGLE中的一个问题,它在所有平台上都是一个问题。浏览器需要切换到OpenGL 4+核心配置文件以支持WebGL2和OpenGL 4+核心配置文件不支持大于1的行宽。从OpenGL 4.0+规范,E.2.1节
E.2.1不推荐但仍支持的功能
以下功能已弃用,但仍存在于核心配置文件中。它们可能会从未来版本的OpenGL中删除,并在实现核心配置文件的前向兼容上下文中删除。
- 宽行 - 大于1.0的LineWidth值将生成INVALID_VALUE错误。
要绘制较粗的线条,您需要生成几何体。对于three.js,有这个库(Wilt也指出)
答案 4 :(得分:1)
您可以使用CanvasRenderer而不是Webglrenderer。查看ifficial文档here,其中每个形状的边框线宽= 10;
答案 5 :(得分:1)
您可以使用extrude-polyline
为增厚(多边形)线生成simplicial complex并使用three-simplicial-complex
将其转换为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);
这是一个complete example以及source。 (目前有一个issue on requirebin阻止它呈现源代码示例。)
如果你想对折线进行纹理贴图,事情会变得复杂一些。
答案 6 :(得分:1)
我使用TubeGeometry在两点之间创建粗线:
查看Helix中的绿线
// 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
);
//add buffer geometry
let tubeBufferGeomtry = new THREE.BufferGeometry().fromGeometry(
tubeGeometry
);
let line = new THREE.Line(tubeGeometry, lineMaterial);
scene.add(line);
答案 7 :(得分:0)
感谢Wilt's answer用THREE.MeshLine指向正确的方向。
这可能比他们想像的要复杂一些,但是...所以这是我非常仔细地遵循他们的文档和demo代码的解决方案...(假设您已经包含了Three和MeshLine ):
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;
关闭大小衰减并使用THREE.DoubleSide
,就像我在上面所做的那样,无论您从何处看,圆都将看起来像是一个不错的,一致的圆(不是“真实3D”)。
只需一行,您显然可以轻松适应。
答案 8 :(得分:0)
为什么不将不透明度设置为 0.1 之类的? 注意:这仅在您为某物设置边框时才有效,如果它背后没有任何内容,它将无法工作。