Why doesn't THREE.js LineGeometry work with orthographic camera? - three.js

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);

Related

Overlay mesh is transparent for certain material colors in Forge 3D viewer

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

lensflare disppearing and rendering too slow

I'm trying to get lensflare to work in ThreeJS.
It seem to function okay when there is distance to camera but if I camera is moved to about 50 units or less distance to lensflare the flare disappears! Why?
Update:
After further investigation I noticed that lensflare works fine in webgl_lensflares.html example. The problem is when I try to add it to ThreeJS Editor. Adding it to Editor causes 3 problems:
Rendering becomes painfully slow.
When I rotate the scene the lensflare rotates fine, but when I move the scene the lensflare moved the opposite direction.
If I put the lensflare at (0,0,0) it disappears when I get too close to it, but if I put it in locations away from origin such as (0,10,0) it doesn't have that problem.
Here is the code that I added to Editor in Viewport.js:
var textureLoader = new THREE.TextureLoader();
var textureFlare0 = textureLoader.load("textures/lensflare/lensflare0.png");
var flareColor = new THREE.Color(0xffffff);
flareColor.setHSL(0.55, 0.9, 0.5 + 0.5);
var lensFlare = new THREE.LensFlare(textureFlare0, 100, 1.0, THREE.AdditiveBlending, flareColor);
lensFlare.position.set(0, 0, -10);
scene.add(lensFlare);
I figured out the answer to all my 3 problems:
Netbean debugger was slowing down the rendering. Once I turned off Netbean debugger it became much faster. I still notice flare rendering slows down rendering a little but it's at least usable now.
The reason lensfare would move the opposition direction was because I passed 1.0 as its 3rd parameter. Should've been 0.0
The reason why at (0,0,0) I don't see the flare is because there is another shape located on that position. Apparently flare is not visible if it is position insider another shape. I had wrongly assumed that flare is rendered last and hence always visible.

exporting a scene from blender to threejs: every object has just one single material

I have made a small scene in blender (6 objects, each using 1 to 4 materials).
When exporting this (using the materials, and the scene option) with the dev exporter and loading it via:
var loader = new THREE.ObjectLoader();
loader.load( 'assets/scene.json', function ( scene ) { ...
And then checking the scene, I can see it has 6 children (good) and that each of the five children only has one MeshLambertMaterial (instead of the material mix from blender) bad.
Any hints on what I am doing wrong?
Those are btw basic materials (just a color basically) no textures or anything.
The scene renders correctly (minus the material mix).
Here is a link to the 113kb scene file (zipped): http://jppresents.net/static/blender/exportBug/scene.zip
Looking at the file I think all materials are there - so the problem must be the way I load it?
Not a solution, but a work around:
Since the only difference between all my materials was just the color, I have now applied exactly one material with a multi colored texture per object.
Then I uv-mapped the faces of the object to the colors corresponding to the previously set material color.
This was easy using the hotkey "shift + G" which lets you select all faces with the same material. (Then just assign them to the texture material, move/scale those in the uv-view to the part of the texture that matches the old color.)

Three.js shading of complex model looks strange

We have a model created in Blender by subtracting an extruded SVG from a “flat” base using a boolean difference operator. Or in other words, we carved a picture into it. The model renders just fine in Blender, but loading it into our simple, three.js-based web viewer (using the json exporter for Blender), we get some really odd shadows on the surface, and depending on the scale, shiny vertexes.
Here's my light and camera:
camera = window.camera = new THREE.PerspectiveCamera(45, $('main').width() / $('main').height(), 10, 10000);
loader = new THREE.JSONLoader(true);
var light = new THREE.DirectionalLight(0xffffff, 1.0);
light.position.set(-30, 30, 100);
light.target.position.set(0, 0, 0);
light.shadowCameraNear = 200;
Can anyone spot whether we did something wrong? And is that a Three-specific issue, or WebGL, or Blender, or our model?
Output (screenshot)
Fiddle
Looking at your fiddle, it seems that your vertexNormals are totally smoothed and thus shading is incorrect.
See here:
https://github.com/mrdoob/three.js/issues/1258
Does this help?
I'm not sure if this technically counts as a solution, but — worked around the problem by dropping the JSON blender export, and using P3D instead to load .stl directly.

Threejs sprite ordering

I'm having an issue rendering sprites using Three.js, to complicate the issue further I'm using a game engine voxel.js to manage the instance.
Example: http://christopherdebeer.com/sandbox/voxeljs/
I've tried messing with depth{write|test}:
material = new game.THREE.SpriteMaterial({
map: spriteB,
useScreenCoordinates: false,
alignment: game.THREE.SpriteAlignment.bottomCenter,
color: 0xffffff,
fog: true,
depthWrite: true,
depthTest: false
});
for the semi transparent meshes on the left of the example.
What I need is a transparent mesh or voxel to give a volume of space some substance while displaying a 2d sprite at that position.
How can I solve this issue, or what am I doing wrong?
This is almost exactly a year after you needed it, but #WestLangley described how sprites are rendered last and thus do not play well with transparent objects. He provides some tips on working around this.
three.js - cannot view a sprite through a mesh with transparency?
It seems to be an alpha test missing to me: try to add the parameter alphaTest: 0.5 to the parameters you pass to the SpriteMaterial and see if it helps (try with depthTestset to true)

Resources