Javascript 使用 THREE.LineBasicMaterial 的线条粗细
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11638883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thickness of lines using THREE.LineBasicMaterial
提问by Dimitris
I am using the code below to create hundreds of lines in my three.js scene
我正在使用下面的代码在我的 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]);
It works just fine, but when i change the value of "linewidth" to a bigger OR smaller value, i see NO difference in the scene.
How should i change the thickness of the lines? Any ideas?
Thanks, Dimitris
它工作得很好,但是当我将“线宽”的值更改为更大或更小的值时,我看不到场景中的任何差异。
我应该如何更改线条的粗细?有任何想法吗?
谢谢,迪米特里斯
采纳答案by mrdoob
回答by Wilt
1) Use native OpenGL
1) 使用原生 OpenGL
You can achieve rendering of line thicknesses with a workaround by setting your browser to use native OpenGL instead of ANGLE. You can read here on how to do this on Chrome. Keep in mind that you will experience performance differences if you swap to native OpenGL.
EDIT:
您可以通过将浏览器设置为使用本机 OpenGL 而不是 ANGLE 来通过变通方法实现线条粗细的渲染。您可以在此处阅读有关如何在 Chrome 上执行此操作的信息。请记住,如果您切换到本机 OpenGL,您将遇到性能差异。
编辑:
The master MrDoob himself posted here how to do this for both Chrome and Firefox.
MrDoob 大师自己在这里发布了如何为 Chrome 和 Firefox 执行此操作。
Note:This first option is no longer a valid solution since the latest OpenGL versions no longer support line thickness either. Check also @gman his answer. This means if you want to use line thickness the second option is the way to go.
注意:第一个选项不再是有效的解决方案,因为最新的 OpenGL 版本也不再支持线条粗细。也检查@gman 他的回答。这意味着如果您想使用线条粗细,则可以选择第二个选项。
2) Use THREE.MeshLine
class
2)使用THREE.MeshLine
类
There is also another solution; this THREE.MeshLine
class on githubis a nice workaround. It comes with a special THREE.MeshLineMaterial
. According to the docs it is as simple as:
还有另一种解决方案;github上的这个THREE.MeshLine
类是一个很好的解决方法。它带有一个特殊的THREE.MeshLineMaterial
. 根据文档,它很简单:
- Create and populate a geometry
- Create a
THREE.MeshLine
and assign the geometry- Create a
THREE.MeshLineMaterial
- Use
THREE.MeshLine
andTHREE.MeshLineMaterial
to create aTHREE.Mesh
- 创建和填充几何体
- 创建一个
THREE.MeshLine
并分配几何- 创建一个
THREE.MeshLineMaterial
- 使用
THREE.MeshLine
和THREE.MeshLineMaterial
创建一个THREE.Mesh
回答by user2090712
This occurs in Windows Chrome and Firefox, both using ANGLE (WebGL to DirectX wrapper).
这发生在 Windows Chrome 和 Firefox 中,两者都使用 ANGLE(WebGL 到 DirectX 包装器)。
The issue is still not solved by the ANGLE project. You can star the issue here to get higher priority and get a notification if it's going to be implemented:
这个问题仍然没有被 ANGLE 项目解决。您可以在此处为问题加星标以获得更高的优先级并在要实施时收到通知:
回答by gman
This is no longer an issue just in ANGLE it's an issue on all platforms. Browsers needed to switching to the OpenGL 4+ core profile to support WebGL2 and the OpenGL 4+ core profile does not support line widths greater than 1. From the OpenGL 4.0+ spec, section E.2.1
这不再是 ANGLE 的问题,而是所有平台的问题。浏览器需要切换到 OpenGL 4+ 核心配置文件以支持 WebGL2,而 OpenGL 4+ 核心配置文件不支持大于 1 的线宽。来自 OpenGL 4.0+ 规范的 E.2.1 部分
E.2.1 Deprecated But Still Supported Features
The following features are deprecated, but still present in the core profile. They may be removed from a future version of OpenGL, and are removed in a forward compatible context implementing the core profile.
- Wide lines - LineWidth values greater than 1.0 will generate an INVALID_VALUE error.
E.2.1 已弃用但仍受支持的功能
以下功能已弃用,但仍存在于核心配置文件中。它们可能会从 OpenGL 的未来版本中删除,并在实现核心配置文件的前向兼容上下文中删除。
- 宽线 - LineWidth 值大于 1.0 将生成 INVALID_VALUE 错误。
To draw thicker lines you need generate geometry. For three.js there is this library (pointed out by Wilt as well)
要绘制更粗的线条,您需要生成几何图形。对于three.js,有这个库(Wilt也指出)
回答by Hitesh Sahu
I use TubeGeometry to create a Thick line between two points:
我使用 TubeGeometry 在两点之间创建一条粗线:
See Green lines in Helix
参见 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);
回答by danvk
You can achieve the same effect using extrude-polyline
to generate a simplicial complexfor the thickened (poly)line and three-simplicial-complex
to convert this to a three.js Mesh:
您可以使用extrude-polyline
为加粗(多边形)线生成单纯复形并将three-simplicial-complex
其转换为three.js Mesh来实现相同的效果:
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);
Here's a complete examplealong with the source. (There's currently an issue on requirebinthat prevents it from rendering the source example).
这是一个完整的示例以及源代码。(目前requirebin 上存在一个问题,阻止它呈现源示例)。
If you want to texture map the polyline, things get a little more complicated.
如果您想对折线进行纹理贴图,事情会变得稍微复杂一些。
回答by raulsi
回答by Andrew
Thanks to Wilt's answerfor pointing me in the right direction with THREE.MeshLine.
感谢Wilt 的回答为我指出了正确的方向THREE.MeshLine。
It can be slightly trickier than they make it out to be, however... So here's my solution following their docs and their democode very carefully... (assuming you've already included Three and MeshLine):
然而,这可能比他们想象的要复杂一些……所以这是我非常仔细地遵循他们的文档和演示代码的解决方案……(假设您已经包含了 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;
With size attenuation off and using THREE.DoubleSide
, like I did above, the circle will look like a nice, consistent circle no matter where you're looking at it from (not "true 3D").
关闭尺寸衰减并使用THREE.DoubleSide
,就像我在上面所做的那样,无论您从哪里看,该圆都会看起来像一个漂亮的、一致的圆(不是“真正的 3D”)。
For just a line, you can obviously easily adapt.
对于一行,您显然可以轻松适应。