2017-01-05 3 views
8

Я использование функции THREE.ImageUtils.loadTexture, чтобы загрузить изображение, а затем вставить его на каждый из объектов в моей сцене так:Как уменьшить и увеличить размер изображения на объекте - ThreeJS

_.forEach(bags, (bag) => { 
    if(bag['children'][0] && bag['children'][0].material) { 
    let material = new THREE.MeshPhongMaterial({map: tex}); 
    bag['children'][0].material = material; 
    } 
}); 

Я посмотрел в tex.scale.x, tex.scale.y & tex.offset.x, tex.offset.y, но они не кажется, что мне нужно. Вот то, что объект выглядит на данный момент

enter image description here

, но я после строгого позиционирования на каждой стороне. Что-то вроде этого (псевдокод), который помещает верхний левый угол на нужную сторону в этом положении.

sideA.image.setSize(x,y); 

У кого-нибудь есть примеры этого?

EDIT

Спасибо за обратную связь до сих пор ребята. @Martin Я установил базовую форму PlaneGeometry, чтобы проверить это. Таким образом, это лицо формы представляет собой два основных треугольника, прикрепленных друг к другу; Я приложил изображение того, что параметры уф, что вы Отправленные сделать:

enter image description here

Так от того, что вы сказали, что я не могу расширить один из треугольников, как бы нарушить геометрию, используемую так что мне нужно управляйте обоими треугольниками, чтобы правильно перемещать изображение. Верный?

+0

Нужная информация о том, какой путь вы загрузили obj (сетка) и сколько у вас контроля над файлом из текстур ... Вы можете сделать сетку с текстурой для каждой стороны а затем как угодно, или вам нужно будет создать свои собственные координаты uv. Попробуйте это, я работал над http://stackoverflow.com/questions/29877032/three-js-webgl-custom-shader-sharing-texture- with-new-offset/30243114 # 30243114 – joshua

ответ

5

К сожалению, нет простого способа сделать это в three.js.

Чтобы получить правильный контроль над текстурированием нетривиальных сеток, вам, вероятно, сначала понадобится сделать UV-unwrapping модели. Обычно это должно делать человек, предоставляющий сетки, потому что это проще сделать в таких инструментах, как blender, 3dstudio, cinema4d и т.п.

Однако, я предполагаю, что у вас нет этого человека по какой-либо причине и нужно сделать это в javascript. Это так забавно. Предположим далее, что мы просто хотим отобразить изображение на переднюю и заднюю стороны сумки, внутри и края не будут текстурированы.

В трехмерных и трехмерных приложениях точное отображение текстуры происходит путем предоставления координат текстуры (или UV-координат) для каждой вершины для каждой грани. Эти УФ-координаты (от 0 до 1) определяют положение текстуры, принадлежащей вершине. Точка (0, 0) - это нижний левый угол изображения, а (1, 1) - верхний правый угол, независимо от соотношения сторон изображения.

Таким образом, для простого четырехугольника, изготовленный из двух треугольников, это будет что-то вроде этого:

const geometry = new THREE.Geometry(); 
const vertices = [ 
    // the four vertices ABCD 
    [0,0,0], [0,1,0], [1,0,0], [1,1,0] 
].map(v => new THREE.Vector3(...v)); 

// setup two triangles ADB and ACD: 
// 
// B---D 
// |/| 
// A---C 

const normal = new THREE.Vector3(0,0,1); 
const faces = [ 
    new THREE.Face3(0, 3, 1, normal), 
    new THREE.Face3(0, 2, 3, normal) 
]; 

geometry.vertices = vertices; 
geometry.faces = faces; 

Таким образом, это просто сама геометрии, но это важно знать, как он был построен для следующего шага - УФ-координаты:

const uvs = geometry.faceVertexUvs[0]; 
const vertexUvs = [ 
    [0,0], [0,1], [1,0], [1,1] 
].map(p => new THREE.Vector2(...p)); 

// we need to set the UV-coordinates for both faces separately, using 
// the same scheme as before: 
uvs[0] = [vertexUvs[0], vertexUvs[3], vertexUvs[1]]; 
uvs[1] = [vertexUvs[0], vertexUvs[2], vertexUvs[3]]; 

