美文网首页
7 从高度图创建地图

7 从高度图创建地图

作者: skoll | 来源:发表于2021-12-04 20:31 被阅读0次

高度图

1 .高度图是一个图像文件,通常只有灰色,每个像素点保存点高度,越亮,越高
2 .http://www.tuxingis.com/resource/dem_12_download.html?trackingLinkId=0f4fbb5ac45749dd871a84bf6632f1df&source=baidu&plan=DEM%E6%95%B0%E6%8D%AE-12%E7%B1%B3&unit=DEM%E6%95%B0%E6%8D%AE&keyword=%E9%AB%98%E5%88%86%E8%BE%A8%E7%8E%87%E5%9C%B0%E5%BD%A2%E6%95%B0%E6%8D%AE&e_keywordid=164155483505&e_keywordid2=164155483505

呼和浩特市.jpeg

从这个网站上面扒的图,然后自己变色成了高度图,如果这个可以实现的话,那么就可以做出一个全国的地形了,配合无限地形,简直爽炸。
3 .还有就是全球的地图
4 .还有就是英雄联盟地图。感觉这种拿高度图做是一种趋势

第一次构建

1 .可以看到,根据高度图生成的东西并没有真的按照我们想要的大小来生成,而是出现了重复堆叠
2 .那这个生成的问题

1 .太生硬,生成的地形根本没有看到的好看,山的棱角不是很平滑,怎么怎么说呢,高度图只能生成很简单的地形,复杂的山,还是要单独做
2 .到处的尖角,完全看不出来是家乡的模样。他这个怎么才能给这些图
<!DOCTYPE html>
<!-- 添加小人,使用序列图 -->
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
    <title>Babylon - Getting Started</title>
    <!-- Link to the last version of BabylonJS -->
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <!-- Link to the last version of BabylonJS loaders to enable loading filetypes such as .gltf -->
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <!-- Link to pep.js to ensure pointer events work consistently in all browsers -->
    <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
    <!-- <script src="https://cdn.rawgit.com/BabylonJS/Extensions/master/DynamicTerrain/dist/babylon.dynamicTerrain.min.js"></script> -->
    <script src="./dy.js"></script>
    <script src="./noise.js"></script>
</head>
<style>
    html, body {
        overflow: hidden;
        width   : 100%;
        height  : 100%;
        margin  : 0;
        padding : 0;
    }

    #renderCanvas {
        width   : 100%;
        height  : 100%;
        touch-action: none;
    }
</style>
<body>
    <canvas id="renderCanvas" touch-action="none"></canvas>
    <script>
        const canvas = document.getElementById("renderCanvas");
        var engine = null;
        // 这里还不能用let,不然就爆炸,获取不到engine
        var scene = null;
        var sceneToRender = null;
        const createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: false}); };
        let createScene=async function(){
            // 关键函数都写在这个里面

                var scene = new BABYLON.Scene(engine)
                var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);    
                camera.attachControl(canvas, true);
                
                // var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, BABYLON.Vector3.Zero(), scene);
                // camera.setPosition(new BABYLON.Vector3(0.0, 10.0, 0.01));
                // camera.attachControl(canvas, true);

                var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0.0, 1.0, 0.0), scene);
                light.intensity = 0.75;
                light.specular = BABYLON.Color3.Black();

                // 这俩值是不是决定了地图的实际大小
                let terrainTexture=new BABYLON.Texture("http://images.wish3d.com/order/resources/alos12m/%E5%91%BC%E5%92%8C%E6%B5%A9%E7%89%B9%E5%B8%82.jpg?1638459571985",scene)

                let terrainMat=new BABYLON.StandardMaterial('tm',scene)
                terrainMat.diffuseTexture=terrainTexture
                terrainMat.diffuseTexture.UScale=1
                terrainMat.diffuseTexture.UScale=1


                let terrain

                let createTerrain=function(mapData,mapSubX,mapSubZ){
                    let params={
                        mapData:mapData,
                        mapSubZ:mapSubZ,
                        mapSubX:mapSubX,
                        terrainSub:100,
                        // 这个值决定了地图会分几份,如果这个值超过了地图的最大树,那么就会先复制出来
                    }

                    terrain=new BABYLON.DynamicTerrain('t',params,scene)
                    terrain.createUVMap()
                    terrain.mesh.material=terrainMat
                    terrain.update(true)
                }

                let mapWidth=3000
                let mapHeight=3000
                // 这俩决定了地图的大小
                let nbPoints=100
                // 每条边的点数决定了图的精细程度

                // 如果地图越小,但是每条边的点越多,那么地图就越精细,山的棱角越尖,需要我们自己去调合适的比例
                

                let hmOptions={
                    width:mapWidth,
                    // 世界地图大小
                    height:mapHeight,
                    subX:nbPoints,
                    // 地图宽度上的点:地图大小和点数的比越小,那么地图越粗糙,那么山峰越平缓
                    subZ:nbPoints,
                    // 地图高度上的点
                    onReady:createTerrain
                }
                let mapData=new Float32Array(nbPoints*nbPoints*3)
                BABYLON.DynamicTerrain.CreateMapFromHeightMapToRef('http://127.0.0.1:8080/dynamic/huhhot.jpeg',hmOptions,mapData,scene)
                

                scene.registerBeforeRender(()=>{
                        if(terrain){
                            camera.position.y=terrain.getHeightFromMap(camera.position.x,camera.position.z)+2
                        }   
                        // 让镜头始终在
                })
                

               
            

        
               

                return scene
        }

    window.initFunction=async function(){
        let asyncEngineCreation=async function(){
            try{
                return createDefaultEngine()
            }catch(e){
                return createDefaultEngine()
            }
        }

        window.engine=await asyncEngineCreation()
        if(!engine){
            throw('engine should not be null')
        }
        window.scene=createScene()
        
    }

    initFunction().then(()=>{
        scene.then((returnedScene)=>{
            sceneToRender=returnedScene
        })

        engine.runRenderLoop(function(){
            if(sceneToRender&&sceneToRender.activeCamera){
                sceneToRender.render()
            }
        })

    })

    window.addEventListener('resize',function(){
        engine.resize()
    })

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

