# Main_Development_Project **Repository Path**: hactory/Main_Development_Project ## Basic Information - **Project Name**: Main_Development_Project - **Description**: 3D低多边形程序化生成项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-07-25 - **Last Updated**: 2026-04-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 🌈🌈Main_Development_Project🌍🌍 ## 🚩🚩项目进度 1、采用2D噪声生成高度图 ![img](https://gitee.com/hactory/image_cache/raw/master/%E5%99%AA%E9%9F%B3%E5%9C%B0%E5%9B%BE.png) 2、将高度图映射为3D模型 ![img](https://gitee.com/hactory/image_cache/raw/master/3Dmesh%E5%9C%B0%E5%BD%A2%E5%9B%BE.png) 改进地图生成尝试使用优化技术 1、携程/线程 2、空气墙 ## 🍳🍳目前正在解决的问题: 1、地图仍不完善,需要改进,例如无法实现高山,地图看起来太过于平滑,使其看起来不真实 2、需要在模型的表面添加更多细节,例如添加草木、矿物,非常的单调,并且只有一种材质需要改进,需要参考相关游戏开发的算法。 ​ 2.1.如星界边境、泰拉瑞亚的在连续的方块中嵌入其他方块。即方块混合。 ​ 2.2.以及在深岩银河中的沙地地形中材质问题。在不同法线上可以呈现不同的纹理,在之前的测试中纹理是单色的,而深岩银河中的表面可以呈现出具有纹理的效果。 3、需要跑通核心玩法迭代的流程 基于一个固定的种族(人类/机器人) 降落行星 -> 采集资源 -> 建造小型基地 -> 对抗环境危害/野生生物 -> 解锁科技 -> 飞往下一个行星(到花园星球上跑通第一个核心玩法流程) 关于预先生成 // 根据一个视距来每帧显示chunk数据的做法,当视距比较长或者移动速度比较快的时候 // 会进行大量的计算,然而大量的chunk显示又牵扯到GPU的计算,导致了画面的卡顿 // 要解决这个问题,必须取消掉顶点数据的实时计算,否则卡顿会几乎一直存在 // 即使用数据预先计算的方法。 // * 高度图 (无人深空) // * 使用预先加载的数据进行显示 ## 🔮🔮未来计划 网格统一化 AI寻路:动态寻路、A * pathfinding技术、unity插件 剧本 电路系统 光照:动态光照 农场 物品目录(ID、名称等),可以参考星界边境的mod模式,不能使用excel,因为有版权问题 GameDesigner?它是对于Unityengine的框架,然而对其过于深入的研究,后面也很可能用不上。因此在研究的同时还应该考虑向godot或unreal engine(更加重要,但也需要花费更多的时间/分割一些时间)转型。晚痛不如早痛。 # 对于当前开发的说明 # 一、地表逻辑生成 ## 1、表面的实体块生成 关于表面的实体块生成,也就是,基本物体(石头、泥土)、矿物等的生成 ### (1)生成的逻辑 ### 逻辑生成脚本(其他脚本) 其他脚本中典型的时chunk_entity_manager chunk_Entity_Manager,管理chunk的如何生成,是逻辑层面上的生成,在何时何地生成,生成chunk 这里的其他脚本既chunk_entity_manager,也可以改为相同功能的其他脚本 ### Chunk3Dmanager Chunk3Dmanager管理chunk的中间脚本,其中包含chunk列表,marching cubes算法,一些chunk生成相关的参数(auto_update,chunksize,isolevel等等) ### chunk_mesh_generator ​ 在生成chunk的时候chunk3dmanager具体的又调用chunk_mesh_generator的函数,这个脚本是具体执行生成的脚本,通过传入的参数,主要执行噪声的iso值的计算,通过Chunk3DManager传入的points和生成方式,计算以何种噪声方式生成每个点上的噪声值也即float4 points=x,y,z,w,其中w一般指的就是噪声的具体值,通过不同的compute shader, ​ 例如数学、柏林噪声计算出不同的噪声值,将points数据组传回chunk3dmanager,而chunk3dmanager再进行执行marching cubes算法,对得到的Points数组进行marching cubes计算法线向量和三角面片从而得到正确的三角形mesh. ​ 其中进行mesh更新的算法处于chunk3dmanager中,mesh更新时会调用chunk_mesh_generator执行,得到的结果传回到chunk3dmanager,也就是说chunk3dmanager将它的chunk生成的实际逻辑进行了封装隐藏 ![](\Projects\Unity_Projects\Game_Development\Main\Main_Development_Project\当前进度图片\chunk生成逻辑.png) # 关于地形生成 ## 一、关于柏林噪声的生成 ### 1、对噪声生成脚本Plat_Noise.compute的理解 关于柏林噪声的生成实际上也就是在Plat_Noise.compute当中 if (id.x >= numPointsPerAxis || id.y >= numPointsPerAxis || id.z >= numPointsPerAxis) { return; } 这个是确保生成的顶点的xyz值正确,使用这三个可以使得id.x,id.y,id.z都处于(0~numPointsPerAxis) 实际上在compute shader进行递增时的顺序是x增加到最大值后,y进1,y增大到最大值后z进1,最后到z到最大值后停止 id.x,id.y,id.z的值的实际范围如下,取决与两个方面 ``` [numthreads(1,2,3)] void csmain(id:xxx) ``` ``` compute.dispatch(kernel_index,x_threads,y_threeads,z_threads) ``` 则此时可以得到id.x的取值范围为(0~1**x_threads),id.y的取值范围为(0~2*y**threads),id.z的取值范围为(0~3*zthreads) int index = indexFromCoord(id.x,id.y,id.z);这个是通过id的xyz值得到数组中对应的顶点索引,因为每一次传入的points的是一个chunk的所有顶点,因此具有相同的顶点的xyz值,从而得到相同的index索引值,索引到每个chunk相同的对应位置的顶点 float3 pos = center + id * cubeSize - numPointsPerAxis * cubeSize * 0.5; 这一行是将chunk的xyz坐标从chunk的本地坐标中转移到游戏空间坐标中去 float3 pos2 = pos * position_scale; 这一行是重点,因为实际噪声是比较小的,chunk也是比较小的,因此如果要连续的化,这里缩小了坐标的实际位置到一个缩小的坐标区域,从而得到该区域的连续的噪声值,在实际中缩小到了0.017左右,使用缩小坐标计算得到的平滑噪声值,再将噪声值放回到原来坐标顶点的位置上面 float value = (noise * noiseScale + pos.y * heightScale); ```shaderlab points[index] = float4(pos, value); ``` 也即这一段,通过pos为原坐标,而noise实际上是缩放后的pos2计算得到的噪声值数据,在基于修改噪声值变动的时候必须要注意到并不是直接在原坐标上面执行的修改,应该要考虑到缩放这一因素,应该先对对应的坐标进行操作,然后执行统一缩放,这样可能才会得到正确的执行结果。 可以使用Position_Scale缩放,然后通过height_scale控制高度的占比,来控制地形的高度,用LOD来控制细节 ## 二、关于噪声上的修改变动 介绍:修改噪声的目的主要是因为在噪声实际生成的时候,产生的地图同质化非常严重,整个地图在近的地方看上去是平滑变化的,但整体的地形感觉上是千篇一律的,就像是熵没有变化一样,考虑的是制造一个熵增的地形,制造更多的变化性,使得整个游戏的地形变得更加的多样化,目前的尝试还非常的浅显 ### 1、基于修改ISO值的插值变动 在chunk3dmanager中的marching cubes算法中基于修改iso值的插值变动,进行动态的计算三角面片,会使得三角面皮不能够正确显示,导致层状的三角面片出现,而中间则是空气,这是因为不同的isolevel值导致不同的噪声得不到正确的计算 ### 2、基于修改噪声值的插值变动 在chunk_mesh_generator中,对computer_shader(NoiseTerrainGenerator)中的噪声值进行修改,这样通过计算出不同的噪声值再导入到chunk3dmanager中进行缝合计算,不会导致类似修改iso的灾难结果,但这样修改需要考虑的东西很多,举个例子 ### (1)基于中心点(圆心邻域),插值附近的柏林噪声参数 ​ 具体的,通过距离的不同,对柏林噪声生成的参数进行插值变动,具体的就是粗糙度、持久度、高度缩放、噪声缩放等参数,通过修改这些参数,产生不同的效果,目前尝试过的是圆心邻域插值 ​ 在插值的时候注意到了,如果插值距离插反了话,会产生奇怪的效果 ### 3、其他方法 ## 二、关于多线程生成 多线程生成这一套主要考虑的是动态生成与预生成结合的逻辑方法,基本思想是在玩家近的地方生成的chunk的速度比较块,而里玩家较远的地方可以同时生成或者延后生成, ### 1、使用IJob 使用ijobfor接口来实现多线程的生成 ### 2、使用空气墙 当要进入该chunk的时候只有等待该chunk完全生成后才能进入,当然最小的范围应当是玩家周围的8个chunk ### 3、使用LOD技术 这里使用LOD的技术也即是对chunk的point_num_per_axis的值进行修改,进而使得显卡在计算chunk的时候可以更快