Colors of GLTF models are too pale with react-three-fiber - three.js

I'm doing a project with react-three-fiber and included my Blender model (a .glb file) with useGLTF (from the drei package). It seems to work but the colors are off, all the parts are way too pale.
The stretched cube (a boxGeometry from R3F) and the cylinder (glb model) have the same material and the same color assigned, but the pink of the cube is much stronger.
I did some googling and think that it might be the encoding, but I do not know to what I have to assign it.
e.g. https://threejs.org/docs/#examples/en/loaders/GLTFLoader
renderer.outputEncoding = THREE.sRGBEncoding;
texture.encoding = THREE.sRGBEncoding;
but I don't have a renderer object with R3F, nor has the material a texture
Update
When I apply <Canvas linear> both objects have the same color, but both not the vibrant version

Related

maptalks.three buildings texture

I'm trying to apply a texture of a little window repeated to the buildings I get from the example code:
https://maptalks.org/maptalks.three/demo/vectortilelayer-mvt.html
What I would like to do is to have one window (png 64x64) repeated in the buildings sides
I'm trying to put this texture:
texture.offset.set(0,0);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(1,1);
var buildMaterial = new THREE.MeshPhongMaterial( { map: texture });
The problem is the texture is applied wrong in some buildings like stretch and all the windows are not the same for all the buildings that's the thing I would like to achieve.
I know the buildings mesh tile are made with a THREE.BufferGeometry of several buildings (extracted from the feature of the geojson data) and then created a Mesh with that BufferGeometry and then apply the material.
On the attached image you can see with red the wrong texture mapping and green what I would like to see.
Image of the texture mapping issues
Hope you can help me with this! Or maybe you know a code of getting the buildings with texture with maptalks.

Threejs doesn't render pointcloud shading, but only flat colors

I am trying to show a point cloud in Threejs, but the result is always flat (not affected by light), and no shading is rendered, is there a way to make it more realistic with shading and shadows (something like Meshlab for example). or is it a limitation in Threejs?
I am using THREE.Points object, with THREE.PointsMaterial material. I tried to use the option vertexColors: THREE.VertexColors, but only flat colors appear.
points = new THREE.Points(geometry, new THREE.PointsMaterial({
size: 1.2,
vertexColors: THREE.VertexColors
}));
Compare threejs rendering to the left, with meshlab rendering to the right

Three.js - CanvasRenderer problems: flat shading?

I'm trying to use CanvasRenderer (three.js) as a fallback for devices not supporting WebGL. Is there some comparison page with explanation what is different and cannot be used with CanvasRenderer?
I'm experiencing two main issues:
flat shading, lights are completely missing (is MeshPhongMaterial supported?), I don't see any lighting nor shadows (are shadows supported in CanvasRenderer)? All I see is the diffuse texture without any lighting. In WebGL my current setup is PointLight, DirectionalLight, softShadows, antialiasing and MeshPhongMaterial (with diffuse, bump, spec and env map)
this.materialM = new THREE.MeshPhongMaterial({
ambient : 0x050505,
color : this.model.color,
specular : 0xcccccc,
shininess : 100,
bumpScale : BUMP_SCALE,
reflectivity : REFLECTIVITY,
});
transparent polygon edges (I know it can be tweaked with material.overdraw = 0.5 yet it produces other artifacts (as it probably does only some scaling of polys along the normal?), but I can do with this one
Any help on 1. or some general overview of what is not possible in CanvasRenderer when comparing to WebGLRenderer is greatly appreciated!
three.js r68
CanvasRenderer has limitations.
MeshPhongMaterial is not supported in CanvasRenderer -- it falls back to MeshLambertMaterial.
MeshLambertMaterial is supported, but not when the material has a texture -- it falls back to MeshBasicMaterial. ( MeshBasicMaterial is rendered without regards to scene lights. )
Shadows are not supported.
material.overdraw = 0.5 is helpful in hiding polygon edges when the material is opaque. It may still leave artifacts if the material is transparent.
three.js r.68

three.js sizeAttenuation to Sprite material

I want the sprite in the scene don't change the size when the camera zoom in or out. and the sprites use different canvas texture as the material.
I found that the sizeAttenuation in ParticleBasicMatierial can work for me. But if I use the WenGLRenderer, I must use ParticleSystem instead of the Particle with the CanvasRenderer.
I currently use ParticleSystem to contain only one vertex, and every vertex correspond to one ParticleSystem, so there are about 800+ ParticleSystem in my scene, this can work, but consume a lot.
Obviously, I can't use "HUD" as the example in three.js source, because the sprites are all in 3D scene.
Can some one help me. Or add the sizeAttenuation to Sprite Material! Thanks!
If you want to prevent size attenuation with sprites, and you are using a perspective camera, you can set the sizeAttenuation property of your material to false:
var material = new THREE.SpriteMaterial( {
color: 0xffffff,
map: texture,
sizeAttenuation: false
} );
This feature was added in three.js r.96.
EDIT: Updated to three.js r.96

Specular highlights with a model imported from Blender?

I made in Dice with 2 different colored materials in Blender and exported it with the Blender exporter. In my three.js code, I use JSONLoader to get the mesh and use new THREE.MeshFaceMaterial(); as material.
This loads the model just fine with the two different colored materials showing correctly. But my problem is, that I want the dice to have specular highlights on the surface. Is this even possible with exported Blender models?
I managed to get a Sphere with specular highlights when I used THREE.MeshPhongMaterial() as material for the sphere, but the sphere wasn't imported from Blender and as far as I know, I can't apply a Phong Material when I load the Mesh with JSONLoader, or is there a trick? Please remember: I got two differently colored materials on the dice, which I import from Blender in the JSON file. The dice by itself is red, but the dots should be black. So I am not talking about different colors on each side of a cube or so, but two different colors on every side of the cube. Can you help me?
Here's the code snippet:
loader.load("models/dice.js", function(geometry){
var material = new THREE.MeshFaceMaterial();
material.specular = 0xffffff;
material.shininess = 10000000000;
dice=new THREE.Mesh(geometry, material);
dice.position.set(0,-400,5);
dice.scale.set(75, 75, 75);
dice.overdraw = true;
dice.name="dice";
navscene.add(dice);
});
If it helps, I am able to create a texture out of the two materials and apply them in Blender, so that the JSONLoader loads the texture instead of the materials, but I wasn't able to achieve a specular highlight either with that.
Thx West, you pointed me into the right direction. The problem was, that Blender's standard material type is Lambert. In Blender, this Lambert material produces the desired specular highlight, but once imported to three, the effect is gone. I don't know if this is a bug, or a desired behaviour.
The solution is to set the material type in Blender to Phong material. This works even after import. My guess is, that THREE.MeshFaceMaterial is an array which contains all the loaded materials, whether they are lambert, phong or whatever. It is even possible to mix those material types. So it appears to me, that THREE.MeshFaceMaterial doesn't seem to be a "stand alone" material type at all. Correct me if I'm wrong please.
If your mesh geometry has a materials array, you can always change the array elements after you load the geometry:
geometry.materials[ i ] = new THREE.MeshPhongMaterial( ... );
You then leave the mesh's material as MeshFaceMaterial:
mesh = new THREE.mesh( geometry, new THREE.MeshFaceMaterial() );
The exporter script you are using may set geometry.materials to Lambert material by default, based on your settings. Have a look at the script source code and see if you can figure it out.

Resources