Как изменить текстуру 3D модели по клику?
Не получается изменить текстуру 3Д модели по клику в Realtime, не могу найти ответ, что отвечает за перерисовку объекта. Смотрел в справочнике Three.js примеры, не могу все равно понять что и за что отвечает :( Помогите разобраться. Функция работает, и переменная получает значение новой текстуры, но изменения не происходят.
// Сhange material color
const color_white = { materials: "white" };
const color_grey = { materials: "grey" };
const color_craft = { materials: "craft" };
changeColor = function(input) {
if (input.value === "craft") {
materials = color_craft.materials;
} else if (input.value === "grey") {
materials = color_grey.materials;
} else if (input.value === "white") {
materials = color_white.materials;
}
console.log(materials);
};
// Create Camera
camera = new THREE.PerspectiveCamera(current_box.perCam, window.innerWidth / window.innerHeight, 0.25, 20);
camera.position.x = current_box.posX;
camera.position.y = current_box.posY;
camera.position.z = current_box.posZ;
camera.rotation.y += 1 * (Math.PI/180);
// Create a Controls
controls = new THREE.OrbitControls(camera, container);
controls.enablePan = false;
controls.enableZoom = true;
controls.minDistance = current_box.minDistance;
controls.maxDistance = current_box.maxDistance;
controls.update();
// Object resize
function resize() {
camera.aspect = w / h;
camera.updateProjectionMatrix();
renderer.setSize( w, h );
animate();
console.log('element resized: ' + w + 'x' + h);
}
window.addEventListener('resize', resize);
// Create a Lights
const pointLight = new THREE.PointLight( 0xffffff, 1.0, 3000 );
pointLight.position.set( 1500, 1500, 1300 );
const ambientLight = new THREE.AmbientLight( 0x999999 ); // soft white light
scene.add(ambientLight, pointLight, );
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round( percentComplete, 2 ) + '% downloaded' );
}
};
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio);
container.append( renderer.domElement );
function loadModel() {
object.traverse( function ( obj ) {
if ( obj.isMesh )
obj.material.map = texture;
material.needsUpdate = true;
} );
object.position.y = 0;
object.position.x = 0;
object.position.z = 0;
scene.add( object );
resize();
animate();
}
var manager = new THREE.LoadingManager( loadModel );
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
// Load texture
var textureLoader = new THREE.TextureLoader( manager );
var texture = textureLoader.load(basePath+'materials/'+materials+'.jpg', function(){
material.map = texture;
material.needsUpdate = true;
});
var mtlLoader = new THREE.MTLLoader( manager );
mtlLoader.load(basePath+models+'.mtl', function(materials) {
materials.preload();
var loader = new THREE.OBJLoader( manager );
loader.load(basePath+models+'.obj', function ( obj ) {
object = obj;
scene.add(obj);
scene.updateMatrixWorld(true);
}, onProgress, onError);
});
function onProgress( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( 'model ' + Math.round( percentComplete, 2 ) + '% downloaded' );
}
}
function onError() {}
// Render scene
function animate() {
renderer.render(scene,camera);
requestAnimationFrame(animate);
}
Ответы (1 шт):
Автор решения: prisoner849
→ Ссылка
Вот такой вариант: загружать текстуры в массив и потом по нажатию на кнопку назначать материалу ту или иную текстуру в свойство .map.
body {
overflow: hidden;
margin: 0;
}
button {
position: absolute;
}
<button id="tex_0">Texture0</button>
<button id="tex_1" style="left: 100px;">Texture1</button>
<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';
var container;
var camera, scene, renderer;
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');
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, 0.8);
camera.add(pointLight);
scene.add(camera);
// manager
function loadModel() {
setTexture(0);
object.position.y = -95;
scene.add(object);
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
// texture
var textures = [];
var textureLoader = new THREE.TextureLoader(manager);
textures.push(
textureLoader.load('https://threejs.org/examples/textures/uv_grid_opengl.jpg'),
textureLoader.load('https://threejs.org/examples/textures/colors.png')
);
tex_0.addEventListener("click", function(){setTexture(0);});
tex_1.addEventListener("click", function(){setTexture(1);});
function setTexture (texIdx){
object.traverse(function(child) {
if (child.isMesh) {
child.material.map = textures[texIdx];
}
});
}
// 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/male02/male02.obj', function(obj) {
object = obj;
}, onProgress, onError);
//
renderer = new THREE.WebGLRenderer();
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) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>