最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Workaround for lack of line width on Windows when using Three.js - Stack Overflow

programmeradmin1浏览0评论

I'm trying to draw a rotating 3D coordinate system using Three.js. I want the axes to have some thickness, which so far I have acplished using LineBasicMaterial's linewidth parameter.

The following code works for me since I am not on 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

What can I use as a workaround so that this displays correctly on Windows?

I'm trying to draw a rotating 3D coordinate system using Three.js. I want the axes to have some thickness, which so far I have acplished using LineBasicMaterial's linewidth parameter.

The following code works for me since I am not on 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

What can I use as a workaround so that this displays correctly on Windows?

Share Improve this question edited May 23, 2017 at 10:29 CommunityBot 11 silver badge asked Jan 11, 2014 at 20:26 nhamnham 1751 silver badge8 bronze badges 1
  • You could create CylinderGeometry with the specific length and orientate the cylinders. For smoother stuff, you could try setting up splines and extruding along those splines like in this example: threejs/examples/#webgl_geometry_extrude_splines Also you can figure stuff out with your own approach and creating your own Geometry, depending on your needs but I think setting up a few cylinders for your coordinate system should be ok? Also you can tell Firefox for example to use native OpenGL drivers and then having linewidth under windows but this is slower in most cases... – GuyGood Commented Jan 12, 2014 at 13:21
Add a ment  | 

4 Answers 4

Reset to default 2

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.

You have these options below:

  1. Google Chrome "solution": "run chrome with the --use-gl=desktop mand-line argument. As you can see in http://nuclear.mutantstargoat./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/viewtopic.php?f=23&t=2090351&start=15

By using Angle the rendering is actually handled by DirectX. Switching to native gl can even lead to performance increase (depending on the OpenGL performance of your graphics card).

You can check the current "under the hood" WebGL settings of your browser using this website here . It also shows you if your browser is currently using angle for WebGL.

You can also check this website for detailed explanation of how to switch to native gl.

There are many possibilities -- I have used cylinders. This routine gives flat lines in the xy plane:

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) );
    }
  }
}
发布评论

评论列表(0)

  1. 暂无评论