In three.js I would like to change the same object material texture multiple times.
After the page loaded the base 3D model rendered but already changed the left side of the furniture. (I made it on purpose). After 5 seconds it should change the texture again but the texture disappears. In the Network Activity tab the texture downloaded.
I would really appreciate it if somebody would give me a hint.
import * as THREE from 'three';
import {
OrbitControls
} from '../js/three/examples/jsm/controls/OrbitControls.js'
import {
GLTFLoader
} from '../js/three/examples/jsm/loaders/GLTFLoader.js'
const scene = new THREE.Scene();
const manager = new THREE.LoadingManager();
const renderer = new THREE.WebGLRenderer();
const loader = new GLTFLoader(manager);
const camera = new THREE.PerspectiveCamera(
30,
window.innerWidth / window.innerHeight,
0.1,
2000
)
camera.position.z = 3.5
camera.position.x = 0
camera.position.y = 1
const hemiLight = new THREE.HemisphereLight();
scene.add(hemiLight);
const light1 = new THREE.AmbientLight(0xFFFFFF, 0.3);
scene.add(light1);
const light2 = new THREE.DirectionalLight(0xFFFFFF, 0.8 * Math.PI);
light2.position.set(0.5, 1, 0.8);
scene.add(light2);
const light3 = new THREE.DirectionalLight(0xFFFFFF, 0.8 * Math.PI);
light3.position.set(-0.5, -1, -0.8);
scene.add(light3);
render.toneMapping = THREE.ACESFilmicToneMapping;
renderer.physicallyCorrectLights = true
renderer.shadowMap.enabled = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setClearColor(0xcccccc);
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const loadElement = async (input, xinput, yinput, zinput, cb) => {
loader.load(input, async function (gltf) {
const box = new THREE.Box3().setFromObject(gltf.scene);
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.x += (gltf.scene.position.x - center.x + xinput);
gltf.scene.position.y += (gltf.scene.position.y - center.y + yinput);
gltf.scene.position.z += (gltf.scene.position.z - center.z + zinput);
cb(gltf.scene)
}),
function () {}, // onProgress function
function (error) {
console.log(error)
} // onError function
}
window.addEventListener('resize', onWindowResize, false)
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
renderer.setSize(window.innerWidth, window.innerHeight)
render()
}
function render() {
renderer.render(scene, camera)
}
function animate() {
requestAnimationFrame(animate)
controls.update()
render()
}
document.addEventListener("DOMContentLoaded", () => {
animate();
loadElement("../models/base/model.gltf", 0, -0.3, 0, (obj) => {
obj.name = "base";
scene.add(obj)
obj.traverse(child => {
if (child.material && child.material.name === 'dark_wood') {
child.material = new THREE.TextureLoader().load("../models/base/wood_color.png", (texture) => {
texture.flipY = false;
texture.encoding = THREE.sRGBEncoding;
texture.needsUpdate = true;
});
}
});
})
setTimeout(() => {
scene.getObjectByName('base').traverse(child => {
if (child.material && child.material.name === 'wood') {
child.material = new THREE.TextureLoader().load("../models/base/dark_wood_color.png", (texture) => {
texture.flipY = false;
texture.encoding = THREE.sRGBEncoding;
texture.needsUpdate = true;
});
}
});
}, 5000);
});
Related
The plan is for it to draw borders using GeoJSON coords. Also when I write coordinates directly into the same file it works normally and I've noticed that my fbih variable doesn't get the fbih: THREE.Vector3 when hovered over. I'm using ViteJS + ThreeJS, Here's the code:
import './style.css'
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { Vector3 } from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("#bg")
});
renderer.setPixelRatio (window.devicePixelRatio);
renderer.setSize( window.innerWidth, window.innerHeight);
camera.position.setZ(20);
renderer.render(scene,camera);
const teksturazemlje = new THREE.TextureLoader().load('slike/zemlja.png')
const zemlja = new THREE.Mesh (
new THREE.SphereGeometry(16, 500, 500 ),
new THREE.MeshStandardMaterial({
map:teksturazemlje,
})
);
scene.add(zemlja)
function koordinate([lon,lat]){
var phi = (90-lat)*(Math.PI/180);
var theta = (lon+180)*(Math.PI/180);
var x = -((16) * Math.sin(phi)*Math.cos(theta));
var z = ((16) * Math.sin(phi)*Math.sin(theta));
var y = ((16) * Math.cos(phi));
return new THREE.Vector3(x,y,z)
}
const boja = new THREE.MeshBasicMaterial({
color: 0xff00cc,
side : THREE.DoubleSide,
});
var fbih = [];
fetch ('granice/bih.json')
.then (res => res.json())
.then (data => {
for (let element of data.features[0].geometry.coordinates[0][0]) {
fbih.push(koordinate(element))
}
});
console.log(fbih)
const linije = new THREE.BufferGeometry().setFromPoints(fbih)
const line = new THREE.Line(linije,boja)
scene.add(line);
const ambientlight= new THREE.AmbientLight(0xffffff);
scene.add(ambientlight)
const controls = new OrbitControls(camera, renderer.domElement);
function animate(){
requestAnimationFrame(animate);
controls.update();
renderer.render (scene, camera);
}
controls.enableDamping = true;
controls.dampingFactor = 0.04;
controls.rotateSpeed = 0.07;
controls.maxDistance = 20;
controls.minDistance = 16.5;
controls.enablePan = false;
controls.zoomSpeed = 0.30;
animate()
It displays Vector3 array in console.log but it isn't displayed through BufferGeometry. Sorry if there are grammatical errors, English isn't my first language.
juste starting to learn threejs and to do so decided to build a t-shirt configurator in combination with fabric js. my goal is that the user can upload a picture to the canvas (cnvs) which will be mapped to the gltf model of a t-shirt the probleme is that the texture doesn't show .
code :
var canvas2 = new fabric.Canvas('cnvs', {
backgroundColor: 'red'
});
fabric.Image.fromURL('eo.png', function(myImg) {
//i create an extra var for to change some image properties
var img1 = myImg.set({ left: 0, top: 0 ,width:150,height:150});
canvas2.add(img1);
canvas2.renderAll();
});
var canvasTexture = new THREE.CanvasTexture(canvas2);
canvasTexture.wrapS = THREE.RepeatWrapping;
canvasTexture.wrapT = THREE.RepeatWrapping;
const gltfLoader2 = new GLTFLoader();
gltfLoader2.load('tshirt2.gltf', (gltf2) => {
model = gltf2.scene;
model.traverse(child => {
console.log(child.material);
if (child.material && child.material.name === 'Pattern2D_13095') {
// Pattern2D_13095
child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial({
map: canvasTexture,
}));
}
});
canvas2.on("after:render", function() {
model.material.map.needsUpdate = true;
});
canvas2.on('mouse:down',function(event){
if(canvas2.getActiveObject()){
alert(event.target);
}
})
scene.add(model);
model.rotation.x = 1.5;
model.position.y=310;
model.position.x=-300;
model.position.z=-100;
model.scale.set(1000,1000,1000);
});
});
function resizeRendererToDisplaySize(renderer) {
const canvas = renderer.domElement;
const width = canvas.clientWidth;
const height = canvas.clientHeight;
const needResize = canvas.width !== width || canvas.height !== height;
if (needResize) {
renderer.setSize(width, height, false);
}
return needResize;
}
function render() {
if (resizeRendererToDisplaySize(renderer)) {
const canvas = renderer.domElement;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function animate(){
requestAnimationFrame(animate);
cloudParticles.forEach(p => {
p.rotation.z -= 0.001;
});
root.rotation.z -= 0.01;
renderer.render(scene, camera);
model.material.needsUpdate = true;
}
animate();
lights/camera:
let cloudParticles = [];
let root;
let model;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1,
1000 );
camera.position.z = 2;
camera.rotation.x = 1.16;
camera.rotation.y = -0.12;
camera.rotation.z = 0;
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({canvas});
scene.fog = new THREE.FogExp2(0x11111f, 0.002);
renderer.setClearColor(scene.fog.color);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild( renderer.domElement );
let directionalLight = new THREE.DirectionalLight(0xff8c19);
directionalLight.position.set(0,0,1);
scene.add(directionalLight);
let orangeLight = new THREE.PointLight(0xcc6600,50,450,1.7);
orangeLight.position.set(200,300,100);
scene.add(orangeLight);
let redLight = new THREE.PointLight(0xd8547e,50,450,1.7);
redLight.position.set(100,300,100);
scene.add(redLight);
let blueLight = new THREE.PointLight(0x3677ac,50,450,1.7);
blueLight.position.set(300,300,200);
scene.add(blueLight);
let directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(-110,-110,-120);
scene.add(directionalLight2);
HTML:
<div class="cnvscon">
<canvas id="cnvs" height="256" width="256" ></canvas></div>
<canvas id="c"></canvas>
here is an img of the result ( the mesh is black ):
result
gltfviewer
child.material.map = new TextureLoader().load( new THREE.MeshStandardMaterial({
map: canvasTexture }));
I'm afraid this code is incorrect. It should be sufficient to assign canvasTexture to the respective map property. Meaning:
child.material.map = canvasTexture;
This is the code I would like to work with:
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 1.0,
metalness: 0.5,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
child.material.map = diffuseMap;
child.material.roughnessMap = roughnessMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new THREE.EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function(texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, false);
//
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/EXRLoader.js"></script>
Instead of the existing material, I would like to have a metallic material like here.
For this, I have tried to delete diffuseMap and roughnessMap, and add cubeMap.
That's my not working result:
var container;
var camera, scene, renderer;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
textureLoader.load('https://threejs.org/examples/textures/2294472375_24a3b8ef46_o.jpg', function(texture) {
texture.encoding = THREE.sRGBEncoding;
texture.mapping = THREE.EquirectangularReflectionMapping;
init(texture);
animate();
});
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 1.0,
metalness: 0.5,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, false);
//
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
The background should be transparent in the end, only the OBJ object should be visible.
Could somebody help me please? Would be soooo happy about it!
There's not much you need to change to make it metallic:
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0, // <- roughness 0
metalness: 1.0, // <- metalness 1
envMapIntensity: 1.0
});
child.material.envMap = newEnvMap;
// Then you only need the envMap, remove the other stuff
//child.material.map = diffuseMap;
//child.material.roughnessMap = roughnessMap;
//child.material.needsUpdate = true;
And finally, if you don't want the background, remove it from the Render loop:
//scene.background = exrBackground;
Live demo:
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0,
metalness: 1.0,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
//child.material.map = diffuseMap;
//child.material.roughnessMap = roughnessMap;
//child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new THREE.EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function(texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, false);
//
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
//scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/EXRLoader.js"></script>
This is the code I am working with:
* {
margin: 0;
padding: 0;
}
.object {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
background-color: rgb(200, 200, 200);
}
<script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import { OBJLoader } from "https://threejs.org/examples/jsm/loaders/OBJLoader.js";
import { EXRLoader } from "https://threejs.org/examples/jsm/loaders/EXRLoader.js";
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
/*var ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 2);
pointLight.position.set(100, 100, 50);
camera.add(pointLight);*/
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function () {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
object.traverse(function (child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0,
metalness: 2.0,
envMapIntensity: 5.0
});
//child.material.flatShading = false;
console.log("setting envmap");
child.material.envMap = newEnvMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function (texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
// model
function onProgress(xhr) {
if (xhr.lengthComputable) {
var percentComplete = (xhr.loaded / xhr.total) * 100;
console.log("model " + Math.round(percentComplete, 2) + "% downloaded");
}
}
function onError() {}
var loader = new OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function (obj) {
object = obj;
},
onProgress,
onError
);
//
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, false);
//
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
</script>
Now I want to add map and roughnessMap like here: https://threejs.org/docs/scenes/material-browser.html#MeshStandardMaterial
I thought I just should add the following:
const textureLoader = new THREE.TextureLoader();
const diffuseMaps = (function() {
const bricks = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
bricks.wrapS = RepeatWrapping;
bricks.wrapT = RepeatWrapping;
bricks.repeat.set(9, 1);
return {
none: null,
bricks: bricks
};
})();
const roughnessMaps = (function() {
const bricks = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
bricks.wrapT = RepeatWrapping;
bricks.wrapS = RepeatWrapping;
bricks.repeat.set(9, 1);
return {
none: null,
bricks: bricks
};
})();
function loadObjectAndAndEnvMap() {
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0,
metalness: 2.0,
envMapIntensity: 5.0,
diffuseMapIntensity: 1.0,
roughnessMapIntensity: 1.0
});
//child.material.flatShading = false;
console.log("setting envmap");
child.material.envMap = newEnvMap;
child.material.diffuseMap = diffuseMaps;
child.material.roughnessMap = roughnessMaps;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
Unfortunately, it does not work.
Could somebody help me please? I would be sooo thankful!!
Try it with this code:
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 1.0,
metalness: 0.5,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
child.material.map = diffuseMap;
child.material.roughnessMap = roughnessMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new THREE.EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function(texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, false);
//
window.addEventListener("resize", onWindowResize, false);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/EXRLoader.js"></script>
Please note:
The maximum value for roughness and metalness is 1. You have used 2for metalness.
Since the sampled value from a roughness map is multiplied with the roughness value from the material, you won't see any effect if you set it to 0. Always start with 1.
I just wanted to create a very simple scene with 2 different objects that move
differently.
But my sphere isnt moving at all.
When I change the line:
scene.add(obj2)
to:
obj.add(obj2)
the sphere is moving exactly as the box
what can I change to just let the sphere rotate?
//set up the scene
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer();
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
const light = new THREE.DirectionalLight();
scene.background = new THREE.Color("white");
renderer.setSize((3 * window.innerWidth) / 4, (3 * window.innerHeight) / 4);
document.body.appendChild(renderer.domElement);
camera.position.z = 17;
light.position.set(-1, 1, 1);
//-----GEOMETRY VARIABLES------//
let box = new THREE.BoxGeometry(1, 1, 1);
let sphere = new THREE.SphereGeometry(0.5, 32, 32);
//-----MATERIAL VARIABLES------//
let phong = new THREE.MeshPhongMaterial({
color: "pink",
emissive: 0,
specular: 0x070707,
shininess: 100,
});
//-----FUNCTIONALITY------//
//make the objects and add them to the scene
let obj, currentShape, currentMesh, obj2;
currentShape = box;
currentMesh = phong;
obj = new THREE.Mesh(currentShape, currentMesh);
scene.add(light);
scene.add(obj);
obj2 = new THREE.Mesh(sphere, currentMesh);
obj2.position.set(3, 0, 0);
scene.add(obj2);
//methods for making the objects move
let up = true;
function animate() {
requestAnimationFrame(animate);
obj.rotation.y += 0.01;
obj2.rotation.x += 0.02;
if (up) {
obj.translateOnAxis(new THREE.Vector3(0, 1, 0).normalize(), 0.1);
if (obj.position.y > 3.4) {
up = false;
}
} else if (!up) {
obj.translateOnAxis(new THREE.Vector3(0, 1, 0).normalize(), -0.1);
if (obj.position.y < -3.4) {
up = true;
}
}
renderer.render(scene, camera);
}
window.onload = () => {
document.getElementById("shape-form").onchange = evt => {
switch (evt.target.value) {
case "box":
currentShape = box;
break;
}
obj.geometry = currentShape;
obj.geometry.buffersNeedUpdate = true;
};
document.getElementById("mesh-form").onchange = evt => {
switch (evt.target.value) {
case "phong":
currentMesh = phong;
break;
}
obj.material = currentMesh;
obj.material.needsUpdate = true;
};
animate();
};
It's just hard to see a sphere rotating :)
Here's a simplified version of your example - I made both the cube and the sphere rotate and float around in gentle waves.
const renderer = new THREE.WebGLRenderer();
renderer.setSize((3 * window.innerWidth) / 4, (3 * window.innerHeight) / 4);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color("white");
const camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 17;
const light = new THREE.DirectionalLight();
light.position.set(-1, 1, 1);
scene.add(light);
const phong = new THREE.MeshPhongMaterial({
color: "pink",
emissive: 0,
specular: 0x070707,
shininess: 100,
});
const boxGeom = new THREE.BoxGeometry(1, 1, 1);
const boxObj = new THREE.Mesh(boxGeom, phong);
scene.add(boxObj);
const sphereGeom = new THREE.SphereGeometry(0.5, 32, 32);
const sphereObj = new THREE.Mesh(sphereGeom, phong);
scene.add(sphereObj);
function animate() {
const time = +new Date() / 1000;
requestAnimationFrame(animate);
boxObj.rotation.y += 0.01;
sphereObj.rotation.x += 0.02;
boxObj.position.x = Math.sin(time * .2) * 3.4;
sphereObj.position.x = Math.cos(time * .3) * 3.4;
boxObj.position.y = Math.sin(time) * 3.4;
sphereObj.position.y = Math.cos(time) * 3.4;
renderer.render(scene, camera);
}
animate();
<script src="https://threejs.org/build/three.min.js"></script>