如何将WebGL实例应用于Three.js线框示例

时间:2018-05-18 13:32:00

标签: three.js webgl

注意:这个问题是previous question的澄清/简化,有望使许多Three.js / WebGL程序员开发性能优化技术。

1 个答案:

答案 0 :(得分:0)

有关实例化的codepen的简化版本,请参阅此wireframe example;为简单起见,删除了原始示例中的动画。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Adopted from three.js webgl - materials - wireframe</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                margin: 0px;
                background-color: #000000;
                overflow: hidden;
            }
        </style>
    </head>
    <body>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"></script> 

        <script type="x-shader/x-vertex" id="vertexShader"> 

            attribute vec3 offset;

            void main() {

                vec3 newPosition = position + offset;               
                gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); 
            }
        </script>

        <script type="x-shader/x-fragment" id="fragmentShader">


            void main() {                           
                gl_FragColor.rgb = vec3(1.0);               
                gl_FragColor.a = 1.0;   
            }
        </script>

        <script>

            var camera, scene, renderer;

            init();
            renderer.render( scene, camera );

            function init() {

                var  material, mesh;
                camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
                camera.position.z = 700;
                scene = new THREE.Scene();

                var instances = 3;
                var size = 100;
                var spacing = 50;
                var offsets = [];

                var geometry = new THREE.InstancedBufferGeometry().copy(new THREE.BoxBufferGeometry( size, size,size ))

                for (var i = 0; i < instances; i++) {   
                offsets = offsets.concat( fnGetOffsets( geometry, (-1 *(size + spacing)) + (i * (size + spacing)) ) );  
                }

                geometry.addAttribute( 'offset', new THREE.InstancedBufferAttribute(new Float32Array( offsets )  , 3 ) );                       

                var material = new THREE.ShaderMaterial( {
                        uniforms: {},     
                        wireframe: true,                        
                        vertexShader: document.getElementById( 'vertexShader' ).textContent,
                        fragmentShader: document.getElementById( 'fragmentShader' ).textContent

                    } );
                material.extensions.derivatives = true; 

                var mesh = new THREE.Mesh( geometry, material );
                scene.add( mesh );


                // renderer

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild( renderer.domElement );

                // events

                window.addEventListener( 'resize', onWindowResize, false );

                function fnGetOffsets( geometry,offsetX ) {

                    var offset = new THREE.Vector3( offsetX, 0, 0 );
                    var position = geometry.attributes.position;

                    var offsets = [];

                    for ( var i = 0; i < position.count; i ++ ) {
                        offsets.push(offsetX,0,0)
                    }

                    return offsets;

                } //fnGetOffsets                


            } //init




            function onWindowResize() {

                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();

                renderer.setSize( window.innerWidth, window.innerHeight );

            }


        </script>

    </body>
</html>