URP数据与接口 - ForwardRenderer
[toc]本篇继续讲URP中的数据与接口。 本篇从渲染方案讲起,也就是ForwardRenderer类型,遇到什么再说什么。
ForwardRenderer概览
ForwardRenderer实例随着管线实例初始化时,批量初始化; 多个ForwardRenderer实例供相机选择,可切换渲染方案: 比如A场景有特殊的镜面效果,A场景的主相机需要用到镜面相机方案。 在代码方面,主要继承Setup方法,判断如何处理Pass队列。 方案中自带了很多Pass,改动需要修改源代码,而自定义Feature则可以灵活插入。
Setup方法
Setup中决定了Pass队列和写入目标,是相当核心的逻辑代码;
分支 - 非相机栈+渲染深度到RT
如果设置相机的渲染目标为RT,且RT的格式为Depth,那么我们可以得到一张深度图; 为了实现这样的,特殊的相机渲染任务,可以简化流程,只渲染有深度值的步骤: RT的写目标就是BuiltinRenderTextureType.CameraTarget,表示用户指定的RT。
分支 - 创建中间RT
如果将写入目标处理为一个可以随时采样的临时RT,对自定义着色方案非常 ...
SRP后处理 Lut贴图与常见效果
[toc]本篇描述SRP中的color LUT,即颜色查找表。 在URP中定义了一个m_ColorGradingLutPass,用来绘制color LUT贴图; 这个贴图被传递给后处理阶段使用,与色调映射相关。 参考资料:Unity后处理wiki
RT的声明
Shader属性名:_InternalGradingLut 采样过滤方式:Bilinear 高度:在管线设置-后处理-LUT size参数 默认是32像素宽 宽度:等于高度的平方 默认是32x32 = 1024像素宽 是否开启HDR模式: 1.在管线设置-质量-HDR选项 默认不开启HDR 2.在管线设置-后处理-Grading Mode选项 默认不开启HDR 纹理格式: 1.HDR模式优先使用R16G16B16A16_SFloat 2.LDR模式使用R8G8B8A8_UNorm //在不支持浮点纹理的平台
影响Lut的后处理效果参数
相关专有名词: 色相:Hue 用色环表示 饱和度:Saturation 亮度:Luminance 很多后处理效果(色调调整类型)的参数都参与了Lut贴图的计算; 在运行时这些效果直接从Lut贴图采样 ...
MMD shader
[toc]本篇内容主要为解析MMD4Mecanim插件中的shader。 工程中使用了RemMiku,测试用的Unity版本为2018.3.9和2019.1.0b10。 MMD4Mecanim使用的2018/05/23版本,Unity加载后会为每个材质生成MMD材质编号。
观察
PmxEditor中、Unity中分别观察Miku,可以发现一些不同来。 这些不同有可能是Unity的锅,也有可能是shader的锅。 不同一: 21号材质Fronthair+表现的头发很死板,高光区域非常小。 在PmxEditor中观察,这块区域由2个材质20.Fronthair和21.Fronthair+控制。 显示顶点后可以发现这2个材质的顶点位置完全相同,但分别使用的不同顶点。 21.Fronthair+只有头发高光采样,高光区域有发色的渐变效果。 20.Fronthair就是普通的前发了。 而在Unity中,重叠着色的两个片元是竞争关系,ZTest默认值LEqual。 所以,应该要为这些重叠的片元做混合。另外高光区域则是Cubemap生成的问题。 21.Fronthair+应该使用透明shader ...
Unity 友元程序集与Package Manager
[toc]本篇描述,设置有元程序集,使其他程序集可访问Internal类型。
Asmdef自定义友元程序集
在Unity中创建一个.asmdef文件,描述一个程序集,同级目录添加AssemblyInfo.cs:
using System.Runtime.CompilerServices;[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.Tests")][assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor")][assembly: InternalsVisibleTo("Unity.ShaderGraph.GraphicsTests")][assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.GraphicsTests")][assembly: InternalsVisibleTo("Unity.R ...
URP数据与接口 - 相机栈
[toc]本篇继续讲URP中的数据与接口。 本篇从相机栈渲染讲起,也就是RenderCameraStack方法,遇到什么再说什么。
编辑相机栈
选择一个Base相机,在Stack栏中用+号按钮添加Overlay相机,组成相机栈; 没有Overlay相机,就新建一个Camera,设置RenderType为Overlay。
渲染管线中出现的几种常见类型
PipelineAsset:就是我们创建的管线配置文件,全局独一份; Pipeline:被Asset的CreatePipeline方法实例化,也是全局独一份; RendererData:Asset的m_RendererDataList参数,指定一个渲染方案列表,长度至少为1; 注:Data列表中有一个被标记为默认值;Camera从列表中选择一个Data执行渲染任务; Renderer:与Data一一对应,包含渲染逻辑,比如Renderer2D、ForwardRenderer。 Feature:Data的m_RendererFeatures参数,是一个Feature列表,这些Feature可以插入Renderer逻辑中的某一个环节,比如透明队 ...
球谐光照与烘焙
[toc]本篇描述Unity中的SampleSH函数。 参考资料: 球谐光照解析 Unity光照烘焙技术 [Unity零基础入门]8.全局光照GI 陈嘉栋:编辑probe信息 LightProbes Manual 特别棒的探针布置教学视频
SH与间接光
我们偶尔能在shader代码里面看到SampleSH这样的引用: float3 color = SampleSH(float3(0, 1, 0)); //采样球体正上方的颜色 这里的SH,指的是光照探针,是Unity根据mesh最近的3个probe进行差值的结果。 如果我们关闭了自动烘焙导致没有烘焙probe,则采样结果是黑色; 如果场景中没有probe,则使用光照设置中的环境probe,通常是Sky Box; 动态物体通过采样probe获得静态物体的间接光贡献; probe中的记录了probe位置处多个角度采样的颜色,保存为SH系数; 采样probe的过程中通过SH系数快速计算出采样结果,相比Cubemap贴图来说节约性能。 probe仅作为保存颜色的方式,而这些颜色都是通过RayTracing离线计算的,不能实时变化。 probe中 ...
URP数据与接口 - 管线实例
[toc]本篇描述URP中的数据与接口 从UniversalRenderPipeline.cs看起,遇到什么讲什么,跳过了XR/VR设置。
PerFrameBuffer
这个类型存储了一组静态int,都是全局shader变量,下面判断变量用途。 1._GlossyEnvironmentColor 环境反射光 在取值上:获取环境探针的L0的3个系数,也就是平均环境光色: new Color(ambientSH[0, 0], ambientSH[1, 0], ambientSH[2, 0]) 得到的是线性空间(linear)的颜色,如果需要转换到gamma空间: color = color.gamma; //0.5变成0.735左右 在使用上:Lighting.hlsl中GlossyEnvironmentReflection方法: 判断材质上是否关闭了环境反射,默认使用unity_SpecCube0(最近的反射探针)采样;关闭后使用本值,从环境光采样反射值。 2._SubtractiveShadowColor 静态物体-烘焙处的阴影色的下限 在Baked Indirect模式下,只烘焙间接 ...
ET 数值与订阅Numeric
[toc]本篇描述ET中的数值监听组件。 参考:ETbook 5.6数值组件的设计 代码:Model/Module/Numeric文件夹 熊猫在book中讲到了,传统面对对象设计思路中,复杂的数值模板继承带来的难以维护。 我们经常可以看到角色类拥有几十个字段的情况,某个字段发生了变化时设置isDirty = true用于判断是否需要重新计算值。 每个属性受到5个字段影响,与MaxHp关联的5个字段是: MaxHpBase、MaxHpAdd、MaxHpPct、MaxHpFinalAdd、MaxHpFinalPct ET的数值组件用容器存储数值,如果一个角色有数值计算的必要,则给它添加一个数值组件; 相对的,很多NPC没有战斗逻辑,也就不需要添加这个组件。 每个属性类型受到5个字典中的值影响,。
应用场景
有一名战士,更换了一件板甲胸,属性如下: 微光胸甲:防御300,力量15,体力30,智力15,HP上限200,MP上限300,附带技能:微光护罩 微光护罩:生成一个护罩,提供临时生命500点,持续时间5秒,冷却30分钟。 那么,道具设计怎么与数值组件关联的呢? 数值框架 策划根据游戏类型 ...
ET 取消任务CancellationToken
[toc]本篇解释任务取消机制。 ET中提供了一种,在主线程取消ETTask的操作。 比如,描述一个异步移动任务:
public ETTask MoveToAsync(..., CancellationToken cancellationToken){ //任务相关设置 this.moveTcs = new ETTaskCompletionSource(); cancellationToken.Register(() => { this.moveTcs = null; }); return this.moveTcs.Task;}
这样的ETTask的特点是: 1.方法声明没有async标签,方法内部也就不能使用await标签; 2.在方法被引用时,必须await本方法,也就说只能在异步方法内调用: await MoveToAsync(…, cancellationToken); 如果不加await,编译器提示:此调用不会等待,将在调用完成之前继续当前方法; 3.从形式上来说,就是返回了一个未完成的任务,而且需要等待任 ...
GOAP入门
[toc]本篇描述Goal-Oriented Action Planning(简称GOAP)。 参考资料: ReGoap:https://github.com/luxkun/ReGoap 烟雨的博客
ExampleFSMScene
MultipleResourcesManager
本篇中,用Plane上的大量mesh来演示资源的概念。 有很多的木材和矿石资源,这些在场景初始化的时候,必须先生成好。 1.资源有不等的初始储蓄量,可以被挖掘消耗,类似于怪物的HP。 2.资源有不同的类型,继承了“资源”接口,在交互逻辑上有相似性。 3.每种资源需要单独管理,比如木材管理组件,告诉工人,哪里有树可以砍伐。
WorkstationsManager
工作站管理组件,在初始化时描述数个工作站,告诉工人,哪个工作站可用。 1.工作站需要明确用途,在本例中,工作站只有一个用途:合成物品(斧头)。 2.工作站有加工资源的能力,将材料,通过配方,转化为产出物品。 3.默认工作站可以处理任何类型的配方。
组件 BankManager
银行管理组件,在初始化时描述数个银行,告诉工人,哪个银行可用。 1.银行使用 ...