Three js - Лучший способ визуализации текстуры изображения только в части сетки - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть .obj футболки, она содержит несколько мешей и материалов, и я раскрашиваю ее, используя CanvasTexture, питаемый встроенным svg.

Теперь я должен добавить lo go в указанном c месте (более или менее над сердцем), но я изо всех сил пытаюсь понять, какой лучший / правильный способ сделать это (я довольно плохо знаком с трехмерной графикой и Three. js). Это то, что я пробовал до сих пор:

  • , так как я раскрашиваю футболку через CanvasTexture, питаемую встроенным svg, я думал, что было бы просто нарисовать lo go в svg в указанных c координатах. И это действительно было легко, но lo go не отображается (или каким-то образом не виден) на текстуре / me sh, хотя это видно в встроенном svg. Так что CanvasTexture, вероятно, не работает со встроенными изображениями (я пробовал и base64, и URL)

  • , поэтому я начал искать более 3d "родные" способы сделать это, но я не нашел тот, который действительно имеет смысл для меня. Я знаю, что есть ShaderMaterial в трех js, которые я мог бы использовать для выборочной визуализации пикселей lo go или пикселей ткани, но это означает, что нужно выполнить много сложных вычислений, чтобы выяснить, где lo go должно быть, и я не могу поверить, что рисование простого JPEG или PNG с указанными c координатами и размером может быть настолько сложным ... Я, должно быть, упустил очевидное решение.

РЕДАКТИРОВАТЬ

Вот как я добавляю изображение к встроенному svg (вариант 1 выше).

  1. Добавление изображения к встроенному svg
const groups = Array.from(svg.querySelectorAll('g'));
// this is the "g" tag where I want to add the logo into
const targetGroup = groups.find((group: SVGGElement) => group.getAttribute('id') === "logo_placeholder");

const image = document.createElement('image');
image.setAttribute('width', '64');
image.setAttribute('height', '64');
image.setAttribute('x', '240');
image.setAttribute('y', '512');
image.setAttribute('xlink:href', `data:image/png;base64,${base64}`);

targetGroup.appendChild(image);
Рисование встроенного SVG на 2D холсте
static drawSvgToCanvas = async (canvas: HTMLCanvasElement, canvasSize: TSize, svgString: string) => {
  return new Promise((resolve, reject) => 
    canvas.width = canvasSize.width;
    canvas.height = canvasSize.height;

    const ctx = canvas.getContext('2d');

    const image = new Image(); // eslint-disable-line no-undef
    image.src = `data:image/svg+xml;base64,${btoa(svgString)}`;
    image.onload = () => {
      if (ctx) {
        ctx.drawImage(image, 0, 0);
          resolve();
        } else {
          reject(new Error('2D context is not set on canvas'));
        }
      };

    image.onerror = () => {
      reject(new Error('Could not load svg image'));
    }
 });
};
Нарисуйте 2D холст на три js Текстура
const texture = new Three.CanvasTexture(canvas);
texture.mapping = Three.UVMapping; // it's the default
texture.wrapS = Three.RepeatWrapping;
texture.wrapT = Three.RepeatWrapping; // it's the default
texture.magFilter = Three.LinearFilter; // it's the default
texture.minFilter = Three.LinearFilter;
texture.needsUpdate = true;

[...add texture to material...]

1 Ответ

0 голосов
/ 13 апреля 2020

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

Сначала отрендерим SVG на холсте, а затем визуализируйте изображение поверх него (на том же холсте).

const ctx = canvas.getContext('2d');
ctx.drawImage(imgSVG, 0, 0);
ctx.drawImage(img2, 130, 10, 65, 90);

const texture = new THREE.CanvasTexture(canvas);

Пример: https://jsfiddle.net/0f9hm7gx/

...