我有一件 T 恤的 .obj,它包含一些网格和材料,我正在使用CanvasTexture
由内联 svg 提供的内容对其进行着色。
现在我应该在特定位置(或多或少在心脏上方)添加一个徽标,但我很难理解哪种方法是最好的/正确的方法(我对 3D 图形和 Three.js 很陌生) . 这是我到目前为止尝试过的:
因为我是通过CanvasTexture
内联 svg 给T 恤着色的,所以我认为在特定坐标处将徽标绘制到 svg 中会很容易。这确实很容易,但徽标不会在纹理/网格上呈现(或以某种方式不可见),尽管它在内嵌 svg 中可见。所以CanvasTexture
可能不适用于嵌入的图像(我尝试了 base64 和 URL)
所以,我开始研究更多的 3d “原生”方式来做这件事,但我还没有找到一种对我来说真正有意义的方式。我知道ShaderMaterial
在 Threejs 中有,我可以用它来有选择地渲染徽标的像素或布料的像素,但这意味着要进行大量复杂的计算才能确定徽标的位置,而且我无法相信绘制简单的 JPEG或具有特定坐标和大小的 PNG 可能如此复杂......我一定错过了一个明显的解决方案。
编辑
这是我如何将图像添加到内联 svg(上面的选项 1)。
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);
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'));
}
});
};
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...]
出于某种原因,画布不喜欢带有嵌入图像的 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);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句