我正在为非正交立方体做一个定制的three.js几何。它松散地基于three.js中现有的Box-几何学,但是它的顶点的绝对位置直接输入到它。
我对three.js有个问题,它似乎不尊重我传递给几何学面的法线。当我在将法线赋值给人脸之前对其进行console.log时,它们看起来很好:
normal: Object { x=0, y=0, z=-1, more...}
normal: Object { x=0, y=0, z=1, more...}这些法线只适合直角立方体的上、下两面。然而,从这张截图中可以看到(如果我适当地倾斜了相机),第一个法线似乎已经应用于两个表面:

这是200x200x200立方体的两面,中心在猎户座,与所有轴正交。白线表示z轴.
下面是我的错误几何学。“四重集”数组包含六个数组,每个数组包含四个Vector3实例。每个内部数组都勾勒出立方体的一侧。
THREE.Box3Geometry = function (quadruplets, normals, debug) {
THREE.Geometry.call(this);
var constructee = this; // constructee = the instance currently being constructed by the Box3Geometry constructor
buildPlane(quadruplets[0], normals[0], 0, debug); // px
buildPlane(quadruplets[1], normals[1], 1, debug); // nx
// buildPlane(quadruplets[2], normals[2], 2); // py
// buildPlane(quadruplets[3], normals[3], 3); // ny
// buildPlane(quadruplets[4], normals[4], 4); // pz
// buildPlane(quadruplets[5], normals[5], 5); // nz
function buildPlane(quadruplet, normal, materialIndex, debug) {
var offset = constructee.vertices.length;
// populate the vertex array:
constructee.vertices.push(quadruplet[0]);
constructee.vertices.push(quadruplet[1]);
constructee.vertices.push(quadruplet[2]);
constructee.vertices.push(quadruplet[3]);
// construct faceVertexUvs:
var uva = new THREE.Vector2(0, 1); //(u:0, v:1), uvb: (u:0, v:0) uvc: (u:1, v:0), uvd: (u:1, v:1)
var uvb = new THREE.Vector2(0, 0);
var uvc = new THREE.Vector2(1, 0);
var uvd = new THREE.Vector2(1, 1);
// construct faces:
var a = 0; // vertex: u:50, v:50
var b = 2; // vertex: u:50, v:-50
var c = 3; // vertex: u:-50, v:-50
var d = 1; // vertex: u:-50, v:50
if (debug) { console.log("normal: ", normal); }
// make a face:
var face1 = new THREE.Face3(a + offset, b + offset, d + offset);
face1.normal.copy(normal);
face1.vertexNormals.push(normal.clone(), normal.clone(), normal.clone());
face1.materialIndex = materialIndex;
constructee.faces.push(face1);
constructee.faceVertexUvs[ 0 ].push([ uva, uvb, uvd ]);
// make another face:
var face2 = new THREE.Face3(b + offset, c + offset, d + offset);
face2.normal.copy(normal);
face2.vertexNormals.push(normal.clone(), normal.clone(), normal.clone());
face2.materialIndex = materialIndex;
constructee.faces.push(face2);
constructee.faceVertexUvs[ 0 ].push([ uvb.clone(), uvc, uvd.clone() ]);
};
this.mergeVertices();
};
THREE.Box3Geometry.prototype = Object.create(THREE.Geometry.prototype);这是我对几何的测试实例化:
var quadruplets = [
[new THREE.Vector3(-100, -100, -100), new THREE.Vector3(100, -100, -100), new THREE.Vector3(-100, 100, -100), new THREE.Vector3(100, 100, -100)],
[new THREE.Vector3(-100, -100, 100), new THREE.Vector3(100, -100, 100), new THREE.Vector3(-100, 100, 100), new THREE.Vector3(100, 100, 100)],
[new THREE.Vector3(-100, -100, -100), new THREE.Vector3(100, -100, -100), new THREE.Vector3(-100, -100, 100), new THREE.Vector3(100, -100, 100)],
[new THREE.Vector3(-100, 100, -100), new THREE.Vector3(100, 100, -100), new THREE.Vector3(-100, 100, 100), new THREE.Vector3(100, 100, 100)],
[new THREE.Vector3(-100, -100, -100), new THREE.Vector3(-100, 100, -100), new THREE.Vector3(-100, -100, 100), new THREE.Vector3(-100, 100, 100)],
[new THREE.Vector3( 100, -100, -100), new THREE.Vector3( 100, 100, -100), new THREE.Vector3( 100, -100, 100), new THREE.Vector3( 100, 100, 100)]
];
var normals = [
new THREE.Vector3( 0, 0, -1),
new THREE.Vector3( 0, 0, 1),
new THREE.Vector3( 0, -1, 0),
new THREE.Vector3( 0, 1, 0),
new THREE.Vector3(-1, 0, 0),
new THREE.Vector3( 1, 0, 0)
];
var myBox3Geometry = new THREE.Box3Geometry(
quadruplets,
normals,
true
);发布于 2014-09-03 19:04:01
我在自定义几何学问题,直面法的姆多布问题的答案中找到了这个问题的答案。
总之,我们必须改变给人脸的顶点的顺序,以控制法线指向的方向。
因此,我的代码现在如下所示:
THREE.Box3Geometry = function (quadruplets, normals, debug) {
THREE.Geometry.call(this);
var constructee = this; // constructee = the instance currently being constructed by the Box3Geometry constructor
buildPlane(quadruplets[0], normals[0], 0, debug); // px
buildPlane(quadruplets[1], normals[1], 1, debug); // nx
buildPlane(quadruplets[2], normals[2], 2); // py
buildPlane(quadruplets[3], normals[3], 3); // ny
buildPlane(quadruplets[4], normals[4], 4); // pz
buildPlane(quadruplets[5], normals[5], 5); // nz
function buildPlane(quadruplet, normal, materialIndex, debug) {
if (debug) {
console.log("materialIndex: ", materialIndex);
console.log("normal: ", normal);
}
var offset = constructee.vertices.length;
// populate the vertex array:
constructee.vertices.push(quadruplet[0]);
constructee.vertices.push(quadruplet[1]);
constructee.vertices.push(quadruplet[2]);
constructee.vertices.push(quadruplet[3]);
// construct faceVertexUvs:
var uva = new THREE.Vector2(0, 1); //(u:0, v:1), uvb: (u:0, v:0) uvc: (u:1, v:0), uvd: (u:1, v:1)
var uvb = new THREE.Vector2(0, 0);
var uvc = new THREE.Vector2(1, 0);
var uvd = new THREE.Vector2(1, 1);
// construct faces:
var a = 0; // vertex: u:50, v:50
var b = 2; // vertex: u:50, v:-50
var c = 3; // vertex: u:-50, v:-50
var d = 1; // vertex: u:-50, v:50
// decide the ordering of the face vertices:
var reference_vertex = a + offset;
var x = constructee.vertices[reference_vertex].clone().sub(normal); // x: the normal relative to reference_vertex
if (debug) { console.log("x: ", x); }
var face_tangential_vector_b_a = constructee.vertices[b + offset].clone().sub(constructee.vertices[reference_vertex]);
var face_tangential_vector_d_a = constructee.vertices[d + offset].clone().sub(constructee.vertices[reference_vertex]);
var face_tangential_vector_x_a = x.sub(constructee.vertices[reference_vertex]);
var matrix = utils.matrix_from_column_vectors(
face_tangential_vector_b_a,
face_tangential_vector_d_a,
face_tangential_vector_x_a
);
var determinant = utils.matrix3Determinant(matrix);
if (debug) { console.log("determinant: ", determinant); }
// make two faces:
if (determinant < 0) {
var face1 = new THREE.Face3(a + offset, b + offset, d + offset);
constructee.faceVertexUvs[ 0 ].push([ uva, uvb, uvd ]);
var face2 = new THREE.Face3(b + offset, c + offset, d + offset);
constructee.faceVertexUvs[ 0 ].push([ uvb.clone(), uvc, uvd.clone() ]);
} else {
var face1 = new THREE.Face3(a + offset, d + offset, b + offset);
constructee.faceVertexUvs[ 0 ].push([ uva, uvd, uvb ]);
var face2 = new THREE.Face3(b + offset, d + offset, c + offset);
constructee.faceVertexUvs[ 0 ].push([ uvb.clone(), uvd.clone(), uvc ]);
}
face1.normal.copy(normal);
face1.vertexNormals.push(normal.clone(), normal.clone(), normal.clone());
face1.materialIndex = materialIndex;
constructee.faces.push(face1);
face2.normal.copy(normal);
face2.vertexNormals.push(normal.clone(), normal.clone(), normal.clone());
face2.materialIndex = materialIndex;
constructee.faces.push(face2);
if (false) {
console.log("materialIndex: ", materialIndex);
console.log("a: %d, vertex: x:%f, y:%f, z:%f", a, constructee.vertices[a][x], constructee.vertices[a][y], constructee.vertices[a][z]);
console.log("b: %d, vertex: x:%f, y:%f, z:%f", b, constructee.vertices[b][x], constructee.vertices[b][y], constructee.vertices[b][z]);
console.log("c: %d, vertex: x:%f, y:%f, z:%f", c, constructee.vertices[c][x], constructee.vertices[c][y], constructee.vertices[c][z]);
console.log("d: %d, vertex: x:%f, y:%f, z:%f", d, constructee.vertices[d][x], constructee.vertices[d][y], constructee.vertices[d][z]);
console.log("face1: a: (x:%f, y:%f, z:%f), b: (x:%f, y:%f, z:%f), d: (x:%f, y:%f, z:%f)",
face1.a.getComponent[0], face1.a.getComponent[1], face1.a.getComponent[2],
face1.b.getComponent[0], face1.b.getComponent[1], face1.b.getComponent[2],
face1.c.getComponent[0], face1.c.getComponent[1], face1.c.getComponent[2]);
console.log("face2: a: (u:%f, v:%f), c: (u:%f, v:%f), d: (u:%f, v:%f)",
constructee.vertices[b + offset][u], constructee.vertices[b + offset][v],
constructee.vertices[c + offset][u], constructee.vertices[c + offset][v],
constructee.vertices[d + offset][u], constructee.vertices[d + offset][v]);
console.log("uva: (u:%f, v:%f), uvb: (u:%f, v:%f) uvc: (u:%f, v:%f), uvd: (u:%f, v:%f)",
uva.getComponent(0), uva.getComponent(1),
uvb.getComponent(0), uvb.getComponent(1),
uvc.getComponent(0), uvc.getComponent(1),
uvd.getComponent(0), uvd.getComponent(1));
console.log(" ");
}
if (false) {
console.log("segUi: %d, segVi: %d, uDir: %d, vDir: %d", segUi, segVi, uDir, vDir);
console.log("segmentDist_u: %f, segmentDist_v: %f", segmentDist_u, segmentDist_v);
console.log(" vertex[ u ] = ( iu * segmentDist_u - uDist_half ) * uDir\n" +
" vertex[ v ] = ( iv * segmentDist_v - vDist_half ) * vDir\n" +
" vertex[ w ] = wDist_half");
console.log(" "); }
};
this.mergeVertices();
};
THREE.Box3Geometry.prototype = Object.create(THREE.Geometry.prototype);发布于 2014-08-26 18:36:12
Three.js有一些非常好的帮助函数:
THREE.BoxHelper( mesh )
THREE.FaceNormalsHelper( mesh )
THREE.VertexNormalsHelper( mesh )
THREE.WireframeHelper( mesh )举几个例子。
看起来您正在设置顶点法线,所以为什么不使用THREE.VertexNormalsHelper(mesh)来验证three.js是否在使用您所期望的呢?
注意:您的变量normal在代码中不可见。
https://stackoverflow.com/questions/25511911
复制相似问题