【问题标题】:BufferGeometry not visibleBufferGeometry 不可见
【发布时间】:2015-01-30 23:46:53
【问题描述】:

我使用 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;
}

【问题讨论】:

  • 你做的比你想象的要多:) 试试renderer.setClearColor( 0x888888, 1 );
  • 哇,这就像我不知道我的左手和右手(系统)!如果您想发布答案,我会接受,否则只需在这里发表另一条评论,我会写下我是如何搞砸的。
  • 其实我还是有点迷茫。我知道我应该使用 RHS 时使用的是 LHS。但是为什么法线被忽略了?显式定义不应该覆盖隐式定义吗?我需要法线指向不同方向的原因有很多,所以让惯用手超过我的预期有点令人不安。
  • 我认为您正在得出结论......但是,从小提琴 #60+ 的外观来看,您似乎明白了。顺便提一句。你不需要每次运行它时都更新小提琴......
  • 是的,我需要更好地使用 jsfiddle 工具...做了更多的修补,我想我明白了。我早期的 3D 体验是使用 Blender。如果一个面朝一个非预期的方向绘制,它通常是一个倒置的 face 法线,并且翻转法线会翻转该面。实际上,它可能是翻转法线并更改面部的顶点顺序。在这种情况下,我更改的是 vertex 法线,而不是面部,这导致 GL 无法像我预期的那样处理光线。简而言之:顶点/索引顺序始终定义面,法线仅用于照明。

标签: javascript three.js buffer-geometry


【解决方案1】:

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

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

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-04
    • 2017-09-26
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多