简体   繁体   English

使用 Three.js 时在 Windows 上缺少线宽的解决方法

[英]Workaround for lack of line width on Windows when using Three.js

I'm trying to draw a rotating 3D coordinate system using Three.js.我正在尝试使用 Three.js 绘制旋转 3D 坐标系。 I want the axes to have some thickness, which so far I have accomplished using LineBasicMaterial's linewidth parameter.我希望轴具有一定的厚度,到目前为止我已经使用 LineBasicMaterial 的线宽参数完成了这一点。

The following code works for me since I am not on Windows:以下代码对我有用,因为我不在 Windows 上:

    var scene = new THREE.Scene();                                              
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.   innerHeight, 0.1, 1000 );                                                           

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

    var triad = new THREE.Geometry();
    triad.vertices.push( new THREE.Vector3(  0,  0,  0 ) ); 
    triad.vertices.push( new THREE.Vector3( 10,  0,  0 ) );
    triad.vertices.push( new THREE.Vector3(  0,  0,  0 ) );
    triad.vertices.push( new THREE.Vector3(  0, 10,  0 ) );
    triad.vertices.push( new THREE.Vector3(  0,  0,  0 ) );
    triad.vertices.push( new THREE.Vector3(  0,  0, 10 ) );

    var line_mat = new THREE.LineBasicMaterial({'linewidth': 3});

    var frame = new THREE.Line(triad, line_mat, THREE.LinePieces);
    scene.add( frame );                       
    camera.position.z = 40;                        

    function render() {                    
        requestAnimationFrame(render);             
        frame.rotation.x += 0.1;            
        frame.rotation.y += 0.02;             
        renderer.render(scene, camera);                            
    }                                                                           
    render();

Unfortunately, there is a limitation on linewidth on Windows due to the ANGLE library, see this question: Thickness of lines using THREE.LineBasicMaterial不幸的是,由于 ANGLE 库,Windows 上的线宽存在限制,请参阅此问题: 使用 THREE.LineBasicMaterial 的线宽

What can I use as a workaround so that this displays correctly on Windows?我可以使用什么作为解决方法,以便在 Windows 上正确显示?

I got workaround for the width of the line.我得到了线宽的解决方法。 I created a new method and passed the coordinates where line is to be drawn.我创建了一个新方法并传递了要绘制线条的坐标。 Then in your method , draw multiple lines around the coordinates.然后在您的方法中,围绕坐标绘制多条线。 Here is the code :这是代码:

function drawLine(lineMaterial, x1, y1 , z1, x2, y2, z2, thickness){
    for (i = 0; i < thickness * 2; i++) {  // multiplied it by 2 to be more granule pixels
        var routerLine1Geometry = new THREE.Geometry();
        routerLine1Geometry.vertices.push( new THREE.Vector3(x1, y1+i/4, z1));//divided it by 4 to be more granule pixels 

        routerLine1Geometry.vertices.push( new THREE.Vector3(x2, y2+i/4, z2)  );
        var routerLine1 = new THREE.Line( routerLine1Geometry, lineMaterial );
        scene.add(routerLine1);
    }
    for (i = 0; i < thickness * 2; i++) { 
        var routerLine1Geometry = new THREE.Geometry();
        routerLine1Geometry.vertices.push( new THREE.Vector3(x1, y1-i/4, z1)  );  // 
        routerLine1Geometry.vertices.push( new THREE.Vector3(x2, y2-i/4, z2)  );
        var routerLine1 = new THREE.Line( routerLine1Geometry, lineMaterial );
        scene.add(routerLine1);
    }
}

Let me know if this doesnt work.如果这不起作用,请告诉我。

To run WebGL with native gl you have to install the OpenGL in your windows machine.要使用本机 gl 运行 WebGL,您必须在 Windows 机器中安装 OpenGL。

You have these options below:您有以下选项:

  1. Google Chrome "solution": "run chrome with the --use-gl=desktop command-line argument. As you can see in http://nuclear.mutantstargoat.com/webgl/谷歌浏览器“解决方案”:“使用--use-gl=desktop命令行参数运行 chrome。正如您在http://nuclear.mutantstargoat.com/webgl/ 中看到的那样
  2. Firefox "solution": "Just type in navigation bar about:config and search for preference webgl.prefer-native-gl and set to true . As you can see in " http://forums.mozillazine.org/viewtopic.php?f=23&t=2090351&start=15 Firefox“解决方案”:“只需在导航栏中输入about:config并搜索首选项webgl.prefer-native-gl并设置为true 。正如您在“ http://forums.mozillazine.org/viewtopic.php? f=23&t=2090351&start=15

By using Angle the rendering is actually handled by DirectX.通过使用 Angle,渲染实际上是由 DirectX 处理的。 Switching to native gl can even lead to performance increase (depending on the OpenGL performance of your graphics card).切换到原生 gl 甚至可以提高性能(取决于显卡的 OpenGL 性能)。

You can check the current "under the hood" WebGL settings of your browser using this website here .您可以在此处使用本网站检查浏览器当前的“幕后”WebGL 设置。 It also shows you if your browser is currently using angle for WebGL.它还显示您的浏览器当前是否正在为 WebGL 使用角度。

You can also check this website for detailed explanation of how to switch to native gl.您还可以查看此网站以获取有关如何切换到原生 gl 的详细说明。

There are many possibilities -- I have used cylinders.有很多可能性——我用过气缸。 This routine gives flat lines in the xy plane:此例程在 xy 平面中给出平线:

function doline(x1, y1, x2, y2, z, w, color) { // draw a "line"
  // scene.add(doline(x1, y1, x2, y2, z, w, 0xrrggbb)) call like this
  if (typeof color == "undefined") color = 0xffffff;
  color = new THREE.Color( color );
  var d = Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); // length
  var geometry = new THREE.Geometry;
  var material = new THREE.MeshBasicMaterial({ color:color, side:THREE.DoubleSide });
  var u1=w*.35, u2=w*.5, v1=0, v2=w*.15, v3=w*.5, v4=w*.85, v5=w; // rounded ends
  fan(geometry, 0, -w/2, z, [[-u1, v2],[-u2, v3],[-u1, v4],[0, v5],[ d, v5]]); // left
  fan(geometry, d,  w/2, z, [[ u1,-v2],[ u2,-v3],[ u1,-v4],[0,-v5],[-d,-v5]]); // right
  geometry.rotateZ(Math.atan2(y2-y1,x2-x1)); // rotate first
  geometry.translate(x1,y1,0);               // then translate
  var mesh = new THREE.Mesh(geometry, material);
  return mesh;
  function fan(geom, x0, y0, z0, pts) { // add vertices and faces in xy plane based on x0, y0, z0
    // pts must be 2 or more points relative to x0,y0 [[x1,y1],[x2,y2],..]
    geom.vertices.push(new THREE.Vector3(x0, y0, z0)); // base point
    var i0 = geom.vertices.length-1; // add to vertices
    for (var i1=0; i1<pts.length; i1+=1) { // 
      geom.vertices.push(new THREE.Vector3(x0+pts[i1][0], y0+pts[i1][1], z0));
      if (i1 > 0) geom.faces.push(new THREE.Face3( i0, i0+i1, i0+i1+1) );
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM