Unity程序化地形教程 第一期

前言:最近在准备作品集,想吧Blender里面利用shader实现的程序化地形导入Unity中,发现我弄不了,于是转向了直接在Unity中实现程序化地形的新途径,但是网上的教程很少,b站和CSDN好像都没有详细的教程,所以今天我科学上网找了一下,查到了一个16年的程序化视频教学,自带机翻英文的那种,就是按他的翻译根本翻译不对,听也听不太懂,所幸能够理解代码意思,想借这个机会去做一篇程序化地形的教程,先是以博客的形式去记录每次所学,把所学弄懂,再去下一章的学习,最后我会在b站制作一个视频教程,希望大家多多支持,文章是我学习后自己的理解,肯定有些地方不对,不对的地方还请大家多多指教,感兴趣的朋友可以点一波关注,持续更新!

零、学完本期后的效果展示

初步直租出一张噪声图,为后续创作打下基础

一、我对于程序化地形的理解

简单来说程序化地形需要一个高效的伪随机数生成器,随机数包括地形的长、宽、高度、大小,然后利用一个载体把这些数合理的展示出来,大家最常见的其实就是黑白噪声图

以这张图为载体,他的长、宽、大小就是程序化地形的大小,那么有人就会问:地形高度和地形间的间隙是如何表现出来的?这里其实是使用到了噪声的波形来做的

波形图看起来是不是很像山脉的起伏一样?从而我们可以自己定义一个波形图,通过修改波形图的长宽大小,以及噪声的分布来实现一个地形的设计,这样之后噪声图就相当于一个地形编辑器了,我们通过编辑噪声图间接的编辑出地形,进而我们再加上颜色和其他属性,就能为地形增添上更多的细节,以此来达到一个程序化地形的效果。

二、程序化地形初步实现

1.定义噪声图

首先我们需要像我上面所说的一样,定义一个噪声图,让它成为程序化地形的一个载体,为此我们编写一个噪声脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public static class Noise
{   //定义一个函数生成地图 利用噪声来设置地形的长宽大小等属性public static  float[,] GenerateNoiseMap(int mapWidth,int mapHeight,float scale) {//定义一个两个维度的浮点数类型的数组 用于存储长、宽数据float[,] noiseMap = new float[mapWidth, mapHeight];//防止地图的大小出现负数if(scale<=0){scale = 0.0001f;}//对传入的函数的长、宽参数进行灰度值赋值 模拟噪声for(int y =0;y<mapHeight;y++){for(int x=0;x<mapWidth;x++){//除以scale 让影响scale的同时能够影响到地图缩放的大小float sampleX = x / scale;float sampleY = y / scale;//柏林值 Mathf.PerlinNoise可以简单理解为随机获得在这个点的灰度值float perlinValue = Mathf.PerlinNoise(sampleX, sampleY);//将灰度值返回给这个点noiseMap[x, y] = perlinValue;}}return noiseMap;}
}

2.定义一个地形生成器

在这里就会用到我们刚刚写好的noise脚本,用这个脚本来实现对噪声参数传入的控制,用这个脚本来控制地形的生成

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MapGenerator : MonoBehaviour
{public int mapWidth;public int mapHeight;public float noiseScale;//生成地图public void GenerateMap(){//这里将输入的长、宽、大小代入刚刚定义好的生成噪声的函数中float[,] noiseMap = Noise.GenerateNoiseMap(mapWidth, mapHeight, noiseScale);//MapDisplay是用来将噪声转化为地形的脚本 在这里将上面处理后的数据转化为地形//下一个脚本再具体介绍 这里可以直接写MapDisplay display = FindObjectOfType<MapDisplay>();display.DrawNoiseMap(noiseMap);}
}

3.定义一个地图展示器

将我们所输入的参数得到的噪声图转换为一个地图展现出来

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MapDisplay : MonoBehaviour
{//通过控制plan的Renderer来控制地形的显示public Renderer textureRender;//绘制噪声图public void DrawNoiseMap(float[,] noiseMap){//用来获取数组指定维数中的元素个数 这里分别是长和宽int width = noiseMap.GetLength(0);int height = noiseMap.GetLength(1);Texture2D texture = new Texture2D(width, height);//Color类型是接收的是一个[0,1]的值,需要用R,G,B,A四个值各自除以255//这里是定义整张图的取值面积 即要修改颜色点的多少Color[] colourMap = new Color[width * height];//将每个点赋值色彩for(int y=0;y<height;y++){for(int x =0;x<width;x++){colourMap[y * width + x] = Color.Lerp(Color.black, Color.white, noiseMap[x, y]);}}//将图按原比例绘制下来texture.SetPixels(colourMap);//将定义的图像纹理进行应用 此前需要进行SetPixelstexture.Apply();//将应用后的图交给Randerer去展现效果textureRender.sharedMaterial.mainTexture = texture;textureRender.transform.localScale = new Vector3(width, 1, height);}
}

四、定义一个地图编辑器

用于实时呈现出更改后的地形的样式

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;//将我们定义好的控件展示出来
[CustomEditor(typeof(MapGenerator))]
public class MapGeneratorEditor : Editor
{public bool mapGenChange = true;public override void OnInspectorGUI() {MapGenerator mapGen = (MapGenerator)target;//修改参数不用运行就能看到修改后的效果if(DrawDefaultInspector()){if(mapGenChange){mapGen.GenerateMap();}}//点击按键就能更新if (GUILayout.Button("Generate")){mapGen.GenerateMap();}}
}

5.初步效果展现

首先在3D场景中创建一个Plane,只保留如下两个组件

创建一个材质球,将它的类型修改为Unlit/Texture,并赋值给Plane,如上图所示

再新建一个空物体用来控制地形的生成,挂载脚本以及赋值如图所示

最后我们通过修改Map Genertor脚本中的参数来控制地形的生成

这样一个基本的用于控制地形生成的噪波图就制作好了,是不是很有趣呢?感兴趣的话点个关注,后面持续更新!

Unity程序化地形教程 第一期 噪波图的制作相关推荐

  1. Unity程序化地形教程 第二期 噪声图的完善和更多细节添加

    Unity程序化地形教程 第二期 噪声图的完善和更多细节添加 前言:完整的程序化地形教程在我的主页相关专栏中,目前正在持续更新,可以添加收藏,方便日后查找 零.学完本期能够实现的效果 书接上期,学完之 ...

  2. Unity程序化地形教程集合

    Unity程序化地形教程集合 Unity程序化地形教程 第一期 Unity程序化地形教程 第二期

  3. 【UE4+Houdini+Bridge】程序化地形生成和野外植被撒点工具制作思路

    B站制作过程展示: Houdini To UE4 程序化地形生成制作过程与效果展示 Github Houdini与HDA源文件:Houdini-PCG-Environment-Generator 最终 ...

  4. 【第一期】看图识车站,快来看看你是不是资深铁路迷

    科普铁路车站空间拓扑 前言 新增"铁路科普"专栏,将融合文字.图片.代码.模型等多种形式分享铁路知识.第一期将以"看图识站名"的形式向大家展示熟悉的铁路车站空间 ...

  5. Unity新GUI教程 – 第一部分

    原文地址:http://www.raywenderlich.com/78675/unity-new-gui-part-1 泰然翻译组:夏月星.校对:glory. 不可否认Unity 是一个很棒的游戏引 ...

  6. android怎么美化ui,安卓教程第一期最终篇(转)systemui.apk最全修改美化

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.status_bar_latest_event.xml的修改: 源代码: xmlns:android="http://schemas.and ...

  7. cracer培训教程第一期 文件上传漏洞与命令注入漏洞

    偏向php 文件包含漏洞是代码注入的一种.其原理就是注入一段用户能控制的脚本或代码,并让服务器段执行,代码注入的典型代表就是文件包含file inclusion.文件包含可能出现在jsp.php.as ...

  8. android即时修改ui,安卓教程第一期最终篇(转)systemui.apk最全修改美化

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 1.status_bar_latest_event.xml的修改: 源代码: xmlns:android="http://schemas.and ...

  9. unity透明通道加颜色_树叶透明贴图的制作原理及渲染!

    对于很多刚开始接触渲染模块的同学来说,不知道透明贴图的制作原理,以及如何渲染出好的效果,今天结合案例给大家讲解一下,先打开我们需要的素材,如下图: 在制作之前我们先给树叶一个普通的blinn材质,然后 ...

最新文章

  1. 大数据WEB阶段 shiro安全控制框架
  2. 关于kafka中的timestamp与offset的对应关系
  3. python ini文件删除修改_如何在INI文件中编写时删除空格 - Python
  4. 【软件工程】软件开发方法
  5. 安卓案例:绘制文本图形图像
  6. Initialization failed for Block pool
  7. 关闭window 8.1 的skydrive
  8. SpringApplication run方法解析:SpringApplicationRunListeners(二)
  9. 5G+折叠屏:华为Mate Xs打造多项创新体验
  10. 微信小程序上线,后台接口失效问题
  11. Visio设计产品流程图
  12. 市政管理学考试复习资料
  13. Java的求学之路--Day01
  14. 数据库系统--期末复习
  15. blastall参数详解
  16. 【笔记本Windows的两个ctrl键失效解决办法大全解】
  17. 3.5mm音频插头的引脚连接关系
  18. Python项目实例——用代理IP爬取1688商品
  19. 【线性代数】分块矩阵的运算、特征值
  20. Linux中vmstat命令详解

热门文章

  1. div如何实现横向滚动
  2. 【一步一步学习VBA】WPS 使用 VBA
  3. 产品经理常用的数据指标(KPI)——用户
  4. unsigned a 是什么玩意
  5. Pandoc: LaTeX 转 Word 文档 (含参考文献样式)
  6. Web APIs,BOM树,声明dom对象,年会抽奖案例,随机图片,表单,用户注册倒计时,innerHTNL,classList的使用
  7. [分享] 30分钟做一个二维码名片应用,有源码!
  8. R语言 for循环之break,next
  9. 2022 年总结 山高路远,看世界,也找自己
  10. 揭开网上传销神秘面纱