智慧城市炫酷效果、threejs绘制道路、TubeGeometry实现道路流光效果

一、先看看效果

在这里插入图片描述

二、实现方法:

实现思路: 使用TubeGeometry创建管道, 给管道设置纹理贴图材质;在循环渲染中修改纹理图片的位置,模拟出流动效果

1、创建材质,使用纹理贴图

// 创建材质 使用贴图
let loader = new THREE.TextureLoader();
let texture = loader.load('./img/bg.png');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //每个都重复
texture.repeat.set(1, 1)
texture.needsUpdate = true

const material = new THREE.MeshPhongMaterial({ 
    transparent: true,
    side: THREE.DoubleSide,
    map: texture
});

2、使用TubeGeometry创建管道, 给管道设置纹理贴图材质

 // 四给点坐标
const pointArr = [
    220, 0, -220,
    220, 0, 220,
    -220, 0, 100,
    -220, 0, -220,
];
let points = [];
for (let i=0; i<pointArr.length; i+=3) {
    points.push(new THREE.Vector3(
        pointArr[i],
        pointArr[i + 1],
        pointArr[i + 2]
    ));
}
/**
 * 创建一个管道
 */
const curve = new THREE.CatmullRomCurve3( points, true/*是否闭合*/,'catmullrom',0.000000001 );
const geometry = new THREE.TubeGeometry( curve, 100, 3, 50, false);
const line = new THREE.Mesh(geometry, material);
scene.add(line);

3、在循环渲染中修改纹理图片的位置,模拟出流动效果

function render () {
   // 修改纹理图片的位置,模拟出流动效果
   if(texture) texture.offset.x -= 0.02
   requestAnimationFrame(render);
   renderer.render(scene, camera);
}

三、实例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TubeGeometry实现道路流光效果</title>
    <style>
        body {
            height: 100vh;
            overflow: hidden;
        }
    </style>
    
    <script src="./lib/three.js"></script>
    <script src="./lib/OrbitControls.js"></script>
</head>
<body>
<script>
    let scene, camera, renderer, controls, mixer, tubeCurve, AgvCar;
    let width = window.innerWidth;
    let height = window.innerHeight

    function init () {
        // 场景
        scene = new THREE.Scene();

        // 环境光
        let light = new THREE.AmbientLight(0xadadad); // soft white light
        scene.add(light);

        // 平行光源
        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(1000, 1000, 0);
        scene.add(directionalLight); 

        // 相机
        camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000)
        camera.position.set(400, 520, 760)
        scene.add(camera)

        // 渲染器
        renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height)
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
        renderer.setClearColor(new THREE.Color('#32373E'), 1);
        document.body.appendChild(renderer.domElement);


        
        // 创建材质 使用贴图
        let loader = new THREE.TextureLoader();
        let texture = loader.load('./img/bg.png');
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping; //每个都重复
        texture.repeat.set(1, 1)
        texture.needsUpdate = true

        const material = new THREE.MeshPhongMaterial({ 
            transparent: true,
            side: THREE.DoubleSide,
            map: texture
        });

        // 四给点坐标
        const pointArr = [
            220, 0, -220,
            220, 0, 220,
            -220, 0, 100,
            -220, 0, -220,
        ];
        let points = [];
        for (let i=0; i<pointArr.length; i+=3) {
            points.push(new THREE.Vector3(
                pointArr[i],
                pointArr[i + 1],
                pointArr[i + 2]
            ));
        }
        /**
         * 创建一个管道
         */
        const curve = new THREE.CatmullRomCurve3( points, true/*是否闭合*/,'catmullrom',0.000000001 );
        const geometry = new THREE.TubeGeometry( curve, 100, 3, 50, false);
        const line = new THREE.Mesh(geometry, material);
        scene.add(line);


        render();
        function render () {
            // 修改纹理图片的位置,模拟出流动效果
            if(texture) texture.offset.x -= 0.02
            requestAnimationFrame(render);
            renderer.render(scene, camera);
        }
        controls = new THREE.OrbitControls(camera, renderer.domElement);
    }
    window.onload = init
</script>
    
</body>
</html>

版权声明:本文为weixin_40856652原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。