Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用THREE.LineBasicMaterial的线条厚度_Javascript_Webgl_Three.js - Fatal编程技术网

Javascript 使用THREE.LineBasicMaterial的线条厚度

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

我正在使用下面的代码在我的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]);
它工作正常,但当我将“线宽”的值更改为更大或更小的值时,我在场景中看不到任何差异。
我应该如何更改线条的厚度?有什么想法吗?
谢谢,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,有一个库(Wilt也指出了这一点)


您可以使用为加厚(多边形)线生成网格并将其转换为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;