shader学习实例——CurvedWorld
前言
动物森友会、地铁跑酷弯曲状的地图效果,在unity资源商店一看,好家伙——49刀,捂了捂钱包,成功被激发了学习unityshader自己制作该效果的欲望。
这是我编写的第一个shader,使用unity URP(通用渲染管线)Graph制作。
准备
- unity editor 21年之后的版本,建立项目时选择urp项目。
- 使用unity shader graph(shader可视化编辑器)。
前置知识
渲染管线简介
渲染管线
也被称为渲染流水线或像素流水线,是显示芯片内部处理图形信号的相互独立的并行处理单元。这可以比作工厂中的生产流水线,以提高产品的生产能力和效率。在某种程度上,渲染管线对于显卡的工作能力和效率至关重要。
目前Unity中的渲染管线主要有以下几种:
内置渲染管线(Build-In Render):这是Unity最早的渲染管线,也是默认的渲染管线,提供了一套简单的渲染流程,但相对来说功能较为基础,对于一些高级的图形效果可能无法实现。
SRP 可编程渲染管线技术(Scriptable Render Pipline) :可以在Unity通过C#脚本调用API配置或执行渲染命令的方式来实现渲染流程,SRP将这些命令传递给Unity底层图形体系结构(low-level graphics architecture),然后再将指令发送给图形API(Graphics API),最终由GPU进行处理,SRP 技术可以强化通用渲染管线 (URP) 和高清渲染管线 (HDRP)。URP和HDRP建立在SRP之上,还可以在 SRP 之上创建自己的自定义渲染管线。
URP 通用渲染管线(Universal Render Pipeline):从Unity 2019.3版本开始,Unity引入了通用渲染管线URP,它是一种快速的单通道前向渲染器,主要设计用于不支持计算着色器技术的低端设备,例如较早的智能手机、平板电脑和XR设备。但是,URP还可为中端设备(如游戏主机和PC)提供更高质量的图形性能。
HDRP 高清渲染管线(High Definition Render Pipeline):这是Unity的高质量渲染管线,主要针对高端设备,例如最新的智能手机、游戏主机和PC等。它提供了更高的视觉效果和更真实的图像表现,同时也需要更高的计算能力。
以Universal Render Pipeline(URP)为例,Unity中的渲染管线的主要步骤如下:
顶点着色器:这个阶段主要处理顶点相关的操作,比如顶点位置,颜色,纹理坐标等相关的变换。
光栅化:这个阶段将顶点数据转换成片元(像素)数据,这个过程也涉及到裁剪和剔除等操作,比如将视野外的模型裁剪掉,剔除背面等操作。
片元着色器:这个阶段会针对每个片元(像素)进行操作,主要处理光照和材质等效果。
输出合并:这个阶段会进行一些操作比如深度测试、模板测试、颜色混合等,最后将渲染结果输出到屏幕上。
Shader Graph简介
Shader Graph 是Unity中的一个可视化着色器编辑工具,它允许开发者通过连接节点来创建和编辑自定义的着色器效果。使用ShaderGraph,开发者可以以图形化方式创建复杂的渲染效果,而无需编写复杂的着色器代码。
ShaderGraph提供了一个直观的界面,其中包含各种节点,开发者可以将它们连接起来以构建想要的效果。这些节点代表了着色器中的各个部分,例如顶点处理、片段处理、表面函数等。通过连接节点,可以定义材质的输入和输出,并在节点之间传递数据。
ShaderGraph支持多个渲染管线,包括Unity的内置管线和Universal Render Pipeline(URP)。在创建ShaderGraph时,开发者可以选择所需的目标管线,并且ShaderGraph会相应地生成相应的着色器代码。
使用ShaderGraph,开发者可以轻松地实现各种常见的着色器效果,例如颜色混合、纹理映射、法线映射和光照计算等。此外,ShaderGraph还支持自定义节点,开发者可以编写自己的节点来实现特定的效果。
除了可视化编辑功能外,ShaderGraph还具有实时预览功能,开发者可以在编辑器中即时查看和调整效果。这使得迭代开发变得更加便捷和高效,开发者可以快速调整参数并立即看到结果。
另一个强大的功能是ShaderGraph的可移植性。开发者可以将创建的ShaderGraph保存为可重用的自定义着色器,然后在不同的项目中重用它们。这简化了着色器的管理和共享,同时也提高了代码复用性和开发效率。
官方称ShaderGraph具有如下的特点:
直观构建着色器。用户无需编写代码,而是在图形框架中创建和连接节点。
提供反映更改的即时反馈。这对于不熟悉着色器创建的用户来说是非常友好的。
Shader Graph仅与可编写脚本的渲染管线(SRP)兼容。这个渲染管线包括高清晰度渲染管线(HDRP)和通用渲染管线(URP),这两个SRP在Unity 2018.1及更高版本中都可用。然而,传统的内置渲染管线不支持Shader Graph。
此外,Shader Graph是基于可编程流水线,通过节点图的方式来实现可视化的Shader的编程,这种方式可以让用户不必再编写大量的代码以及考虑语法和错误调试等问题。
总而言之,ShaderGraph是Unity中一个强大而直观的工具,它使得创建自定义着色器效果变得更加容易和可视化。无论是新手还是经验丰富的开发者,都可以通过ShaderGraph快速实现各种复杂的渲染效果,并将其应用于自己的游戏或应用程序中。
Shader Graph相关链接
- Shader Graph官方文档:最新版本文档
- Shader Graph官方文档:中文文档
- Shader Graph官方示例: Shader Graph示例
Shader Graph窗口介绍
在Project面板右键 Create → Shader Graph → URP
,选择 Lit Shader Graph 或 Unlit Shader Graph,创建 Shader Graph。
Lit Shader Graph和Unlit Shader Graph的主要区别在于是否包含光照模型。
- Lit Shader Graph带有光照模型,它基于物理的光照模型(PBR),使用法类似于表面着色器。这意味着在Lit Shader Graph中,你可以实现光照的反射、投射和散射等效果,创建出更逼真、更具视觉冲击力的图形。
- Unlit Shader Graph没有光照模型,你需要自己编写光照计算流程。这意味着在Unlit Shader Graph中,无法直接实现光照的反射、投射和散射等效果,而是需要用其他手段模拟这些效果,或者实现其他类似的效果。不过,这也给了Unlit Shader Graph更大的灵活性,因为它不依赖于固定的光照模型,可以根据需要进行更定制化的处理。
创建完Shader Graph之后会出现一个shadergraph文件,双击打开该文件即可弹窗ShaderGraph的窗口面板。
Shader Graph窗口组成
Shader Graph 由 Blackboard
、Graph Inspector
、Main Preview
、Vertex
、Fragment
、Node
等模块组成。
Blackboard:用于创建外部属性,相当于 Shader 中的 Properties,可以创建 Float、Vector2
4、Color、Boolean、Gradient、Texture2D、Texture2D Array、Texture3D、Cubemap、Matrix24 等类型变量。Graph Inspector:包含节点设置和图设置两个选项卡,节点设置中可以设置节点命名、参数值域、默认值等信息;图设置中可以设置着色器数值计算精度、支持的渲染管线(Built-in 或 Universal)、管线参数等。
Main Preview:用于预览着色器渲染效果,在该窗口右键,可以选择预览的模型。
Vertex:顶点着色器,顶点变换、法线变换、切线变换在这里进行。
Fragment:片元着色器,光照计算、贴图在这里进行,在 Graph Inspector 窗口的 Graph Settings 选项卡里的 Material 中可以选择 Lit(PBR 光照模型)或 Unlit(无光照模型)的片元着色器。
Node:节点,在 Shader Graph 窗口的空白区域右键,选择 Create Node,创建相应节点,节点类型主要有 Artistic(对比度、饱和度、白平衡等美术调整)、Channel(合并和分离通道等)、Input(顶点位置、颜色、法线、时间等输入)、Math(加减乘除等数学运算)、Procedural(噪声、圆形、多边形等程序纹理)、Utility(逻辑判断、自定义函数等实用工具)、UV(球形扭曲、旋转贴图等 uv 变换)。
可以在官网文档查阅关于更多节点的作用:节点库
Shader Graph 窗口使用技巧
Shader Graph 窗口中的Blackboard、Graph Inspector、Main Preview模块可以通过右上角的按钮控制显示和隐藏,点击左上角的 Save Asset 按钮可以保存Shader Graph文件。
滑动鼠标滑轮可以放大和缩小节点,按鼠标中键或者Alt+鼠标左键拖拽可以平移场景,在Shader Graph 窗口中鼠标移动到模块的右下角可以调整预览框的大小。
当节点较多时,可以对其分类整理使得视图更加整洁清晰,还可以对整组进行保存复用。
鼠标按下框选要放在一组中的节点,然后右键选择Group Selection,自定义命名即可创建组。选中组之后,点击右键选择Delete即可删除组。
实例制作—curvedWorld
效果
游戏画面和场景画面
游戏画面可以看到地图尽头是扭曲的,打上光线更有氛围。
这是场景,这是目前生成的地图,其实已经可以看出来了,弯曲的原理就是抛物线。
Graph
话不多说,直接上结果图
原理
- 道路离玩家(摄像机)越远,世界就向侧边弯曲——世界需要的曲线的指数取决于玩家的位置关键字
- 地图会根据相机的位置而变化,所以地图是抛物线制成,从上往下看是它的抛物面
判断相机与物体位置在z轴上的距离(用split分离出z,rgba分别代表xyzw),并用power结点将其平方(抛物线公式)
用两个浮点数结点控制曲率强度,一个是左右弯曲,一个是上下弯曲(本案例中没有采用,但是动森是这种上下弯曲效果)。
然后将该值与平方数相乘(multiply结点),就可以改变弯曲度了。最后将这个值add在position上,但现在只是物体本身的位置,要用transform将物体坐标空间切换到世界坐标空间,连接Vertex结点基本就完成了。后续需要改变材质的话的话可以在Fragment结点操作。