I am using three js and need a way to draw lines that have a thickness greater that 1px. Whenever I use LineBasicMaterial and try to change the lineWidth property, nothing happens. There is already a reason related to Windows Chrome versions so I am asking if there are any good, working alternatives that can help me achieve thick lines.
Here is the material:
const material = new THREE.LineBasicMaterial({
color: "red",
lineWidth: 20
});
https://threejs.org/docs/#api/en/materials/LineBasicMaterial.linewidth
As in the above link said :
.linewidth : Float
Controls line thickness. Default is 1.
Due to limitations of the OpenGL Core Profile with the WebGL renderer on most platforms linewidth will always be 1 regardless of the set value.
Related
I am working on a project that uses three.js and I am using an orthographic camera. I have tried using an external MeshLine package and also the built in THREE.LineGeometry. The MeshLine has a known issue with orthographic cameras that has not been fixed and this THREE.LineGeometry (which I am focused on trying to get to work) seems to also have a problem when I use an orthographic camera. The line sort of takes its shape but it is as wide as the entire viewport, and I am not sure why it is doing this or if I can fix it with a property.
I am looking for either a solution to one of the line types I listed or any other working 2D line solutions for three.js.
This is an image of a THREE.LineGeometry that is supposed to be just a diagonal line. Those grey arrows are a part of my project, and are supposed to be there (my concern is that the line is large and clips through them currently).
Here is my code:
var lineGeometry = new LineGeometry();
lineGeometry.setPositions([0,0,0,1,0,1,2,0,2,3,0,3]);
lineGeometry.setColors([0,0,255,0,0,255,0,0,255,0,0,255]);
console.log(lineGeometry)
var lineMaterial = new LineMaterial({
color: 0xffffff,
vertexColors: true,
dashed: false,
lineWidth: 1,
});
var myLine = new Line2(lineGeometry, lineMaterial);
myLine.computeLineDistances();
this.Scene.add(myLine);
When using the LineGeometry in three.js, make sure to also set the viewport size for the line material shader either in the update loop or on window resize.
myLineMaterial.resolution.set(window.clientWidth, window.clientHeight);
I'm trying to add custom geometry to my forge viewer, following this example. It mostly works fine, except when using certain colors.
I'm using the following code to add a sphere mesh:
const geometry = new THREE.SphereGeometry(0.4, 32, 32)
const material = new THREE.MeshBasicMaterial({
color: someColor,
transparent: false,
})
const sphere = new THREE.Mesh(geometry, material)
viewer.overlays.addScene('sphere-mesh-scene')
viewer.overlays.addMesh(sphere, 'sphere-mesh-scene')
for certain values of someColor the sphere is transparent, for other values, it's not:
e.g.
#6b6e75 and #54ffff yields a transparent sphere,
while
#000000 and #988888 yields an opaque sphere.
Is there any material properties I need to set to avoid this? Or do I need to deal with the material manager in forge?
I'm using forge viewer version 7.14.0.
Edit
I also get the same result for point clouds - with a point cloud with many different colors, some of the points are transparent, and get a "glowing outline" against the Forge geometry.
This is happending because by default the blend shader determines if it should add transparency (to selected nodes for instance) by its hue color in the overlay...
We can suppress this behavior by turning useIdBufferSelection in the initOptions like below when calling viewer.start/loadModel(svf,options,cb,cb,cb,initOptions):
viewer.loadModel(svf,null,null,null,{useIdBufferSelection:true});
See live demo here
I am unable to create thick wireframes. Using the following code:
new THREE.MeshBasicMaterial( {
color: new THREE.Color( 'rgb(100,100,100)' ),
emissive: new THREE.Color( 'rgb(23,23,23)' ),
shading: THREE.FlatShading,
wireframeLinewidth: 10,
wireframe: true
})
I get the following result:
no matter what number I use the lines are always 1px thick. I've noticed that the same is true for threejs api demos page:
is this a known bug? is there any work around?
The maximum required thickness of lines in WebGL1 is 1 so basically your browser or OS or driver has a limit of 1 for line thickness.
In WebGL2 it's even more common for the limit to be 1 because it's 1 in OpenGL 4.0+ Core Profile.
From the OpenGL 4.+ specs, section 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.
While WebGL2 is based on OpenGL ES 3.0 on desktops it runs on top of OpenGL 4 or ANGLE both of which have a limit of 1. Since Firefox 51 and Chrome 56 shipped yesterday and both are using ANGLE or OpenGL 4+ on desktops that means the limit is now 1 pretty much everywhere even in WebGL1
The point of all of that is unless you only care about lines of with 1 you shouldn't use GL's line drawing to draw lines (yea, I know, sounds silly).
Instead you need to come up with some other solution.
Some links,
First a library for three.js
https://github.com/spite/THREE.MeshLine
Otherwise some articles about how to create lines
http://labs.hyperandroid.com/efficient-webgl-stroking
https://cesiumjs.org/2013/04/22/Robust-Polyline-Rendering-with-WebGL/
https://mattdesl.svbtle.com/drawing-lines-is-hard
I have a scene where one light is present, and diamonds.
Light properties:
Point light, position: 0 0 30, intensity: 1, distance 60, color: White.
The diamonds material is Phong, color:Red, no emissive, specular: White, shininess 10.
On Chrome, the diamons shine as suppose to, but on Firefox the diamonds not shine at all, and looks very dark (like have something black on it).
I have tried to use both Firefox on desktop Windows and Android mobile phone.
I would like to ask what I am missing?
Below are the settings in my code:
// Renderer:
ren=new THREE.WebGLRenderer({ antialias:true,alpha:true });
ren.shadowMap.enabled=true;
elm.appendChild(ren.domElement); // the renderer is added to a DOM element "elm"
// Light
var o=new THREE.PointLight(0xffffff,1,60);
o.position.set(0,0,30);
o.name="sun"; // light will be later added to the scene, and use "update materials" flag to update the materials of the entire scene.
// The diamond's material: (I gave a new parameter "name", for later use. I guess it should not makes trouble to the engine....)
var mt=new THREE.MeshPhongMaterial({ name:"RedDiamond", transparent:true, opacity:0.85, fog:false, color:0xff0020, specular:0xffffff, shininess:10 });
Live example can see here: https://www.crazygao.com/VideoGames/Lamps, since the first level (loading may takes a bit time only for the first time, the opening scene though is yet not complete). The lighting difference issue can be seen even in the progress scene (with the flash one)
My question: What should I do to make the diamonds shine in Firefox, but not make the entire scene too bright in Chrome? (I tried adding Ambient light to the scene, then in Chrome it becomes too bright....)
Is the problem comes from my settings, or it is the nature of Firefox? What are the best steps I can take to solve this issue?
Thanks a lot
My guess is that you're missing that the webgl canvas is composited with the HTML behind it. By default the browser expects the values of the pixels in the canvas to represent premultiplied alpha values. That means there are many possible invalid colors
Example RGBA = 1,1,1,0
That's an invalid color because since alpha = 0 and multiplying by 0 = 0 then R, G, and B also have to be zero
When the values are invalid the results are undefined and so you'll get different results on different browsers
This answers covers some of the solutions.
When I working with CanvasRendereer then linewidth of LineBasicMaterial working fine but when I switch to WebGL then its not working only default linewidth is applied in material. I found some post regarding this issue and I got idea that its not working in windows for ANGLE issue.
Is this problem still there?
If this problem is solved then how to use it or if not solved then is there any other way to implement linewidth in WebGL?
Thank you.
WebGL does not support line width for three js
See https://threejs.org/docs/index.html#api/geometries/TubeGeometry
WebGL renderer on Windows platforms linewidth will always be 1
regardless of the set value.
You could use TubeGeometry
https://github.com/jjcc1421/Three3DExtras
var line=new three3DExtras.tubeLine([-1,-1,0],[1,1,0],0.02,'#FFF');
var line2=new three3DExtras.tubeLine([-1,0,0],[1,0,0],0.02,'#E3DC1C');
var line3=new three3DExtras.tubeLine([-1,0,1],[1,0,1],0.02,'#B02735');
scene.add(line.getObject3D());
scene.add(line2.getObject3D());
scene.add(line3.getObject3D());