This follows on from my previous question here. I'm just trying to apply a different texture to each side of this obj but nothing appears. There are no console errors and I believe I'm applying things in the right order.
This should be quite simple to do but I've been struggling with it for the past hour. Here's a code sample below:
(function onLoad() {
var canvasElement;
var width, height;
var scene, camera;
var renderer;
var controls;
var pivot;
var bagMesh;
var planeMesh;
const objLoader = new THREE.OBJLoader2();
const fileLoader = new THREE.FileLoader();
const textureLoader = new THREE.TextureLoader();
init();
function init() {
container = document.getElementById('container');
initScene();
addGridHelper();
addCamera();
addLighting();
addRenderer();
addOrbitControls();
loadPlaneObj();
// Logic
var update = function() {};
// Draw scene
var render = function() {
renderer.render(scene, camera);
};
// Run game logic (update, render, repeat)
var gameLoop = function() {
requestAnimationFrame(gameLoop);
update();
render();
};
gameLoop();
}
/**** Basic Scene Setup ****/
function initScene() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0xd3d3d3);
var axis = new THREE.AxesHelper();
scene.add(axis);
}
function addCamera() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(3,3,3);
scene.add(camera);
}
function addGridHelper() {
var planeGeometry = new THREE.PlaneGeometry(2000, 2000);
planeGeometry.rotateX(-Math.PI / 2);
var planeMaterial = new THREE.ShadowMaterial({
opacity: 0.2
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.position.y = -200;
plane.receiveShadow = true;
scene.add(plane);
var helper = new THREE.GridHelper(2000, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper();
scene.add(axis);
}
// *********** Lighting settings **********************
function addLighting() {
var light = new THREE.HemisphereLight(0xffffff, 0xffffff, 1);
scene.add(light);
}
// ************** Material settings **************
function setMaterial(materialName) {
// get the object from the scene
var bagMesh = scene.getObjectByName('bag');
var material;
if (!materialName) {
materialName = materials.material;
}
if (bagMesh) {
var colour = parseInt(materials.colour);
switch (materialName) {
case 'MeshBasicMaterial':
material = new THREE.MeshBasicMaterial({
color: colour
});
break;
case 'MeshDepthMaterial':
material = new THREE.MeshDepthMaterial();
break;
case 'MeshLambertMaterial':
material = new THREE.MeshLambertMaterial({
color: colour
});
break;
case 'MeshNormalMaterial':
material = new THREE.MeshNormalMaterial();
break;
case 'MeshPhongMaterial':
material = new THREE.MeshPhongMaterial({
color: colour
});
break;
case 'MeshPhysicalMaterial':
material = new THREE.MeshPhysicalMaterial({
color: colour
});
break;
case 'MeshStandardMaterial':
material = new THREE.MeshStandardMaterial({
color: colour
});
break;
case 'MeshToonMaterial':
material = new THREE.MeshToonMaterial({
color: colour
});
break;
}
bagMesh.children.forEach(function(c) {
c.material = material;
});
}
}
function setMaterialColour(colour) {
materials.colour = colour;
setMaterial(null);
}
// ************** End of materials ***************
function addRenderer() {
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
}
function addOrbitControls() {
var controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function addPivot() {
var cubeGeo = new THREE.BoxBufferGeometry(5, 5, 5);
var cubeMat = new THREE.MeshBasicMaterial();
pivot = new THREE.Mesh(cubeGeo, cubeMat);
bagMesh.position.x -= 15;
bagMesh.position.z -= 55;
pivot.add(bagMesh);
pivot.add(handle);
scene.add(pivot);
}
function loadPlaneObj() {
loadObjWithMtl('PlaneWithMaterial',
'https://rawgit.com/Katana24/threejs-experimentation/material-test/models/PlaneWithMaterial.obj',
'https://rawgit.com/Katana24/threejs-experimentation/material-test/models/PlaneWithMaterial.mtl')
.then(function(mesh) {
loadTexture(
'https://rawgit.com/Katana24/threejs-experimentation/material-test/img/1.jpg', scene, 0xff0000, THREE.FrontSide, mesh);
});
}
function loadObjWithMtl(modelName, modelUrl, mtlUrl) {
return new Promise(function(resolve, reject) {
var callbackOnLoad = function ( event ) { resolve(event.detail.loaderRootNode); };
var onLoadMtl = function ( materials ) {
objLoader.setModelName( modelName );
objLoader.setMaterials( materials );
objLoader.getLogger().setDebug( true );
objLoader.load( modelUrl, callbackOnLoad, null, null, null, false );
};
objLoader.loadMtl(mtlUrl, null, onLoadMtl );
});
}
function loadTexture(imgPath, scene, color, side, mesh) {
var loadedMesh = mesh;
textureLoader.load(imgPath,
function (texture) {
var geometry = new THREE.Geometry().fromBufferGeometry( loadedMesh.children[0].geometry );
mesh.children[0].material.map = texture;
mesh.children[0].material.needsUpdate = true;
scene.add(mesh);
},
undefined,
function ( err ) {
console.error( 'An error occurred...' );
}
);
}
function addPlaneToSceneSOAnswer(mesh) {
var frontMaterial = new THREE.MeshBasicMaterial( { color : 0xff0000, side: THREE.FrontSide } );
var backMaterial = new THREE.MeshBasicMaterial( { color : 0x00ff00, side: THREE.BackSide } );
var geometry = new THREE.Geometry().fromBufferGeometry( mesh.children[0].geometry );
var length = geometry.faces.length;
geometry.faces.splice(14, 1);
for (var i = 0; i < geometry.faces.length; i ++ ) {
var face = geometry.faces[i];
face.color.setHex(Math.random() * 0xffffff);
}
mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial({ vertexColors: THREE.FaceColors, side: THREE.DoubleSide }) );
mesh.material.side = THREE.FrontSide;
var mesh2 = new THREE.Mesh( geometry, mesh.material.clone() );
mesh2.material.side = THREE.BackSide;
// mesh2.material.vertexColors = THREE.NoColors;
mesh2.material.vertexColors = [new THREE.Color(0xff0000), new THREE.Color(0x00ff00), new THREE.Color(0x0000ff)];
mesh.add( mesh2 );
scene.add(mesh);
}
})();
body {
background: transparent;
padding: 0;
margin: 0;
font-family: sans-serif;
}
#canvas {
margin: 10px auto;
width: 800px;
height: 350px;
margin-top: -44px;
}
<body>
<div id="container"></div>
<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/LoaderSupport.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/OBJLoader2.js"></script>
</body>
So what simple thing am I doing wrong here? I think the problem is in this function:
function loadTexture(imgPath, scene, color, side, mesh) {
var loadedMesh = mesh;
textureLoader.load(imgPath,
function (texture) {
var geometry = new THREE.Geometry().fromBufferGeometry( loadedMesh.children[0].geometry );
mesh.children[0].material.map = texture;
mesh.children[0].material.needsUpdate = true;
scene.add(mesh);
},
undefined,
function ( err ) {
console.error( 'An error occurred...' );
}
);
}
This function gets the mesh then loads the required texture and applies it to the material in the mesh. It then tells the material to update. Is this the correct approach?
This answer here actually only calls render once everything is set it but I want to be-able to change textures, materials etc at run time.
I thought that mesh.children[0].material.needsUpdate = true
would signal the shader program to update...
Thanks