Итак, у меня есть эта сцена, полученная из glb-файла, который я импортировал с помощью GLTFLoader. Он содержит эти объекты парней в разных цветах. Каждый объект имеет свой материал (RedMat, BlueMat, GreenMat и т.д.). Материалы сделаны в Blender, и все они используют один и тот же файл текстуры (этот), который в основном представляет собой просто цветовую палитру. Таким образом, разные цвета объектов просто исходят из того, что каждый материал имеет разное значение UV.
Пока это работает хорошо, и объекты имеют правильные цвета, когда я загружаю их с помощью GLTFLoader и отображаю в своей сцене three.js (скриншот из рендеринга three.js). Но я хочу иметь возможность обновлять материал одного объекта, чтобы, например, красный объект брал материал зеленого объекта.
new GLTFLoader().load('myfile.glb', function (gltf) {
const redGuy = gltf.scene.children.find(x => x.name === 'RedGuy');
const greenGuy = gltf.scene.children.find(x => x.name === 'GreenGuy');
redGuy.material = greenGuy.material; // I expect here that the red guy would become green, but nothing happens
// But if I instead do this:
redGuy.material = new THREE.MeshPhongMaterial({color: '#FF0000'});
// that works, but I want to be able to use the materials I already setup in Blender that are in the glb-file
});
Кроме того, если я console.info redGuy.material и greenGuy.material в консоли, они выглядят почти одинаково, что я нахожу странным, у них просто разные имена и идентификаторы.
Очевидно, это короткий фрагмент, демонстрирующий мою проблему, надеюсь, этого достаточно. В противном случае я мог бы загрузить весь проект и файл Blender куда-нибудь, если это необходимо.
Не могли бы вы поделиться файлом glb в этой теме?
Судя по атласу текстур, вам, вероятно, нужно преобразовать UV-координаты модели, а не изменить материал. Цвет исходит из позиций в текстуре.
@emackey да, это звучит правдоподобно, но я предположил, что координаты UV были частью материала. Где найти координаты UV в дочернем узле? Там вроде ничего по этому поводу нет.
Как вы обнаружили, это часть геометрии. Вероятно, есть какой-то способ применить преобразование текстуры, но похоже, что в этом случае работает просто выбор другой геометрии. Также вы можете немного оптимизировать, повторно использовать один и тот же материал Blender для всех этих объектов, поскольку все они указывают на одну и ту же текстурную карту.
@emackey Спасибо. Да, в этом случае этот метод, кажется, работает, хотя он не кажется оптимизированным, потому что объект «геометрия» на самом деле очень большой и содержит много вещей, и я не уверен, что это все такое, если бы я знал, какой дочерний элемент У геометрии были UV-координаты, которые я мог бы только скопировать. И да, повторяющиеся материалы кажутся пустой тратой времени, это была моя попытка решить эту проблему, разбив их на отдельные материалы (хотя в основном они одинаковы).
Взгляните на некоторые свойства текстур: threejs.org/docs/index.html#api/en/textures/… и threejs.org/docs/index.html#api/en/textures/Texture.offset . Я думаю, вы можете компенсировать UV без копирования какой-либо геометрии.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Итак, я наконец узнал ответ. Вместо
redGuy.material = greenGuy.material;
я должен написать
redGuy.geometry = greenGuy.geometry;
В этом случае цвета различных объектов определяются координатами UV. Я думал, что они будут частью узла материала, но оказалось, что они находятся в узле геометрии.
возможен дубликат? stackoverflow.com/questions/56660584/…