35 - three.js 笔记 - 线段几何体材质

线段几何体材质,分为LineBasicMaterialLineDashedMaterial,线段上只有顶点没有面。

LineBasicMaterial:通过线段基础材质,可以设置线段的颜色、宽度和连接点。
LineDashedMaterial:虚线材质的基本属性跟基础线段材质一样,但是可以指定短划线的和间距空格的长度。

示例:01-LineMaterial.html

LineBasicMaterial 属性
名称 描述
color 指定线框的颜色默认为白色,如果指定vertexColors,这个属性会被忽略
linewidth 指定线框的宽度,默认为1,在WebGLRenderer不支持该属性
linecap 线框端点形状,属于2D画布lineCap属性,它被WebGL渲染器忽略
linejoin 线框节点外观,属于2D画布lineCap属性,它被WebGL渲染器忽略
LineDashedMaterial 属性

lineDashedMaterial除了与LineBasicMaterial有一样的属性外,还具有几个额外的属性。

名称 描述
dashSize 虚线的长度,默认为3
gapSize 中间缝隙的大小,默认为1
scale 虚线的缩放比例,默认为1,若这个值小于1**dashSize**和gapSize就会增大,小于1则变小

注意:虚线材质,需要计算线段之间的距离,所以需要添加这行代码 lines.computeLineDistances(),否则显示的是实线。

示例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LineBasicMaterial 和 LineDashedMaterial 线段几何材质</title>
    <style>
        body {
            margin: 0;
            overflow: hidden; /*溢出隐藏*/
        }
    </style>
    <script src="../../libs/build/three-r93.min.js"></script>
    <script src="../../libs/examples/js/controls/OrbitControls.js"></script>
    <script src="../../libs/examples/js/libs/dat.gui.min.js"></script>
    <script src="../../libs/examples/js/libs/stats.min.js"></script>
    <script src="../../libs/examples/js/Detector.js"></script>
</head>
<body>
<script>

    let stats = initStats();
    let scene, camera, renderer, lines, controls, guiControls;

    /* 场景 */
    function initScene() {

        scene = new THREE.Scene();

    }

    /* 相机 */
    function initCamera() {

        camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 5000);
        camera.position.set(0, 1000, 2000);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

    }

    /* 渲染器 */
    function initRenderer() {

        renderer = new THREE.WebGLRenderer({antialias: true});
        renderer.setSize(window.innerWidth, window.innerHeight);

        document.body.appendChild(renderer.domElement);

    }

    /* 灯光 */
    function initLight() {


    }

    /* 控制器 */
    function initControls() {

        controls = new THREE.OrbitControls(camera, renderer.domElement);
        // 添加惯性
        controls.enableDamping = true;
        // 最大偏移角度
        controls.maxPolarAngle = 0.49 * Math.PI;
        controls.enableRotate = false;

    }

    /* 调试插件 */
    let gui;

    function initGui() {

        guiControls = new function () {

            this.rotation = true;
            this.vertexColors = true;
            this.color = material.color.getStyle();
            this.opacity = material.opacity;
            this.transparent = material.transparent;
            this.lineMaterial = 'LineBasicMaterial';

        };

        gui = new dat.GUI();

        gui.add(guiControls, 'rotation').onChange(function (e) {

            step = e ? 0.005 : 0;

        });
        gui.add(guiControls, 'vertexColors').onChange(function (e) {

            material.vertexColors = e ? true : false;

            material.needsUpdate = true;

        });
        gui.addColor(guiControls, 'color').onChange(function (e) {

            material.color.setStyle(e);

            material.needsUpdate = true;

        });
        gui.add(guiControls, 'opacity', 0, 1).onChange(function (e) {

            material.opacity = e;

        });
        gui.add(guiControls, 'transparent').onChange(function (e) {

            material.transparent = e;

        });
        gui.add(guiControls, 'lineMaterial', ['LineBasicMaterial', 'LineDashedMaterial']).onChange(function (e) {

            switch (e) {

                case 'LineBasicMaterial':

                    material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors});
                    break;

                case  'LineDashedMaterial':

                    material = new THREE.LineDashedMaterial({vertexColors: THREE.VertexColors, gapSize: 2});
                    break;

            }

            lines.material = material;

        });


    }

    /* 场景中的内容 */
    let material;

    function initContent() {

        // 分段数
        let segments = 1000;

        let geometry = new THREE.BufferGeometry();
        material = new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors});

        let positions = [];
        let colors = [];

        let r = 1000;

        for (let i = 0; i < segments; i++) {

            let x = Math.random() * r - r / 2;
            let y = Math.random() * r - r / 2;
            let z = Math.random() * r - r / 2;

            // 位置
            positions.push(x, y, z,);

            // 颜色
            colors.push((x / r) + 0.5);
            colors.push((y / r) + 0.5);
            colors.push((z / r) + 0.5);

        }
        // 次数传递的 position 和 color 是固定的
        geometry.addAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
        geometry.addAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

        geometry.computeBoundingSphere();

        lines = new THREE.Line(geometry, material);
        lines.computeLineDistances();

        scene.add(lines);

    }

    /* 性能插件 */
    function initStats() {

        let stats = new Stats();

        stats.domElement.style.position = 'absolute';
        stats.domElement.style.left = '0px';
        stats.domElement.style.top = '0px';

        document.body.appendChild(stats.domElement);

        return stats;
    }

    /* 更新 */
    let step = 0.005;

    function update() {

        stats.update();
        controls.update();

        lines.rotation.y -= step;
        lines.rotation.x -= step;

    }

    /* 初始化 */
    function init() {

        // 兼容性判断,若不兼容会提示信息
        if (!Detector.webgl) Detector.addGetWebGLMessage();

        initScene();
        initCamera();
        initRenderer();
        initLight();
        initControls();
        initContent();
        initGui();

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

    }

    /* 窗口变动触发的方法 */
    function onWindowResize() {

        // 重新设置相机的宽高比
        camera.aspect = window.innerWidth / window.innerHeight;

        // 更新相机投影矩阵
        camera.updateProjectionMatrix();

        // 更新渲染器大小
        renderer.setSize(window.innerWidth, window.innerHeight);

    }

    /* 循环渲染 */
    function animate() {

        requestAnimationFrame(animate);
        renderer.render(scene, camera);
        update();
    }

    /* 页面绘制完后加载 */
    window.onload = function () {

        init();
        animate();

    };

</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/ithanmang/article/details/81505535