how to use 3d model as a scene background in three.js? - three.js

Greeting, I want to use a 3d model as a scene background. how is it possible?
const assetsLoader = new GLTFLoader();
assetsLoader.load(monkeyURL.href, function (gltf) {
const model = gltf.scene;
scene.add(model);
model.castShadow = true;
model.position.set(10, 5, 15);
});
scene.background = assetsLoader.load(model);

What you are trying to achieve is not possible. Like mentioned in the documentation you can assign to Scene.background:
A color for defining a uniform colored background.
Textures defining a (flat) textured background.
Environment maps for defining a skybox.

Related

Ready Player Me Avatar texture/lightning rendering in ThreeJS and Matterport

I try to import a Ready Player Me GLB avatar into a Matterport scene (in ThreeJS).
It works but the avatar is very flat (left picture) compared to the rendering into RPM (right picture) or basic GLTF Viewer. I don't understand what I missed ? Pseudo code :
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load('https://api.readyplayer.me/v1/avatars/63580183b445da7aa57b9ce3.glb',
(gltf) => {
this.mesh = gltf.scene;
const light = new THREE.AmbientLight( 0xFFFFFF, 1 );
light.castShadow = true
this.mesh.add( light );
...
}, undefined);
On the WebGL part I have access to Matterport renderer :
(renderer, THREE, effectComposer) => {
renderer.outputEncoding = THREE.sRGBEncoding
renderer.toneMapping = THREE.ACESFilmicToneMapping
}
Is it related to Antialias ? Or a paramter or lighting that flatten hair and hands ? Or is it related to texture ?
Thanks !
EDIT 11/12/2022:
Thanks to #Mugen87, I find how to use the EquirectangularShader from GLTFLoader sample. This code works with Matterport context.
let pmremGenerator = new THREE.PMREMGenerator( this.context.renderer );
pmremGenerator.compileEquirectangularShader();
let envMap = pmremGenerator.fromScene( new THREE.RoomEnvironment() ).texture;
this.context.scene.environment = envMap;
Instead of using a single instance of AmbientLight, apply a more advanced type of environmental lighting to your scene. Especially if you already enabled tone mapping, consider to use a HDR environment map. The basic GLTFLoader example of three.js is a good code template. The most important part is:
new RGBELoader()
.load( 'textures/equirectangular/royal_esplanade_1k.hdr', function ( texture ) {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = texture;
// more scene setup
} );
Applying an environment map to Scene.environment ensures all PBR materials in the scene are going to use it.

THREE.JS : Change material color behind PNG texture ? Assign 2 materials to a mesh imported from GLTF model?

