Overlay mesh is transparent for certain material colors in Forge 3D viewer - three.js

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

Related

Three.js emissive materials don't cast shadow

Conext
I'm using three.js, #react-three/drei and #react-three/fiber.
I'm loading a GLTF file that contains emissive materials using
const gltf = useLoader(GLTFLoader, '/model.glb')
When I inspect the loaded data like this:
for (const key of Object.keys(gltf.materials)) {
const v = gltf.materials[key] as MeshStandardMaterial & Material
if (!v.isMeshStandardMaterial) return
console.log(key, v, v.emissive, v.emissiveIntensity, v.emissiveMap)
}
I can see that certain materials have a color set and their emissiveIntensity is equal to 1.
Problem
Objects made of these emissive materials load and display correctly on the scene. They have the desired color. There is, however, one problem. I would like those emissive materials to behave like a directonalLight/pointLight - i.e. cast shadows and cause reflections. Right now, they only display as shiny blobs, but their light doesn't affect other objects.
Question
How do I make emissive materials cast shadows and create reflections? Do I need a shader or is there some hidden option that I'm not seeing?

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

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

Forge MeshPhongMaterial transparent color

In Forge Viewer I added and I tried to set color for THREE.PlaneBufferGeometry to #384c70 and as Material I used THREE.MeshPhongMaterial(). But there is a problem because that Color is transparent. If I used the same Color in THREEjs sandbox then it was right without transparent. Where is a problem?
I don't need transparent color. This error is also present for other colors not for all.
Thanks.
There is a example of my code:
this.viewer.overlays.addScene("custom-scene");
let plane = new THREE.PlaneBufferGeometry(100, 100);
let material = new THREE.MeshPhongMaterial();
material.color = new THREE.Color("#384c70");
material.side = THREE.DoubleSide;
let mesh = new THREE.Mesh(plane, material);
mesh.position.set(0, 0, 0);
this.viewer.overlays.addMesh(mesh, "custom-scene");
this.viewer.impl.sceneUpdated(true);
This is a kind of a weird bug in Forge Viewer when using a certain kind of color in an overlay. The reason is - the overlay rendering pipeline uses a custom shader logic for turning a specific range of colors into a see-through selection highlight.
It's definitely something the viewer needs to fix but in the meantime, I'd suggest avoiding the overlays and adding your custom geometry using ModelBuilder instead.

Setting a texture in ThreeJS does nothing

I'm trying to set a texture to an already existing mesh like this:
const texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
(The source a HTML5 canvas and that part works ok.)
...
mesh.material[0].map = texture;
I can change the material color without any problems, but setting the texture doesn't change anything. I guess this is not how changing the texture should be done..? I'm using MeshPhongMaterial.
So, long story short: I want to be able dynamically change a texture of an mesh.
Edit:
I'm trying to set the texture to one of the materials of a Collada model that is loaded. By using dev tools I can see that the texture is there in the object, but it is just not visible. I can change the color of the same material without any problems. Sometimes I can see the texture appearing with wrong colors after a very long idle time (which is weird).

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

Resources