Setting a texture in ThreeJS does nothing - three.js

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

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?

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.

I can't get the aoMap showing in three.js using a glb/gltf asset

I’m having a hard time getting an aoMap working in three.js…
I have a glb asset with an aoMap on the red channel or something. When I bring it into to the babylon viewer, I can see the ao just fine, but it wont show up in the three.js viewer or my project. I think this has something to do with a second set of uvs, but I can't find a resource that involves doing that on top of using the gltf loader… I really don't know what to do here. Any response would be greatly appreciated!
Here is my code (I’m using a html-canvas as the texture)
And I get the model’s geometry and diffuse texture (all white) as desired, but the aomap isnt showing…
code
babylon viewer
three.js viewer
working application with shadows included in diffuse
not working, diffuse is just white, and aoMap is not showing
You're right about needing a second set of UVs. The reason behind this is that diffuse textures often repeat (think of a brick wall, or checkered t-shirt). AO shading, however, is more likely to be unique on each part of the geometry, so it's almost never repetitive. Since this often would need an alternative UV mapping method, the default is to use a second set of UVs.
You could do 2 things:
Re-export your GLTF asset with a duplicate set of UVs.
Duplicate existing UVs in Three.js by creating a new BufferAttribute in your geometry:
// Get existing `uv` data array
const uv1Array = mesh.geometry.getAttribute("uv").array;
// Use this array to create new attribute named `uv2`
mesh.geometry.setAttribute( 'uv2', new THREE.BufferAttribute( uv1Array, 2 ) );
.getAttribute and .setAttribute are methods of BufferGeometry, if you want to read more about them.

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

Transparent shader pass with effect composer

I'm trying to render a scene and then have a half-transparent post-processing effect rendered on top of it. I'd like to make it work with effect composer so I can later use more passes easily.
My basic structure is this:
composer = new Three.EffectComposer renderer
composer.addPass renderPass
composer.addPass transparentPass
composer.addPass copyPass
copyPass has renderToScreen = true, transparentPass is my custom fragment shader with each pixel's alpha is set to 0.5 and loaded with ShaderPass.
I've tried blending, depthTest and transparent for the shaderMaterial.
Also tried alpha and premultipliedAlpha options for renderer, autoClear off.
I'm getting either the scene from renderPass with nothing else or the transparentPass on any renderer.clearColor I choose. Not the composite of both. What do I need to set to make this work?
Thank you.
EDIT:
Here is a codepen example:
http://codepen.io/Eskel/pen/PzaOWb?editors=0010
And the code of my shader:
http://eskel.cz/js/three79/RGBAShader.js
It shows all white (and not a rotating cube underneath) even though all pixels are rendered with alpha channel set to 0.5. Should I mix it with the tDiffuse render target in the shader or is there a way to make the shaderPass transparent?
It's a really late response, but maybe it would help someone.
In constructor ShaderPass creates internal ShaderMaterial and we should set this material's transparency to true:
copyPass.material.transparent = true

Resources