代码之家  ›  专栏  ›  技术社区  ›  TheJim01

第三组,多种材料

  •  0
  • TheJim01  · 技术社区  · 8 年前

    作为原型化一些调试器对象和方法的一部分,我创建了一个简单的立方体,每一面都有不同的颜色。我决定使用绘制组和三种材质,而不是创建多个网格。不幸的是,它只起了一半作用,我不明白为什么。

    工作的是前两条边(4个三角形)。其他方面都不起作用。其他面都看不见。我添加了调试代码来绘制(基于索引的)顶点法线、(基于索引、手动计算的)面法线和线框(THREE.WireframeHelper)。

    如果我将第二组的计数增加到9,则不会发生任何事情。如果我更改组以引用前8个顶点中的不同开始/计数值,则这些更改将按预期工作。在第8个顶点以上执行任何操作都没有效果。

    我还检查了drawRange是否设置为从0到Infinity绘制。我还排除了数据中的输入错误,因为否则法线和线框将无法工作。我还缺什么吗?谢谢

    (我在r76中发现了这个问题。在编写本文时,下面的代码引用了r79。)

    jsfiddle(小提琴): http://jsfiddle.net/TheJim01/gumftkm4/

    HTML格式:

    <script src="http://threejs.org/build/three.js"></script>
    <script src="http://threejs.org/examples/js/controls/TrackballControls.js"></script>
    <script src="http://threejs.org/examples/js/libs/stats.min.js"></script>
    <div id="host"></div>
    
    <script>
    // INITIALIZE
    var WIDTH = window.innerWidth,
        HEIGHT = window.innerHeight,
        FOV = 35,
        NEAR = 1,
        FAR = 1000;
    
    var renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(WIDTH, HEIGHT);
    document.getElementById('host').appendChild(renderer.domElement);
    
    var stats= new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.top = '0';
    document.body.appendChild(stats.domElement);
    
    
    var camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
    camera.position.z = 250;
    
    var trackballControl = new THREE.TrackballControls(camera, renderer.domElement);
    trackballControl.rotateSpeed = 5.0; // need to speed it up a little
    
    var scene = new THREE.Scene();
    
    var light = new THREE.PointLight(0xffffff, 1, Infinity);
    light.position.copy(camera.position);
    
    scene.add(light);
    
    function draw(){
        light.position.copy(camera.position);
        renderer.render(scene, camera);
      stats.update();
    }
    trackballControl.addEventListener('change', draw);
    
    function navStartHandler(e) {
      renderer.domElement.addEventListener('mousemove', navMoveHandler);
      renderer.domElement.addEventListener('mouseup', navEndHandler);
    }
    function navMoveHandler(e) {
      trackballControl.update();
    }
    function navEndHandler(e) {
      renderer.domElement.removeEventListener('mousemove', navMoveHandler);
      renderer.domElement.removeEventListener('mouseup', navEndHandler);
    }
    
    renderer.domElement.addEventListener('mousedown', navStartHandler);
    renderer.domElement.addEventListener('mousewheel', navMoveHandler);
    </script>
    

    CSS(客服代表):

    html *{
        padding: 0;
        margin: 0;
        width: 100%;
        overflow: hidden;
    }
    
    #host {
        width: 100%;
        height: 100%;
    }
    

    JavaScript语言:

    // New Color Cube
    (function () {
    
        var pos = new Float32Array([
            // front
            -1, 1, 1,
            -1, -1, 1,
            1, 1, 1,
            1, -1, 1,
            // right
            1, 1, 1,
            1, -1, 1,
            1, 1, -1,
            1, -1, -1,
            // back
            1, 1, -1,
            1, -1, -1,
            -1, 1, -1,
            -1, -1, -1,
            // left
            -1, 1, -1,
            -1, -1, -1,
            -1, 1, 1,
            -1, -1, 1,
            // top
            -1, 1, -1,
            -1, 1, 1,
            1, 1, -1,
            1, 1, 1,
            // bottom
            -1, -1, 1,
            -1, -1, -1,
            1, -1, 1,
            1, -1, -1
        ]),
        nor = new Float32Array([
            // front
            0, 0, 1,
            0, 0, 1,
            0, 0, 1,
            0, 0, 1,
            // right
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            1, 0, 0,
            // back
            0, 0, -1,
            0, 0, -1,
            0, 0, -1,
            0, 0, -1,
            // left
            -1, 0, 0,
            -1, 0, 0,
            -1, 0, 0,
            -1, 0, 0,
            // top
            0, 1, 0,
            0, 1, 0,
            0, 1, 0,
            0, 1, 0,
            // bottom
            0, -1, 0,
            0, -1, 0,
            0, -1, 0,
            0, -1, 0
        ]),
        idx = new Uint32Array([
            // front
            0, 1, 2,
            3, 2, 1,
            // right
            4, 5, 6,
            7, 6, 5,
            // back
            8, 9, 10,
            11, 10, 9,
            // left
            12, 13, 14,
            15, 14, 13,
            // top
            16, 17, 18,
            19, 18, 17,
            // bottom
            20, 21, 22,
            23, 22, 21
        ]);
    
        var sideColors = new THREE.MultiMaterial([
            new THREE.MeshLambertMaterial({ color: 'red' }), // front
            new THREE.MeshLambertMaterial({ color: 'green' }), // right
            new THREE.MeshLambertMaterial({ color: 'orange' }), // back
            new THREE.MeshLambertMaterial({ color: 'blue' }), // left
            new THREE.MeshLambertMaterial({ color: 'white' }), // top
            new THREE.MeshLambertMaterial({ color: 'yellow' }) // bottom
        ]);
    
        var cubeGeometry = new THREE.BufferGeometry();
        cubeGeometry.addAttribute("position", new THREE.BufferAttribute(pos, 3));
        cubeGeometry.addAttribute("normal", new THREE.BufferAttribute(nor, 3));
        cubeGeometry.setIndex(new THREE.BufferAttribute(idx, 3));
        cubeGeometry.clearGroups();
        cubeGeometry.addGroup(0, 6, 0);
        cubeGeometry.addGroup(6, 6, 1);
        cubeGeometry.addGroup(12, 6, 2);
        cubeGeometry.addGroup(18, 6, 3);
        cubeGeometry.addGroup(24, 6, 4);
        cubeGeometry.addGroup(30, 6, 5);
    
        THREE.ColorCube = function (scaleX, scaleY, scaleZ) {
            THREE.Mesh.call(this, cubeGeometry, sideColors);
            var scaler = new THREE.Matrix4().makeScale(scaleX, scaleY, scaleZ);
            this.applyMatrix(scaler);
        };
        THREE.ColorCube.prototype = Object.create(THREE.Mesh.prototype);
        THREE.ColorCube.prototype.constructor = THREE.ColorCube;
    
        THREE.ColorCube.prototype.clearVertexNormals = function () {
            if (this.vNormals === undefined) {
                this.vNormals = [];
            }
            for (var i = 0, len = this.vNormals.length; i < len; ++i) {
                this.parent.remove(this.vNormals[i]);
            }
            this.vNormals.length = 0;
        }
        THREE.ColorCube.prototype.drawVertexNormals = function (scale, color) {
            this.clearVertexNormals();
            scale = (scale === undefined) ? 1 : scale;
            color = (color === undefined) ? 0xff : color;
            var origin = new THREE.Vector3(),
                normalArrow = null,
                vert = null,
                norm = null,
                index = null,
                vertexArray = this.geometry.attributes.position.array,
                normalArray = this.geometry.attributes.normal.array,
                indexArray = this.geometry.index.array;
    
            for (var i = 0, len = indexArray.length; i < len; ++i) {
                index = indexArray[i];
                vert = new THREE.Vector3(...vertexArray.slice((index * 3), (index * 3) + 3)).applyMatrix4(this.matrix);
                norm = new THREE.Vector3(...normalArray.slice((index * 3), (index * 3) + 3));
    
                normalArrow = new THREE.ArrowHelper(
                    norm,
                    origin,
                    1 * scale,
                    color,
                    0.2 * scale,
                    0.1 * scale
                );
    
                normalArrow.position.copy(vert);
    
                this.vNormals.push(normalArrow);
                this.parent.add(normalArrow);
            }
        };
    
        THREE.ColorCube.prototype.clearFaceNormals = function () {
            if (this.fNormals === undefined) {
                this.fNormals = [];
            }
            for (var i = 0, len = this.fNormals.length; i < len; ++i) {
                this.parent.remove(this.fNormals[i]);
            }
            this.fNormals.length = 0;
        }
        THREE.ColorCube.prototype.drawFaceNormals = function (scale, color) {
            this.clearFaceNormals();
            scale = (scale === undefined) ? 1 : scale;
            color = (color === undefined) ? 0xffaa00 : color;
            var origin = new THREE.Vector3(),
                normalArrow = null,
                vertices = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()],
                normals = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()],
                indices = [0, 0, 0],
                centroid = new THREE.Vector3(),
                faceNormal = new THREE.Vector3(),
                vertexArray = this.geometry.attributes.position.array,
                normalArray = this.geometry.attributes.normal.array,
                indexArray = this.geometry.index.array;
    
            for (var i = 0, len = indexArray.length; i < len; i += 3) {
                indices = indexArray.slice(i, i + 3);
    
                vertices[0].set(...vertexArray.slice((indices[0] * 3), (indices[0] * 3) + 3)).applyMatrix4(this.matrix);
                vertices[1].set(...vertexArray.slice((indices[1] * 3), (indices[1] * 3) + 3)).applyMatrix4(this.matrix);
                vertices[2].set(...vertexArray.slice((indices[2] * 3), (indices[2] * 3) + 3)).applyMatrix4(this.matrix);
    
                normals[0].set(...normalArray.slice((indices[0] * 3), (indices[0] * 3) + 3));
                normals[1].set(...normalArray.slice((indices[1] * 3), (indices[1] * 3) + 3));
                normals[2].set(...normalArray.slice((indices[2] * 3), (indices[2] * 3) + 3));
    
                centroid.set(
                    (vertices[0].x + vertices[1].x + vertices[2].x) / 3,
                    (vertices[0].y + vertices[1].y + vertices[2].y) / 3,
                    (vertices[0].z + vertices[1].z + vertices[2].z) / 3
                );
    
                faceNormal.set(
                    (normals[0].x + normals[1].x + normals[2].x) / 3,
                    (normals[0].y + normals[1].y + normals[2].y) / 3,
                    (normals[0].z + normals[1].z + normals[2].z) / 3
                );
                faceNormal.normalize();
    
                normalArrow = new THREE.ArrowHelper(
                    faceNormal,
                    origin,
                    1 * scale,
                    color,
                    0.2 * scale,
                    0.1 * scale
                );
    
                normalArrow.position.copy(centroid);
    
                this.fNormals.push(normalArrow);
                this.parent.add(normalArrow);
            }
        };
    
        THREE.ColorCube.prototype.clearAllNormals = function () {
            THREE.ColorCube.prototype.clearVertexNormals();
            THREE.ColorCube.prototype.clearFaceNormals();
        }
    
        THREE.ColorCube.prototype.drawWireframe = function (color) {
            if (this.wireframe === undefined) {
                color = (color === undefined) ? 0 : color;
                this.wireframe = new THREE.WireframeHelper(this, color);
                this.parent.add(this.wireframe);
            }
        }
    
        THREE.ColorCube.prototype.clearWireframe = function () {
            if (this.wireframe) {
                this.parent.remove(this.wireframe);
                delete this.wireframe;
            }
        }
    
    })();
    
    var cc = new THREE.ColorCube(25, 25, 25);
    scene.add(cc);
    
    cc.drawVertexNormals(25);
    cc.drawFaceNormals(25);
    cc.drawWireframe(0xffffff);
    draw();
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Hasan    8 年前

    您设置的索引错误。你有 每个顶点1个索引

    如果你改变了

    cubeGeometry.setIndex(new THREE.BufferAttribute(idx, 3));
    

    cubeGeometry.setIndex(new THREE.BufferAttribute(idx, 1));
    

    你的问题解决了。

    这里是工作 jsfiddle