0

我使用 BufferGeometry 已经有一段时间了,我认为我对它非常熟悉。现在,我正在尝试创建一个简单的方形平面,但它什么也没做——据我所知,没有可见的平面,没有错误,也没有明显的问题。我在这里看到过其他类似的帖子,但没有一个解决方案成功。

当我检查场景时,网格就在那里,它有合适的材质,而且它的几何形状似乎设置正确。但我得到的只是一个黑色的视口。我必须错过一个痛苦的明显/简单的步骤,但现在它正在逃避我。我究竟做错了什么?

小提琴+代码:http: //jsfiddle.net/TheJim01/kafybhge/34/

// BufferGeometry Tester

var hostDiv, scene, renderer, camera, root, controls, light;

var WIDTH = 500;//window.innerWidth,
    HEIGHT = 500;//window.innerHeight,
    FOV = 35,
    NEAR = 1,
    FAR = 1000;

function createBufferGeometryMesh(){
    var geo = new THREE.BufferGeometry();

    var vertices = 
        [
            -10.,  10., 0., // 0 - top left
             10.,  10., 0., // 1 - top right
             10., -10., 0., // 2 - bottom right
            -10., -10., 0.  // 3 - bottom left
        ],
    normals =
        [
            0., 0., 1.,
            0., 0., 1.,
            0., 0., 1.,
            0., 0., 1.
        ],
    indices = [ 0, 1, 2, 0, 2, 3 ];

    geo.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( vertices ), 3 ) );
    geo.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( normals ), 3 ) );
    geo.addAttribute( 'index', new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );

    var mat = new THREE.MeshPhongMaterial( {
                    color: 0xffffff,
                    ambient: 0xffffff,
                    specular: 0xffffff,
                    shininess: 50,
                    side: THREE.DoubleSide
                } );

    var msh = new THREE.Mesh(geo, mat);

    return msh;
}

function init() {
    hostDiv = document.createElement('div');
    document.body.appendChild(hostDiv);

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(WIDTH, HEIGHT);
    hostDiv.appendChild(renderer.domElement);

    camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
    camera.position.z = 50;

    controls = new THREE.TrackballControls(camera, renderer.domElement);

    light = new THREE.PointLight(0xffffff, 1, 1000);
    light.position.copy(camera.position);

    scene = new THREE.Scene();
    scene.add(camera);
    scene.add(light);

    var square = createBufferGeometryMesh();
    scene.add(square);

    animate();
}

function render() {
    renderer.render(scene, camera);
}

function animate() {
    light.position.copy(camera.position);    

    requestAnimationFrame(animate);
    render();
    controls.update();
}

init();

只是为了表明我对 BufferGeometry 并不陌生,这是我以前做过的事情,如果我将它插入到我的代码中代替createBufferGeometryMesh()上面的内容,它就会起作用。我已经尝试定义像下面这样的缓冲区(甚至明确地),但它没有改变任何东西。

function colorCube(scale){
    scale = scale || 1;
    var geo = new THREE.BufferGeometry();

    var positions = new Float32Array( 72 );
    var normals = new Float32Array( 72 );
    var colors = new Float32Array( 72 );
    var indices = new Uint16Array( 36 );

    var face = 0, idx = 0, vert = 0;
    var x = 0, r = 0, y = 1, g = 1, z = 2, b = 2;

    // front face (RED)
    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = 1.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 0.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    // back face (BLUE)
    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
    colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
    colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
    colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 0.; normals[vert + z] = -1.;
    colors[vert + r] = 0.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    // right face (GREEN)
    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    // left face (MAGENTA)
    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = -1.; normals[vert + y] = 0.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 0.; colors[vert + b] = 1.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    // top face (CYAN)
    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = 0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = 1.; normals[vert + z] = 0.;
    colors[vert + r] = 0.; colors[vert + g] = 1.; colors[vert + b] = 1.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    // bottom face (YELLOW)
    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = 0.5;
    normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = -0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    positions[vert + x] = 0.5; positions[vert + y] = -0.5; positions[vert + z] = -0.5;
    normals[vert + x] = 0.; normals[vert + y] = -1.; normals[vert + z] = 0.;
    colors[vert + r] = 1.; colors[vert + g] = 1.; colors[vert + b] = 0.;
    vert += 3;

    indices[idx + 0] = (face * 4) + 0; indices[idx + 1] = (face * 4) + 1; indices[idx + 2] = (face * 4) + 2;
    indices[idx + 3] = (face * 4) + 0; indices[idx + 4] = (face * 4) + 2; indices[idx + 5] = (face * 4) + 3;
    idx += 6;
    ++face;

    geo.addAttribute( 'index', new THREE.BufferAttribute( indices, 1 ) );
    geo.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
    geo.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
    geo.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );

    var mat = new THREE.MeshPhongMaterial( {
                    color: 0xffffff,
                    ambient: 0xffffff,
                    specular: 0xffffff,
                    shininess: 50,
                    side: THREE.DoubleSide,
                    vertexColors: THREE.VertexColors
                } );    

    var msh = new THREE.Mesh(geo, mat);
    msh.scale.multiplyScalar(scale);

    return msh;
}
4

1 回答 1

2

由于 WestLangley 是谦虚的,这就是我上面的代码中出了什么问题。

我的主要心理障碍是我对法线在绘制人脸方面的功能存在误解。我开始认为顶点法线可以定义面部的方向,但这根本不是真的。顶点法线用于计算表面上的光照,与定义面方向无关。它是定义面方向(面法线)的顶点顺序。补充一下,当three.js 使用右手系统时,我使用的是左手系统。

在我的原始代码中,我有:

indices = [ 0, 1, 2, 0, 2, 3 ];

要以正确的方向绘制面,应该是:

indices = [ 0, 2, 1, 0, 3, 2 ];

差异是微妙的,但在我的示例中,它们表示分别指向 -Z 和 +Z 方向的面法线之间的差异。面孔面对错误的接受光的方式。明确的法线甚至没有发挥作用,因为表面无论如何都没有反射任何光线。使用右手系统的索引固定了面部方向。

面对面部方向问题,我做了一个练习来巩固我的理解,我将顶点法线翻转到(再次)指向与面部法线相反的方向。正如所料(这一次),广场变黑了。即使面部指向正确的方向,法线本质上还是告诉 GL 将光线反射到物体上,将其变成某种黑洞。

我的总结是:面方向(面法线)是根据构成面的顶点的顺序计算的,并使用 RHS。顶点法线影响面表面的光照,与定义面方向无关。

于 2014-12-03T17:35:44.200 回答