第二次构建,拿官方demo的数据试试,地球高度图

1 .最后的效果出来也不是很清楚,这个大小比例还是要调整

<!DOCTYPE html>
<!-- 添加小人,使用序列图 -->
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
    <title>Babylon - Getting Started</title>
    <!-- Link to the last version of BabylonJS -->
    <script src="https://preview.babylonjs.com/babylon.js"></script>
    <!-- Link to the last version of BabylonJS loaders to enable loading filetypes such as .gltf -->
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <!-- Link to pep.js to ensure pointer events work consistently in all browsers -->
    <script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
    <!-- <script src="https://cdn.rawgit.com/BabylonJS/Extensions/master/DynamicTerrain/dist/babylon.dynamicTerrain.min.js"></script> -->
    <script src="./dy.js"></script>
    <script src="./noise.js"></script>
</head>
<style>
    html, body {
        overflow: hidden;
        width   : 100%;
        height  : 100%;
        margin  : 0;
        padding : 0;
    }

    #renderCanvas {
        width   : 100%;
        height  : 100%;
        touch-action: none;
    }
</style>
<body>
    <canvas id="renderCanvas" touch-action="none"></canvas>
    <script>
        const canvas = document.getElementById("renderCanvas");
        var engine = null;
        // 这里还不能用let,不然就爆炸,获取不到engine
        var scene = null;
        var sceneToRender = null;
        const createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: false}); };
        let createScene=async function(){
            // 关键函数都写在这个里面

                var scene = new BABYLON.Scene(engine)
                var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);    
                camera.attachControl(canvas, true);
                
                // var camera = new BABYLON.ArcRotateCamera("camera1",  0, 0, 0, BABYLON.Vector3.Zero(), scene);
                // camera.setPosition(new BABYLON.Vector3(0.0, 10.0, 0.01));
                // camera.attachControl(canvas, true);

                var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0.0, 1.0, 0.0), scene);
                light.intensity = 0.75;
                light.specular = BABYLON.Color3.Black();

                // 这俩值是不是决定了地图的实际大小
                let terrainTexture=new BABYLON.Texture("https://www.babylonjs-playground.com/textures/earth.jpg",scene)

                let terrainMat=new BABYLON.StandardMaterial('tm',scene)
                terrainMat.diffuseTexture=terrainTexture
                terrainMat.diffuseTexture.UScale=1
                terrainMat.diffuseTexture.UScale=1


                let terrain

                let createTerrain=function(mapData,mapSubX,mapSubZ){
                    let params={
                        mapData:mapData,
                        mapSubZ:mapSubZ,
                        mapSubX:mapSubX,
                        terrainSub:120,
                        // 这个值决定了地图会分几份,如果这个值超过了地图的最大树,那么就会先复制出来
                    }

                    terrain=new BABYLON.DynamicTerrain('t',params,scene)
                    terrain.createUVMap()
                    terrain.mesh.material=terrainMat
                    terrain.update(true)
                }

                let mapWidth=1000
                let mapHeight=1000
                // 这俩决定了地图的大小
                let nbPoints=500
                // 每条边的点数决定了图的精细程度

                // 如果地图越小,但是每条边的点越多,那么地图就越精细,山的棱角越尖,需要我们自己去调合适的比例
                

                let hmOptions={
                    width:mapWidth,
                    // 世界地图大小
                    height:mapHeight,
                    subX:nbPoints,
                    // 地图宽度上的点:地图大小和点数的比越小,那么地图越粗糙,那么山峰越平缓
                    subZ:nbPoints,
                    // 地图高度上的点
                    onReady:createTerrain
                }
                let mapData=new Float32Array(nbPoints*nbPoints*3)
                BABYLON.DynamicTerrain.CreateMapFromHeightMapToRef('https://www.babylonjs-playground.com/textures/worldHeightMap.jpg',hmOptions,mapData,scene)
                

                scene.registerBeforeRender(()=>{
                        if(terrain){
                            camera.position.y=terrain.getHeightFromMap(camera.position.x,camera.position.z)+12
                        }   
                        // 让镜头始终在
                })
                

               
            

        
               

                return scene
        }

    window.initFunction=async function(){
        let asyncEngineCreation=async function(){
            try{
                return createDefaultEngine()
            }catch(e){
                return createDefaultEngine()
            }
        }

        window.engine=await asyncEngineCreation()
        if(!engine){
            throw('engine should not be null')
        }
        window.scene=createScene()
        
    }

    initFunction().then(()=>{
        scene.then((returnedScene)=>{
            sceneToRender=returnedScene
        })

        engine.runRenderLoop(function(){
            if(sceneToRender&&sceneToRender.activeCamera){
                sceneToRender.render()
            }
        })

    })

    window.addEventListener('resize',function(){
        engine.resize()
    })

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

相关文章

网友评论

      本文标题:7 从高度图创建地图

      本文链接:https://www.haomeiwen.com/subject/jdouxrtx.html