gpt4 book ai didi

three.js - 如何减小和增加对象上图像的大小 - ThreeJS

转载 作者:行者123 更新时间:2023-12-04 08:21:59 30 4
gpt4 key购买 nike

我正在使用 THREE.ImageUtils.loadTexture加载图像然后将其粘贴到我场景中的每个对象上的函数,如下所示:

_.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);

有没有人有这方面的例子?

编辑

感谢到目前为止的反馈。 @Martin 我已经设置了一个基本的 PlaneGeometry形状来测试一下。所以这个形状的脸是基本的两个相互连接的三角形;我附上了您发布的 uv 设置的图像:

enter image description here

因此,根据您所说,我无法扩展其中一个三角形,因为这会破坏所使用的几何形状,因此我需要操纵两个三角形以正确移动图像。正确的?

最佳答案

不幸的是,在three.js 中没有简单的方法可以做到这一点。

为了正确控制非平凡网格的纹理,您可能需要做一些 UV-unwrapping首先是模型。这通常应该由提供网格的人来完成,因为在 blender 、3dstudio、cinema4d 等工具中更容易做到这一点。

但是,我假设您由于某种原因没有那个人可用,并且需要在 javascript 中执行此操作。这种方式更有趣。让我们进一步假设,我们只想将图像映射到包的正面和背面,内部和边缘不会被纹理化。

在 three.js 和大多数其他 3D 应用程序中,纹理的精确映射是通过为每个面的每个顶点提供纹理坐标(也称为 UV 坐标)来实现的。这些 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;

所以,这只是几何本身,但重要的是要知道它是如何为下一步构建的——UV坐标:
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 能够处理两组不同的 uv 坐标,这就是为什么有 geometry.faceVertexUvs[0] .
  • 该数组中的索引对应于 faces-array 中的索引,所以 uvs[0]是第一张脸和uvs[1]第二。
  • 每一个又是一个长度为 3 的数组,对应于该面的顶点。

  • 现在,在您的包的情况下,应该可以找出哪两个面是正面和背面部分。您将需要找到它们并编辑它们的 UV 坐标以匹配您想要查看的图像中的位置(我不知道这些模型的外观如何,所以在这里我无法为您提供更多帮助)。所有其他 UV 坐标都可以设置为某个安全值,例如 (0, 0) ,那么所有不是正面或背面的东西都将具有纹理左下角像素的颜色。

    如果您也想对它们进行纹理处理,您应该真正考虑在适当的 3D 编辑软件中进行纹理映射。

    编辑 (2017-01-15)

    查看带有 angular-logo 的图像,左上角的三角形被翻转。这是因为 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])

    现在对于另一点,缩放纹理。您可以尝试的一件事是对顶点使用大于 1 的 UV 值。这将导致纹理绘制得更小。但是,这只有在以下情况下才能正常工作
  • 纹理环绕模式是钳制到边缘(texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;)
  • 所有纹理都有一个 1px 宽的中性色边框

  • 否则(这是我推荐的方式)您应该使用 Canvas 作为纹理并在实际使用之前准备图像。我在这里做了一个简单的例子: http://codepen.io/usefulthink/pen/GrjmrM?editors=0010

    关于three.js - 如何减小和增加对象上图像的大小 - ThreeJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41490489/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com