GLTF Exporter Lighting Issue - three.js

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;

Related

Spherical environment map blurry

I took an equirectangular envMap from the three.js docs sample where it appears sharp on a sphere.
If I load the same material into my aframe scene with the following params
material="spherical-env-map: /assets/models/1/envtest.jpeg; roughness: 0; metalness: 1"
it appears blurry like this
What am I doing wrong?
Reproducible example via glitch: https://glitch.com/edit/#!/sepia-forest-keyboard
What I have noticed when setting up the glitch:
Using Aframe 1.0.3 it is blurry
Using Aframe 1.2.0 it remains black no matter what I do
That happens because you are using a PBR material in your code since the default material of A-Frame is MeshStandardMaterial. Meaning a material that tries to render physically correct. The official three.js example uses MeshLambertMaterial which is no PBR material. Both type of materials implement environment maps differently.
When using a PBR material, it's recommended to use a HDR environment map which is also pre-processed with PMREMGenerator like in this example: https://threejs.org/examples/webgl_loader_gltf

Ambient occlusion not showing in three.js

I'm using the MeshStandardMaterial in three.js and when I create and apply the material, all maps work fine except for the aoMap, which has no effect on the model. I suspect this is because I don't have a 2nd set of UVs (my UV unwrapping is done through Blender and I don't manually apply any UV at all in three.js), as the documentation says:
The red channel of this texture is used as the ambient occlusion map.
Default is null. The aoMap requires a second set of UVs, and
consequently will ignore the repeat and offset Texture properties.
I've tried using the below code to solve this:
var geometry = mesh.geometry;
geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
but had no luck. How do I copy my UV map to the uv2 property, or wherever it is needed to make ambient occlusion work?
An aoMap is an ambient occlusion map, and like its name says, it occludes ambient light. That is all it occludes.
There are currently three sources of ambient (or indirect) light in three.js: AmbientLight, HemiSphereLight, and LightMap.
So the aoMap occludes those three sources. It does not occlude direct light sources. Direct light sources include DirectionalLight, SpotLight, PointLight, and AreaLight.
three.js r.95
What kind of lighting are you using? I recreated your situation, and it works as expected. The things to look out for is that aoMap shows up with THREE.AmbientLight, but not with THREE.Spotlight. It also works if you use an envMap on your MeshStandardMaterial

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

Messed up UVs and Lightmap

I want to bake my model lightmap in blender then load them all in three.js.
So in blender i set two uvs for each objects and baked ambient occlusion in second uv. finally i exported whole scene via three.js exporter into js file.
(exporter has problem that the baked texture goes for diffuse-map not light-map which is correctable by editing exported js file).
But the problem is when i load js with SceneLoader, the textures especially for my floor goes wrong, like upside down.
here is my test files: Test Light Map
So is there something wrong with my blender file or ...? Which loader i should use for it?
Thanks.
I just upload some images to see what i mean:
Messed up textures:
After edit js file, it's get better. but still there is problem at the edges:
And specially at floor, the light-map goes wrong:
Ok, i don't know why, but it seems my uvs was messed up in blender. i did some recaculate normals and flip normals in blender and now textures map fine on objects.
But i still need to edit exported scene to change map:texture.png to lightMap:texture.png.
[EDIT]
Actually this is a bug related to three.js scene exporter: Blender Exporter - Scene Exporting
[Final Answer]
The problem was about my model which had a negative scale in blender. i select my model, hit crtl+a then choose scale. now everything's fine.

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