首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >three.js对我的正常人毫不尊重

three.js对我的正常人毫不尊重
EN

Stack Overflow用户
提问于 2014-08-26 17:38:12
回答 2查看 1.1K关注 0票数 0

我正在为非正交立方体做一个定制的three.js几何。它松散地基于three.js中现有的Box-几何学,但是它的顶点的绝对位置直接输入到它。

我对three.js有个问题,它似乎不尊重我传递给几何学面的法线。当我在将法线赋值给人脸之前对其进行console.log时,它们看起来很好:

代码语言:javascript
复制
normal: Object { x=0, y=0, z=-1, more...}
normal: Object { x=0, y=0, z=1, more...}

这些法线只适合直角立方体的上、下两面。然而,从这张截图中可以看到(如果我适当地倾斜了相机),第一个法线似乎已经应用于两个表面:

这是200x200x200立方体的两面,中心在猎户座,与所有轴正交。白线表示z轴.

下面是我的错误几何学。“四重集”数组包含六个数组,每个数组包含四个Vector3实例。每个内部数组都勾勒出立方体的一侧。

代码语言:javascript
复制
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);

这是我对几何的测试实例化:

代码语言:javascript
复制
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
);

这就是我被“启发”的盒子几何

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-03 19:04:01

我在自定义几何学问题,直面法姆多布问题的答案中找到了这个问题的答案。

总之,我们必须改变给人脸的顶点的顺序,以控制法线指向的方向。

因此,我的代码现在如下所示:

代码语言:javascript
复制
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);
票数 0
EN

Stack Overflow用户

发布于 2014-08-26 18:36:12

Three.js有一些非常好的帮助函数:

代码语言:javascript
复制
THREE.BoxHelper( mesh )
THREE.FaceNormalsHelper( mesh )
THREE.VertexNormalsHelper( mesh )
THREE.WireframeHelper( mesh )

举几个例子。

看起来您正在设置顶点法线,所以为什么不使用THREE.VertexNormalsHelper(mesh)来验证three.js是否在使用您所期望的呢?

注意:您的变量normal在代码中不可见。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25511911

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档