将纹理添加到自定义 three.js 几何体
Add Texture to custom three.js Geometry
我一直在寻找一种方法来将 uv 映射添加到我在 three.js 中的自定义几何体中。我找到了解决方法,但 none 我找到的解决方案有效。谁能解释一下 uv-mapping 是如何工作的以及如何正确地做到这一点?
var s = 100;
var MapHeight = function(x, y, mult){
var map = new Array(x);
for(var i = 0; i < x; i++){
map[i] = new Array(y);
for (var j = 0; j < y; j++) {
map[i][j] = Math.sin((i*12+j)/10)*mult;
}
}
return map;
};
var heightMap = MapHeight(s, s, 0.3);
var loader = new THREE.TextureLoader();
var sandTex = loader.load("Textures/sand.jpeg");
var div = 2;
var Sand = function(color){
var geo = new THREE.Geometry();
var i;
for (i = 0; i < s; i++) {
for (var j = 0; j < s; j++) {
geo.vertices.push(new THREE.Vector3(i/div, heightMap[i][j], j/div));
}
}
for (i = 0; i < (s)*(s-1); i++) {
if (!Number.isInteger((i+1)/s)){
geo.faces.push(new THREE.Face3(i, i+1, i+s+1));
geo.faces.push(new THREE.Face3(i, i+s+1, i+s));
}
}
geo.computeVertexNormals();
geo.computeFaceNormals();
geo.center();
var mesh = new THREE.Mesh(
geo,
new THREE.MeshStandardMaterial({map: map})
);
return mesh;
};
现在,当我尝试将 UV 贴图添加到我的几何体时,结果要么是黑色 material,要么我的程序不是 运行。
纹理坐标必须按面添加到第 1 层 UV 层。
参见 THREE.Geometry.faceVertexUvs
在UV层创建并排列:
geo.faceVertexUvs[0] = [];
并为每个三角形面添加 3 个 THREE.Vector2
的数组:
geo.faceVertexUvs[0].push([
new THREE.Vector2(u0, v1),
new THREE.Vector2(u1, v1),
new THREE.Vector2(u2, v2)
]);
按如下方式将此应用于您的代码:
var geo = new THREE.Geometry();
var i;
var uv = [];
for (i = 0; i < s; i++) {
for (var j = 0; j < s; j++) {
geo.vertices.push(new THREE.Vector3(i/div, heightMap[i][j], j/div));
uv.push(new THREE.Vector2((i-1)/s, (j-1)/s));
}
}
geo.faceVertexUvs[0] = [];
for (i = 0; i < (s)*(s-1); i++) {
if (!Number.isInteger((i+1)/s)){
var vi = [i, i+1, i+s+1, i+s];
geo.faces.push(new THREE.Face3(vi[0], vi[1], vi[2]));
geo.faces.push(new THREE.Face3(vi[0], vi[2], vi[3]));
geo.faceVertexUvs[0].push([ uv[vi[0]], uv[vi[1]], uv[vi[2]] ]);
geo.faceVertexUvs[0].push([ uv[vi[0]], uv[vi[2]], uv[vi[3]] ]);
}
}
geo.computeVertexNormals();
geo.computeFaceNormals();
我一直在寻找一种方法来将 uv 映射添加到我在 three.js 中的自定义几何体中。我找到了解决方法,但 none 我找到的解决方案有效。谁能解释一下 uv-mapping 是如何工作的以及如何正确地做到这一点?
var s = 100;
var MapHeight = function(x, y, mult){
var map = new Array(x);
for(var i = 0; i < x; i++){
map[i] = new Array(y);
for (var j = 0; j < y; j++) {
map[i][j] = Math.sin((i*12+j)/10)*mult;
}
}
return map;
};
var heightMap = MapHeight(s, s, 0.3);
var loader = new THREE.TextureLoader();
var sandTex = loader.load("Textures/sand.jpeg");
var div = 2;
var Sand = function(color){
var geo = new THREE.Geometry();
var i;
for (i = 0; i < s; i++) {
for (var j = 0; j < s; j++) {
geo.vertices.push(new THREE.Vector3(i/div, heightMap[i][j], j/div));
}
}
for (i = 0; i < (s)*(s-1); i++) {
if (!Number.isInteger((i+1)/s)){
geo.faces.push(new THREE.Face3(i, i+1, i+s+1));
geo.faces.push(new THREE.Face3(i, i+s+1, i+s));
}
}
geo.computeVertexNormals();
geo.computeFaceNormals();
geo.center();
var mesh = new THREE.Mesh(
geo,
new THREE.MeshStandardMaterial({map: map})
);
return mesh;
};
现在,当我尝试将 UV 贴图添加到我的几何体时,结果要么是黑色 material,要么我的程序不是 运行。
纹理坐标必须按面添加到第 1 层 UV 层。
参见 THREE.Geometry.faceVertexUvs
在UV层创建并排列:
geo.faceVertexUvs[0] = [];
并为每个三角形面添加 3 个 THREE.Vector2
的数组:
geo.faceVertexUvs[0].push([
new THREE.Vector2(u0, v1),
new THREE.Vector2(u1, v1),
new THREE.Vector2(u2, v2)
]);
按如下方式将此应用于您的代码:
var geo = new THREE.Geometry();
var i;
var uv = [];
for (i = 0; i < s; i++) {
for (var j = 0; j < s; j++) {
geo.vertices.push(new THREE.Vector3(i/div, heightMap[i][j], j/div));
uv.push(new THREE.Vector2((i-1)/s, (j-1)/s));
}
}
geo.faceVertexUvs[0] = [];
for (i = 0; i < (s)*(s-1); i++) {
if (!Number.isInteger((i+1)/s)){
var vi = [i, i+1, i+s+1, i+s];
geo.faces.push(new THREE.Face3(vi[0], vi[1], vi[2]));
geo.faces.push(new THREE.Face3(vi[0], vi[2], vi[3]));
geo.faceVertexUvs[0].push([ uv[vi[0]], uv[vi[1]], uv[vi[2]] ]);
geo.faceVertexUvs[0].push([ uv[vi[0]], uv[vi[2]], uv[vi[3]] ]);
}
}
geo.computeVertexNormals();
geo.computeFaceNormals();