#javascript #graphics #three.js #3d #gltf
#javascript #графика #three.js #3D #gltf
Вопрос:
Я попытался динамически изменить текстуру модели glTF, заменив текстуру на THREE.TextureLoader
. Цвет текстуры изменился, как я и ожидал, однако рисунок текстуры был несколько смешанным.
Я впервые занимаюсь веб-графикой. Я переделывал пример просмотра 3D-моделей с помощью three.js это может загружать модели glTF. Я хотел динамически изменять текстуру с помощью кнопок. Из различных форматов я выбрал glTF, потому что он казался новым стандартом. Лучшим решением, которое я мог найти до сих пор, было добавить texture.flipY = false;
под моим загрузчиком текстур, но это не сработало. Я также пытался изменить некоторые значения внутри объекта текстуры, но ничего не произошло.
Здесь я загружаю свою модель:
loader.load( urls, function (texture) {
var pmremGenerator = new THREE.PMREMGenerator( texture );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker(pmremGenerator.cubeLods);
pmremCubeUVPacker.update( renderer );
var envMap = pmremCubeUVPacker.CubeUVRenderTarget.texture;
var loader = new THREE.GLTFLoader().setPath( `models/${modelName}/`);
loader.load(`${modelName}.gltf`, (gltf) => {
gltf.scene.traverse((child) => {
if (child.isMesh) {
child.material.envMap = envMap;
}
});
gltf.scene.scale.set(0.01,0.01,0.01)
scene.add(gltf.scene);
});
и я попытался изменить ее текстуру, реализовав эту функцию:
function changeColor(color) {
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load(`models/${modelName}/textures/fabric-${color}.jpg`);
texture.flipY = false;
scene.traverse((child) => {
if (child.isMesh) {
if (child.material.map.format === 1022) {
child.material.map = texture;
}
}
});
}
Хотя я смог настроить таргетинг на нужную мне сетку и изменил ее цвет, шаблон текстуры был очень неудобным. Это была верхняя часть стула, сделанная из ткани.
чтобы нарисовать это в тексте, это выглядело так…
Что это должно было быть:
-------------------
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
| / / / / / / / / |
-------------------
Figure 1
Реальность:
-------------------
| |
| |
| |
| |
| |
| |
| |
-------------------
Figure 2
Для ясности:
Как я могу сохранить шаблон текстуры, как показано на рисунке 1, при изменении файла текстуры с помощью функции выше?
Комментарии:
1. Хотя мне нравятся иллюстрации в формате ASCII, немного сложно понять, что вы здесь видите. 😉 Вы правильно настроили
flipY=false
. Помимо этого, есть ли у модели текстура изначально, которую вы меняете? Или текстура не встроена, но вы ее добавляете? Если сетки в модели не имеют UVS (mesh.geometry.attributes.uv
), это будет проблемой. Обычно UV-отображение — это способ управления расположением текстуры в сетке, и это лучше всего делать в таком инструменте, как Blender.2. @DonMcCurdy извините за мой плохой рисунок: ( если вы не возражаете, вы можете посетить эту ссылку , чтобы посмотреть, как это выглядит. Да, у модели изначально есть текстура, и я пытался просто изменить
material.map
с помощью нового файла JPG, который я покрасил по-другому. Я попробую что-нибудь с UV-отображениями. Спасибо за помощь.
Ответ №1:
Благодаря помощи DonMcCurdy я наконец получил ответ.
Это действительно была проблема с отображением UV.
Чтобы получить текстуру в нужном месте, мне нужно было добавить эти: wrapS, wrapT и RepeatWrapping
function changeColor(color) {
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load(`models/${modelName}/textures/fabric-${color}.jpg`);
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.flipY = false;
scene.traverse((child) => {
if (child.isMesh) {
if (child.material.map.format === 1022) {
child.material.map = texture;
}
}
});
}
Официальная документация:
https://threejs.org/docs/#api/en/textures/Texture