我正在使用Three.js生成一个由画布元素生成的具有不同颜色和文本的多面体。目前,我正在使用Three.js原生类生成多面体,但在某些时候,我想尝试更不规则的形状。
网上有许多示例(包括StackOverflow帖子,例如Three.js每个面都有不同贴图的立方体)可以解释如何用立方体实现。我没有找到任何适用于非立方体的相同技术的样本,但对于大部分情况来说,适用于CubeGeometry的过程也适用于TetrahedronGeometry等其他类。
以下是我用来生成多面体的简化代码:
这种技术可以完美地渲染立方体,但是对于其他多面体而言,纹理的表现并不如预期:
很难准确地解释这里发生了什么。基本上,每个面都显示了正确的纹理,但是纹理本身已经被拉伸和移动,好像要覆盖整个多面体。换句话说,从正面观察,左上角的面只显示其纹理的左上部分,右上角的面只显示其纹理的右上部分,依此类推。
多面体相对面上没有任何纹理细节,只有颜色。
在尝试 Three.js 之前,我没有任何 3D 渲染经验,因此我想象可能有一些步骤我错过了,立方体几何体可以自动处理,但其姐妹类不行。我想参考其他已发布的示例,但大多数示例都是渲染立方体,而那些不是则通常使用实心颜色。
为使非立方体形状的纹理缩放和居中,需要做些什么呢?
网上有许多示例(包括StackOverflow帖子,例如Three.js每个面都有不同贴图的立方体)可以解释如何用立方体实现。我没有找到任何适用于非立方体的相同技术的样本,但对于大部分情况来说,适用于CubeGeometry的过程也适用于TetrahedronGeometry等其他类。
以下是我用来生成多面体的简化代码:
switch (shape) {
case "ICOSAHEDRON" :
// Step 1: Create the appropriate geometry.
geometry = new THREE.IcosahedronGeometry(PolyHeatMap.GEOMETRY_CIRCUMRADIUS);
// Step 2: Create one material for each face, and combine them into one big
// MeshFaceMaterial.
material = new THREE.MeshFaceMaterial(createMaterials(20, textArray));
// Step 3: Pair each face with one of the materials.
for (x = 0; face = geometry.faces[x]; x++)
{
face.materialIndex = x;
}
break;
// And so on, for other shapes.
}
function createTexture (title, color) {
var canvas = document.createElement("canvas");
// Magical canvas generation happens here.
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return new THREE.MeshLambertMaterial({ map : texture });
}
function createMaterials (numFacets, textArray)
{
var materialsArray = [],
material;
for (var x = 0, xl = numFacets; x < xl; x++)
{
material = createTexture(textArray[x], generateColor(textArray[x]));
material.side = THREE.DoubleSide;
materials.push(oMaterial);
}
return materials;
}
这种技术可以完美地渲染立方体,但是对于其他多面体而言,纹理的表现并不如预期:
![Icosahedron Example](https://istack.dev59.com/7Mcgo.webp)
多面体相对面上没有任何纹理细节,只有颜色。
在尝试 Three.js 之前,我没有任何 3D 渲染经验,因此我想象可能有一些步骤我错过了,立方体几何体可以自动处理,但其姐妹类不行。我想参考其他已发布的示例,但大多数示例都是渲染立方体,而那些不是则通常使用实心颜色。
为使非立方体形状的纹理缩放和居中,需要做些什么呢?