Question

How can I draw simple square using BufferGeometry? For example BufferGeometry draws 120000 triangles and I want to knock it down to two that form a simple square.

<html>
<head>
    <title>test app</title>
    <style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
    <script src="three.min.js"></script>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        //var geometry = new THREE.CubeGeometry(1,1,1);
        var triangles = 2;

        var geometry = new THREE.BufferGeometry();
        geometry.attributes = {
            index: {
                itemSize: 1,
                array: new Uint16Array( triangles * 3 ),
                numItems: triangles * 3
            },
            position: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            },
            normal: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            },
            color: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            }
        }

        var color = new THREE.Color();

        var indices = geometry.attributes.index.array;
        var positions = geometry.attributes.position.array;
        var normals = geometry.attributes.normal.array; //not setting normals - is it relevant if there is no light defined?
        var colors = geometry.attributes.color.array;

        for ( var i = 0; i < indices.length; i ++ ) {

                indices[ i ] = i % ( 3 * 1 ); // How to set indices????

        }

        for ( var i = 0; i < positions.length; i += 9 ) {

            //I know these will make two triangles at same position, but i want to see them appear first..
            positions[ i ]     = 0;
            positions[ i + 1 ] = 0;
            positions[ i + 2 ] = 0;

            positions[ i + 3 ] = 0;
            positions[ i + 4 ] = 1;
            positions[ i + 5 ] = 0;

            positions[ i + 6 ] = 1;
            positions[ i + 7 ] = 0;
            positions[ i + 8 ] = 0;

            color.setRGB( 55, 202, 55 );

            colors[ i ]     = color.r;
            colors[ i + 1 ] = color.g;
            colors[ i + 2 ] = color.b;

            colors[ i + 3 ] = color.r;
            colors[ i + 4 ] = color.g;
            colors[ i + 5 ] = color.b;

            colors[ i + 6 ] = color.r;
            colors[ i + 7 ] = color.g;
            colors[ i + 8 ] = color.b;
        }           

        var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
        var square = new THREE.Mesh(geometry, material);
        scene.add(square);

        camera.position.z = -5;

        var render = function () {
            requestAnimationFrame(render);

            square.rotation.x += 0.1;
            square.rotation.y += 0.1;

            renderer.render(scene, camera);
        };

        render();
    </script>
</body>

Was it helpful?

Solution 2

Here are the solution for your problems: Since your camera near and far view is between 0.1 and 1000

var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

Then your vertices z position must be in between that range. Therefore, please change your code from

positions[ i + 2 ] = 0; 

to

positions[ i + 2 ] = 1;

Also, your code seem to be missing these parts:

geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 3 ) );
geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );

for the full fixed code, please refer it here: http://learn-daily.com/three-js-drawing-flying-triangle-using-buffergeometry/

OTHER TIPS

In the newest three js version you cannot set index as how @calvin-sydney wrote in his answer. You will have to use the setIndex method from the THREE.BufferGeometry.

geometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));
geometry.addAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3));

geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top