И все в порядке. Это примерно то, что делает THREE.PlaneGeometry.Еще некоторые моменты о том, что:

  • Three.js способен обрабатывать два различных набора уф-координат, поэтому есть geometry.faceVertexUvs[0].
  • индексы внутри этого массива соответствуют индексам в массиве faces, поэтому uvs[0] - это первая грань и uvs[1] вторая.
  • каждый из них снова представляет собой массив длиной 3, соответствующий вершинам этой грани.

Теперь в случае ваших сумок должно быть возможно выяснить, какие две стороны - лицевая сторона и обратная сторона. Вам нужно будет найти их и отредактировать их UV-координаты, чтобы они соответствовали позициям изображения, которое вы хотите увидеть (я не знаю, как именно выглядят эти модели, поэтому я не могу больше помочь вам здесь). Все другие УФ-координаты могут быть установлены на какое-то безопасное значение, например (0, 0), тогда все, что не является фронтальным или задним, будет иметь цвет нижнего левого пикселя вашей текстуры.

Если вы хотите текстурировать их также, вы должны действительно рассмотреть возможность создания текстурной карты в правильном программном обеспечении для редактирования 3D.

РЕДАКТИРОВАТЬ (2017-01-15)

Глядя на изображение с угловым логотипом, верхний левый треугольник переворачивается. Это связано с тем, что three.js использует другой граничный или вершинный порядок, чем в моем примере.

Это помогает понять это, если вы просто играете с ним в браузере-консоли или отладчике (это то, что я только что сделал). В соответствии с этим, самолет-геометрии из three.js имеет следующую структуру:

// A---B 
// |/| 
// C---D 

vertices = [A, B, C, D] 
faces = [Face3(A, C, B), Face3(C, B, D)] 

Примечательным здесь, по какой-либо причине, первое лицо против часовой стрелки, и второе лицо по часовой стрелке порядка (я считаю, что это плохая практика, и треугольники всегда должны быть против часовой стрелки). Посмотрите на faceVertexUVs для геометрии, чтобы увидеть, как это должно выглядеть для этого случая (просто введите new THREE.PlaneGeometry(1,1).faceVertexUvs[0] в консоль браузера)

Теперь для другой точки, масштабируя текстуры. Одна вещь, которую вы можете попробовать, - использовать значения UV, превышающие 1 для вершин. Это приведет к уменьшению текстуры. Тем не менее, это будет работать только если

  • обертка режим текстура зажим к краю (texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;)
  • всех текстур имеют 1px границы ширины в нейтральном цвете

В противном случае (и именно так я бы рекомендовал), вы должны использовать холст в качестве текстуры и подготовить изображение до его фактического использования. Я сделал простой пример здесь: http://codepen.io/usefulthink/pen/GrjmrM?editors=0010

+0

Возможно, текстурные коорды этой модели расположены так, чтобы позволить скинированию - использование одной текстуры, которая обертывает весь объект, а не 4 или 5 разделенных текстур. Взгляните взглядом с Lithunwrap или каким-нибудь другим (и более новым) моделированием SW. – Monza

+0

Ну, мы должны угадать, основываясь на изображении, предоставленном OP, и это говорит о очень простом cube'ish-mapping с использованием единственной текстуры. Возможно, это хорошо для небольших повторяющихся текстур. Также я согласен с тем, что для этого нужно использовать одну текстуру, но ее необходимо развернуть без использования неискаженных изображений. –

+0

Спасибо за ответ Мартин и сожалею, что мне так долго приходилось возвращаться к тебе. Я считаю, что то, что вы описываете, по сути является тем, что мне нужно, но результаты не были правильными, потому что стороны, к которым добавляются изображения, состоят из двух треугольников, поэтому изображение будет разворачиваться на каждом из них соответственно вместо коллективного. Я начал новый вопрос, который следует из этого, если вы хотите следить за http://stackoverflow.com/questions/41673535/why-do-two-faces-appear-invisible-in-threejs – Katana24

Смежные вопросы