I am trying to change the color of my 3D model "behind" the png texture I set (which includes transparency).
I have done a lot of researches, and i finally found an example with a cube which actually works, but I can't understand how to make that with my gltf 3D model (not a BoxGeometry).
METHOD :
Define an array of two materials,
first one is my png texture with transparency = true;
second one is a basic material with its plain color (the color i will be able to change later...)
var materialBack = new THREE.MeshBasicMaterial({color: 0xfadce6});
var materialTxt = new THREE.MeshBasicMaterial({map: mytexture,transparent: true});
var materials = [materialBack, materialTxt];
It works perfect with a cube :
var geometry = new THREE.BoxBufferGeometry();
geometry.clearGroups();
geometry.addGroup( 0, Infinity, 0 );
geometry.addGroup( 0, Infinity, 1 );
var cube = new THREE.Mesh( geometry, materials );
Problem : I can't figure out how to do the same when my model is actually an imported GLTF, and not a "BoxBufferGeometry". It looks like we can't assign an array to o.material :
var loader = new THREE.GLTFLoader();
loader.load(mymodel.glb, function(gltf) {
gltf.scene.traverse((o) => {
if (o.isMesh) {
o.material = materials;
}
scene.add(gltf.scene);
});
I also tried to extract geometry from gltf, then create a new mesh, but without success :
var loader = new THREE.GLTFLoader();
loader.load(mymodel.glb, function(gltf) {
var geometry = gltf.scene.getObjectByName("name").geometry;
mymesh = new THREE.Mesh(geometry,materials);
scene.add(mymesh);
});
Can someone please help ?

ThreeJs add Texture to a GLTF object surface

I am trying to apply an image dynamically on a gltf loaded mesh.
The code to load the model looks like:
const gltfLoader = new GLTFLoader();
const url = 'resources/models/mesh.gltf';
gltfLoader.load(url, (gltf) => {
const root = gltf.scene;
scene.add(root);
})
When looking from top the element looks like a rounded rect:
When inspecting the imported mesh I can see that the BufferGeometry has a count of 18.000 points:
Everything works fine however if I apply the texture like this:
const texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
root.children[0].material = material;
The image is not visible but the mesh is now colored in 1 color.
Is it possible to apply the image just on the top face of the rect?
Hard to tell what the problem is without seeing the resulting image. However, I would just assign a new texture like this: root.children[0].material.map = texture instead of creating a whole new material, since you don't want to lose all the material attributes that came in the GLTF.
Additionally, MeshBasicMaterial always looks flat because it is not affected by lights.

Three.js adding texture gives complete object color of 1 pixel

I have this texture of 20x20pixels and and object from a collada 1.4.1 model.
So I want to give this object this new texture for testing
I do the following
var loader = new THREE.TextureLoader();
loader.load("/assets/images/texture2/TextureResource129.png", texture => {
var material = new THREE.MeshLambertMaterial({
map: texture
});
node.material = material;
material.needsUpdate = true;
});
Now what happens is that the object is in 1 color
How can I change the texture so it is just as the texture?
Instead of creating a new material that behaves differently than the one that comes in your Collada import, just change the texture of the existing material. Do this inside your texture loader callback:
node.material.uniforms.MatDiff2.value = texture;
That way you just change the texture input to the existing material.

unable to apply three.js texture to JSON model imported from blender

I am trying to apply a texture to a simple 3-d cube model exported from Blender 2.78b (as a matter of fact, the default blender cube). I exported the model in the standard three.js JSON format. I realize that I should be able to apply a texture in Blender on top of the geometry, but I want to "style" the blender model in three.js at runtime. Thus I am only interested in using blender to provide the geometry for my mesh.
I have created a plunker illustrating the situation.
I load in a blender model as blenderGeom, and then apply a MeshBasicMaterial with map set to a brick texture (unfortunately, I have to load the texture as Base64, since plunker doesn't allow you to upload images). I then apply the exact same material/texture to a native three.js BoxGeometry nonBlenderCubeGeom:
function loadModel() {
console.log('now in loadModel');
var promise = new Promise( (resolve, reject) => {
var loader = new THREE.JSONLoader();
// load a resource
loader.load(
'cube.json', (blenderGeom, materials) => {
console.log(`loadModel: now loading cube: geomery=${geometry}`);
let cubeMaterial = new THREE.MeshBasicMaterial({
color: 0xff8080,
wireframe: false,
map: brickTexture
})
nonBlenderCubeGeom = new THREE.BoxGeometry(50, 50, 50);
blenderCubeGeom = blenderGeom;
blenderCube = new THREE.Mesh(blenderGeom, cubeMaterial); //no work
blenderCube.position.x = -20;
nonBlenderCube = new THREE.Mesh(nonBlenderCubeGeom, cubeMaterial); //work
nonBlenderCube.position.x = 20;
blenderCube.scale.set(10, 10, 10);
scene.add(blenderCube);
scene.add(nonBlenderCube);
As you can see from running the plunker, only the native three.js object on the right is textured, and the blender model on the left is not:
Am I doing something wrong? Is it simply a restriction that you can only texture a model in Blender?
Three.js r84. Blender 2.78b. I'm assuming this on three.js side, but I'm opening it up to blender as well.
Many Thanks.

Resources