45

我正在使用下面的代码在我的 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]);

它工作得很好,但是当我将“线宽”的值更改为更大或更小的值时,我发现场景没有区别。
我应该如何改变线条的粗细?有任何想法吗?
谢谢, 迪米特里斯

4

9 回答 9

33

1)使用原生OpenGL

您可以通过将浏览器设置为使用原生 OpenGL 而不是 ANGLE 来实现线条粗细的渲染。您可以在此处阅读如何在 Chrome 上执行此操作。请记住,如果您切换到原生 OpenGL,您将体验到性能差异。

编辑:

大师 MrDoob 本人在这里发布了如何为 Chrome 和 Firefox 执行此操作

注意: 第一个选项不再是有效的解决方案,因为最新的 OpenGL 版本也不再支持线条粗细。还要检查@gman 他的答案。这意味着,如果您想使用线条粗细,第二个选项就是您要走的路。


2)使用THREE.MeshLine

还有另一种解决方案;github上的这个THREE.MeshLine类是一个很好的解决方法。它带有一个特殊的THREE.MeshLineMaterial. 根据文档,它很简单:

  • 创建和填充几何
  • 创建THREE.MeshLine并分配几何
  • 创建一个THREE.MeshLineMaterial
  • 使用THREE.MeshLineTHREE.MeshLineMaterial创建一个THREE.Mesh
于 2014-09-10T07:07:37.210 回答
21

你在使用 Windows 吗?
我记得这在 Windows 上不起作用,因为它没有在ANGLE中实现。

于 2012-07-25T00:05:21.563 回答
12

这发生在 Windows Chrome 和 Firefox 中,两者都使用 ANGLE(WebGL 到 DirectX 包装器)。

ANGLE项目仍然没有解决这个问题。您可以在此处为问题加注星标以获得更高的优先级,并在将要实施时收到通知:

https://code.google.com/p/angleproject/issues/detail?id=119

于 2013-05-23T13:38:14.303 回答
8

我使用 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
  );

  let line = new THREE.Line(tubeGeometry, lineMaterial);
  scene.add(line);
于 2019-05-09T13:47:18.073 回答
5

这不再只是 ANGLE 中的问题,而是所有平台上的问题。浏览器需要切换到 OpenGL 4+ 核心配置文件以支持 WebGL2,而 OpenGL 4+ 核心配置文件不支持大于 1 的线宽。来自 OpenGL 4.0+ 规范,E.2.1 节

E.2.1 已弃用但仍受支持的功能

以下功能已弃用,但仍存在于核心配置文件中。它们可能会从 OpenGL 的未来版本中删除,并在实现核心配置文件的前向兼容上下文中删除。

  • 宽线 - LineWidth 值大于 1.0 将生成 INVALID_VALUE 错误。

要绘制较粗的线条,您需要生成几何图形。对于three.js,有这个库(Wilt 也指出)

https://github.com/spite/THREE.MeshLine

于 2017-01-28T15:30:58.383 回答
1

您可以使用 CanvasRenderer 代替 Webglrenderer。在此处查看官方文档,其中每个形状的边框线宽 = 10;

于 2015-12-17T06:18:37.537 回答
1

您可以使用为加厚(多段)线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);

如果你想对折线进行纹理贴图,事情会变得有点复杂。

于 2017-11-09T15:24:13.653 回答
0

感谢Wilt 的回答,他用THREE.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;

关闭尺寸衰减并使用THREE.DoubleSide,就像我在上面所做的那样,无论你从哪里看它(不是“真正的 3D”),这个圆圈都会看起来像一个漂亮、一致的圆圈。

只需一行,您显然可以轻松适应。

于 2020-04-19T22:54:05.177 回答
0

为什么不将不透明度设置为 0.1 之类的?注意:这仅在您为某物设置边框时才有效,如果它后面没有任何东西,它将不起作用。

于 2021-07-15T06:51:23.337 回答