THREE.JS - Reflections in the windows of a building - three.js

I created a building with Blender and imported it in three.js. I managed to give the windows of the building a semi-reflective effect with a cube camera and this line:
geometry.materials[3] = new THREE.MeshLambertMaterial( { color: 0x0000ff, ambient:0x0000aa, envMap: cubeCamera.renderTarget, reflectivity: 0.7, refractionRatio: 0.25 } );
geometry.materials[3] is the Blender material for my windows. Problem is, that this building I created, is a skyscraper and it happens to have plenty of windows. If I do it like above, I get the same reflection in every single window, because there are other materials between the windows and every window-material is isolated from the next window-material by the wall-material. But I would like to have one big reflection over all windows, like if the whole building was only made out of one material. The reflection should only appear in the windows and not on the walls. Windows are all the same material. Is there a way to archieve this behaviour?

Related

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

GLTF Exporter Lighting Issue

Just swapped from the older GLTF Blender exporter to the newer import/export version. Upon doing so, my meshes got significantly darker, and I can't figure out why.
mesh lighting sample :
The left is the older Blender > GLTF exporter, and the right is the newer one. Gamma is set to true, and I've played around with various options within Blender, as well as three.js lighting intensity, etc. (jacking the intensity up to make it look reasonable makes the shadows disappear). It renders the same in Mccurdy's GLTF viewer, and none of the lighting sliders get anywhere close to the lighting from the prior GLTF exporter. I need to use the new version for animation and morph playback purposes. Thanks as always for any suggestions.
Just in case it's helpful to anyone else, apparently the newer Blender > GLTF exporter defaulted to THREE.MeshStandardMaterial. I swapped to THREE.MeshLambertMaterial and the problem was solved.
const oldMat = child.material;
const newMat = new THREE.MeshLambertMaterial({
color: oldMat.color,
map: oldMat.map
});
child.material = newMat;

Texture looks like one flat color, lacking detail of image, in three js

I am attempting to modify the ThreeJS materials example seen here, and have been fairly successful so far in reverse engineering it in to my own minimalist demo.
The problem comes when I attempt to modify the materials.
I have changed mlib["Orange metal"] to the following:
"Orange metal": new THREE.MeshLambertMaterial( {
map: carTexture,
envMap: skyBox,
combine: THREE.MultiplyOperation
} )
carTexture is a reference to the following:
var carTexture = THREE.ImageUtils.loadTexture('texture/blue.jpg');
carTexture.wrapS = carTexture.wrapT = THREE.RepeatWrapping;
carTexture.repeat.set(3,3 );
carTexture.wrapS = THREE.RepeatWrapping;
carTexture.wrapT = THREE.RepeatWrapping;
And while this has changed my final output, the detail in the texture is missing.
For reference: here is the texture file:
Which clearly has a metalic flake texture.
Meanwhile my final product looks like this:
Completely smooth.
Yet, if I add a taurus with the exact same texture, I can see the details quite clearly:
I have played around with the dimensions of the texture file (up to several thousand percent), and the reflectivity of the MeshLambertMaterial, but not been able to see any change at all.
Your model needs UV coordinates.
On a model like this, it will need to be done in 3d software such as 3ds Max, Maya etc.
If you could get your hands on a version of the model which already has the correct UV coordinates set it would save you all the hassle.
Setting up UV coordinates is not so easy on a model like this if you have never done it before.
An alternative may be generate your paint flake in your shader (without using UV) rather than in a texture (I willl soon be attempting this myself for a personal project).
HERE are some youtube videos on UV unwrapping in 3ds Max

Issue upgrading threejs with shaders

I am working on a 3d dataviz. I need to show a world with data on it and I using the chrome experiments (chromeexperiments.com/globe) as a guide.
The issue is that this visualizations are made with Threejs r40 and it is hard to find docs about it so I tried to upgrade to r71.
I solved the compatibility issues rendering the world but cant make it show the atmosphere, in fact, when I try to show the atmosphere nothing is shown (is like the atmosphere is rendered black and it hides the world).
I think that the problem is the shader but I am not really sure.
Does anybody have a clue?
This is the code I am using:
gist.github.com/glena/0b2875044cd6c39ff150
Thanks
==========
Update:
if I remove the fragentShader, this is rendered as a red sphere but stills covers the world with a black background:
var mesh = new THREE.Mesh(new THREE.SphereGeometry(100, 40, 30),
new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader
})
);
The issue (as said by #WestLangley) was
mesh.flipSided = true; ==> mesh.material.side = THREE.BackSide;

overrideMaterial in CanvasRenderer

I fall back to CanvasRenderer if user's browser does not support WebGL. I would like to have wireframe only rendering when using CanvasRenderer for performance reasons. However I cannot get overrideMaterial to work with it. It's working with WebGLRendererer quite nicely like this:
scene.overrideMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true });
In CanvasRenderer this seems to have no effect, making FireFox unresponsive because the code is just too heavy for all but the simplest models.
Previously I had replaced all object materials directly with wireframe material by traversing the scene geometries and just overwriting the "real" materials. That kind of works, but makes material and object management guite messy, as I would like to have the material information present in the models even if they are not rendered.
Is it possible use scene.overrideMaterial with CanvasRenderer? Or other way to force wireframe rendering? I'm using r54.
No, CanvasRenderer does not support scene.overrideMaterial. I think you have pretty much exhausted your options.
I would be careful about using MeshBasicMaterial as an override. Only do so if your scene contains meshes only -- no lines, for example.
three.js r.54

Resources