1.unity urp源码学习一(渲染流程)
2.UnityShaderBlur 模糊(5)
3.UGUI源码阅读之Mask
4.UnityShaderBillBoard(公告牌)原理和实现
5.UnityShader 基础(29)-球面朝向映射(Matcap)-视角法线与平面反射
6.UnityShader入门精要—基础光照
unity urp源码学习一(渲染流程)
sprt的一些基础:
绘制出物体的关键代码涉及设置shader标签(例如"LightMode" = "CustomLit"),以确保管线能够获取正确的shader并绘制物体。排序设置(sortingSettings)管理渲染顺序,如不透明物体从前至后排序,透明物体从后至前,以减少过绘制。ethtoll源码分析逐物体数据的启用、动态合批和gpuinstance支持,以及主光源索引等配置均在此进行调整。
过滤规则(filteringSettings)允许选择性绘制cullingResults中的几何体,依据RenderQueue和LayerMask等条件进行过滤。
提交渲染命令是关键步骤,无论使用context还是commandbuffer,调用完毕后必须执行提交操作。例如,context.DrawRenderers()用于绘制场景中的网格体,本质上是执行commandbuffer以渲染网格体。
sprt管线的基本流程涉及context的命令贯穿整个渲染流程。例如,首次调用渲染不透明物体,随后可能调用渲染半透明物体、天空盒、特定层渲染等。流程大致如下:
多相机情况也通过单个context实现渲染。
urp渲染流程概览:
渲染流程始于遍历相机,如果是游戏相机,则调用RenderCameraStack函数。此函数区分base相机和Overlay相机:base相机遍历渲染自身及其挂载的Overlay相机,并将Overlay内容覆盖到base相机上;Overlay相机仅返回,不进行渲染操作。
RenderCameraStack函数接受CameraData参数,其中包含各种pass信息。添加pass到m_ActiveRenderPassQueue队列是关键步骤,各种pass类实例由此添加至队列。
以DrawObjectsPass为例,其渲染流程在UniversialRenderer.cs中实现。首先在Setup函数中将pass添加到队列,执行时,执行队列内的pass,并按顺序提交渲染操作。XP完整源码
UnityShaderBlur 模糊(5)
本节介绍模糊算法。模糊、边沿查找本质是一个滤波器,使用低通滤波/高通滤波来完成图像处理的目的。这些似乎涉及CV(计算机视觉)的研究范围,本文旨在展示如何在Unity中实现模糊效果,而非深入研究“信号与系统”的理论知识。做工程讲究实用性,能用即可。 后续更新:在Unity中实现模糊算法的步骤。一、在Unity中的前期准备
在上一节中,我们了解到如何在Unity URP中实现后处理效果。为了扩展PostProcessing相关组件(现在称为Volume),我们需要编写一个cs脚本,继承于VolumeComponent。Volume组件包含了常用的后处理特效,如Bloom(辉光)与ToneMapping(色调映射),可以显著提升画面效果。尽管Volume组件本身没有提供模糊功能,我们可以通过自定义实现。二、模糊算法实现
虽然高斯模糊是模糊算法的代表,但还有其他方式,如方框模糊、径向模糊、双重模糊、Kawase模糊等。本节将实现其中几种自认为实用的模糊效果。1. 模糊的本质
当我们感觉图像“模糊”时,实际上是因为像素点的颜色受到周围区域颜色的影响,使得像素点的“对比度”下降,颜色特征不鲜明。这种现象可以类比于人眼在远视状态下的视觉体验,物体反射的光线无法聚焦在视网膜上,形成多个“重影”,增加了模糊感。在图像处理中,模糊算法通过“污染”像素点的tomcat框架源码颜色,达到“模糊”效果。2. Kawase Blur
Kawase模糊采用动态卷积核来提升效率,不同于高斯模糊或方框模糊中的恒定卷积核。其核心思路是对距离当前像素较远的位置进行采样,并在两个大小相等的纹理之间进行乒乓式的blit操作。通过随迭代次数移动的blur kernel,实现更加灵活且高效的模糊效果。3. Dual Blur
双重模糊通过降采样和升采样过程实现,即在blit过程中进行图像大小的调整。相比于Kawase模糊,双重模糊在实现上更加复杂,但能提供不同场景下的模糊效果。4. Radial Blur
为了在图像中产生“速度感”和“打击感”,径向模糊是最常用的技术。通过在指定方向上进行模糊处理,可以模拟出物体移动或光线照射的效果。实现径向模糊时,需要调整纹理和采样方向,以达到预期的视觉效果。小结
通过上述方法,我们能够在Unity URP中实现常见的模糊算法。在实际应用中,可以根据需求选择最合适的模糊类型,例如,Kawase模糊在性能和效果上通常被认为是一个不错的选择。模糊算法在后处理中有着广泛的应用,如体积光处理,能够有效提升场景的视觉效果。UGUI源码阅读之Mask
Mask主要基于模版测试来进行裁剪,因此先来了解一下unity中的模版测试。
Unity Shader中的模版测试配置代码大致如上
模版测试的伪代码大概如上
传统的渲染管线中,模版测试和深度测试一般发生在片元着色器(Fragment Shader)之后,但是现在又出现了Early Fragment Test,可以在片元着色器之前进行。
Mask直接继承了UIBehaviour类,同时继承了ICanvasRaycastFilter和IMaterialModifier接口。
Mask主要通过GetModifiedMaterial修改graphic的Material。大致流程:
1.获取当前Mask的层stencilDepth
2.StencilMaterial.Add修改baseMaterial的模板测试相关配置,并将其缓存
3.StencilMaterial.Add设置一个unmaskMaterial,ai对战源码用于最后将模板值还原
MaskableGraphic通过MaskUtilities.GetStencilDepth计算父节点的Mask层数,然后StencilMaterial.Add修改模板测试的配置。
通过Frame Debugger看看具体每个batch都做了什么。先看第一个,是Mask1的m_MaskMaterial,关注Stencil相关的数值,白色圆内的stencil buffer的值设置为1
这个是Mask2的m_MaskMaterial,根据stencil的计算公式,Ref & ReadMask=1,Comp=Equal,只有stencil buffer & ReadMask=1的像素可以通过模板测试,即第一个白色圆内的像素,然后Pass=Replace,会将通过的像素写入模板值(Ref & WriteMask=3),即两圆相交部分模板值为3
这个是RawImage的Material,只有模板值等于3的像素可以通过模板测试,所以只有两个圆相交的部分可以写入buffer,其他部分舍弃,通过或者失败都不改变模板值
这是Mask2的unmaskMaterial,将两个圆相交部分的模板值设置为1,也就是还原Mask2之前的stencil buffer
这是Mask1的unmaskMaterial,将第一个圆内的模板值设置为0,还有成最初的stencil buffer
可以看到Mask会产生比较严重的overdraw。
2.drawcall和合批
每添加一个mask,一般会增加2个drawcall(加上mask会阻断mask外和mask内的合批造成的额外drawcall),一个用于设置遮罩用的stencil buffer,一个用于还原stencil buffer。
如图,同一个Mask下放置两个使用相同的RawImage,通过Profiler可以看到两个RawImage可以进行合批
如图,两个RawImage使用相同的,它们处于不同的Mask之下,但是只要m_StencilValue相等,两个RawImage还是可以进行合批。同时可以看到Mask1和Mask1 (1),Mask2和Mask2 (1)也进行了合批,说明stencilDepth相等的Mask符合合批规则也可以进行合批。
StencilMaterial.Add会将修改后的材质球缓存在m_List中,因此调用StencilMaterial.Add在相同参数情况下将获得同一个材质球。hbase x源码
UnityShaderBillBoard(公告牌)原理和实现
公告牌技术
公告牌技术是基于视角确定纹理矩形朝向的一种图形处理方法。它广泛应用于实现诸如草、烟、火、雾、爆炸、云等特殊效果。这一技术的核心在于建立一个基于视角的坐标系,通过旋转物体来保持纹理矩形在特定方向上固定,从而模拟各种动态效果。
公告牌原理
在实现公告牌技术时,需要记录物体在物体空间的顶点相对于原点的各方向位移。利用相机位置确定视线方向,从而确定物体的法向量(与视线方向相反且平行)。通过指定一个向上向量重建新的坐标系,并将顶点在原坐标系的位移转移至新坐标系建立旋转后的顶点位置,完成在物体空间下的旋转。
公告牌分类
屏幕对齐的广告牌是最简单的一种形式,其图像总是平行于屏幕,具有恒定的向上向量。摄像机将物体投影到与远近平面平行的视图平面上。在这种类型的广告牌中,物体表面的法线为视图平面法线的相反方向。通常用于粒子系统或总是面向屏幕的文本。
Viewpoint-oriented广告牌则更为复杂。在这种情况下,向上的向量由相机本身的向上向量变为世界空间下的向上向量。通过与物体法向(与视线方向相反且平行)叉乘求得向右向量,最后使用物体法向与该向右向量叉乘求得物体最终准确的向上向量,完成新的坐标系的重建。这使得广告牌能够更好地模拟真实世界中的运动。
公告牌实现
在UnityShader中,实现公告牌技术可以通过编写特定的着色器代码来完成。参考《UnityShader入门精要(冯乐乐)》等资源,可以学习到具体的实现方法。在Unity中,物体的scale属性必须等比例缩放,且rotation属性全为0,才能确保广告牌达到预期效果。这确保了物体空间的向上向量与世界空间的向上向量同向平行。
公告牌技巧
虽然等比例缩放和旋转属性为0是推荐的做法,但也可以利用这些属性达到一些特殊效果,例如特定视角下的物体缩放。通过调整物体的scale属性在不同坐标轴上的比例,可以实现特定视角下物体形状的变化。这展示了公告牌技术的灵活性和多用途性。
UnityShader 基础()-球面朝向映射(Matcap)-视角法线与平面反射
在Unity Shader中,有一种叫做Matcap的技术,它是一种快速模拟反射效果的便捷方法。Matcap源自于ZBrush,其原理是通过让物体表面的视角法线与Matcap球体表面的坐标方向对应,实现直观的反射效果展示。视角法线是一种特殊的法线,它依据摄像机视角定义,例如物体正面朝向正左时,视角法线的X值为1,正右则为-1,以此类推。
在处理法线数据时,需要注意缩放可能带来的影响,通过normalize()函数将其转换为标准的-1到1范围。然后,通过UV坐标映射,使用*0.5+0.5的转换方法和saturate()函数防止溢出,确保视角法线与UV对应。Matcap通常来自金属球体或鱼眼相机,被称为鱼眼图像,获取更多素材可以通过加入指定QQ群。
基础Matcap Shader代码中,可以引入_MatCapMipLevel来控制清晰度级别,以便在不同的LOD(Level of Detail)下显示。在处理纯平面物体时,反射效果会呈现出单一颜色,这是因为取色和反射取色规则不同。通过reflect()函数可以实现反射,但可能产生折返效果。通过调整法线数据,可以控制反射的强度和形状,如使用Pow()函数或自定义函数。
针对平面颜色一致问题,需要在顶点和法线到视角空间的转换中进行修正,确保法线方向在缩放时保持正确。通过这种方式,平面图像的反射效果得以改善。最后,可以结合曲率计算,混合平面和曲面的反射效果,创建更丰富的视觉效果。
总的来说,Matcap技术为Unity Shader提供了直观、高效的反射模拟,通过灵活的处理和组合,可以实现丰富多样的材质效果。
UnityShader入门精要—基础光照
在Unity引擎中,模拟物体与光交互的结果是通过光照模型实现的。该过程包括光源发射光,物体与光交互发生散射与吸收,以及最终光线到达摄像机形成影像。物体表面的属性、光源信息通过特定的数学公式计算,得到沿某个观察方向出射的光的集合。
标准光照模型包括自发光、高光反射、漫反射和环境光四个部分。漫反射模型基于兰伯特定律,计算公式为I=Kd*N·I,其中n表示法线方向,I表示指向光源的单位矢量,Kd是材质的漫反射颜色,I是光源颜色。半兰伯特模型通过缩放和偏移调整值域,计算出更亮的漫反射效果。
高光反射使用Phong模型计算,公式为I=Ks*r·v,其中r=2(n·I)n-I,Ks表示材质的高光度,v表示观察方向,max(0,x)防止计算结果为负数。Blinn提出了一种简化版的高光计算模型,计算效果与Phong模型类似但更简单。
Unity中应用标准光照模型时,通过顶点着色器和片元着色器进行自定义计算。顶点着色器逐点计算,片元着色器逐像素计算,后者计算量更大但效果更佳。漫反射和高光反射分别通过代码片段和UnityASE编辑器节点实现,优化后的高光模型通过修改部分代码或编辑器参数来实现。
总结:在UnityShader中,通过综合运用数学公式和编辑器工具,可以精确地模拟物体与光的交互过程,实现丰富多样的光照效果。这不仅为场景增添真实感,也是游戏和虚拟现实项目中不可或缺的技术。
UnityShader渲染纹理(Render Texture)应用(镜子、玻璃)
Unity为渲染目标纹理定义了专门的纹理类型——渲染纹理(Render Texture)。
使用渲染纹理通常的两种方式:镜子效果和玻璃效果。
在实现镜子效果中,首先创建一个相机(MirrorCamera),在Project窗口创建一个Render Texture,并将其赋值给MirrorCamera的Target Texture属性。然后在场景中创建一个四边形(Quad)作为镜子,并调整MirrorCamera的位置和裁剪平面视角参数,使渲染结果实时更新到Render Texture中。最后,通过Shader将Render Texture左右翻转展示在镜子上。
玻璃效果的实现需要定义GrabPass命令。在Shader中,使用切线空间下的法线方向,_Distortion属性和_RefractionTex_TexelSize对屏幕图像的采样坐标进行偏移,模拟折射效果。同时,注意物体的渲染队列设置,确保所有不透明物体都已被绘制在屏幕上。最后,通过透视触发得到正确的屏幕图像采样坐标,完成屏幕坐标的计算。
通过这种方式,可以在Unity中实现逼真的镜子和玻璃效果。通过对比,了解了两种方法的优缺点,玻璃效果需要额外小心物体的渲染队列设置,而镜子效果则更加直观。通过实践,可以更深入地理解Unity Shader渲染纹理的应用。
UnityShader 曲面细分着色器(Tessellation Shader)()
UnityShader曲面细分着色器(Tessellation Shader)详解()
在深入理解几何着色器后,曲面细分着色器(Tessellation Shader,简称TS)是另一个值得探索的领域。它利用GPU技术对网格中的三角形进行精细的细分,以提升模型表面的细节。TS并非独立的着色器,而是由壳着色器(HullShader)、域着色器(DomainShader)和镶嵌器阶段(Tessellation Stage)组成的一个概念。嵌套在这一过程中的常量外壳着色器(Constant Hull Shader)负责计算细分因子。
Hull Shader作为传递着色器,接收输入的控制点,并根据指定的参数,如细分模式(整数或非整数)、输出顶点数量等,输出控制点。控制点的设置决定了细分形状,就如同贝塞尔曲线中的控制点定义了曲线的形态。
Constant Hull Shader主要负责确定每个边的细分因子,影响细分后顶点的数量。细分因子的动态调整,如根据摄像机距离,是通过简单的归一化算法实现的,以实现LOD(层次细节)效果。
Domain Shader则是执行细分的阶段,计算细分后的顶点位置,并进行MVP变换。这个阶段的输出是新的顶点坐标,它们在原始网格的基础上进行了插值计算。
TS的执行流程在渲染管线中表现为:Vertex Shader -> Tessellation Shader -> Fragment Shader。在实际项目中,TS可以与几何着色器(GS)结合,增加更多的几何处理可能性。
虽然TS看似复杂,但理解和应用它有助于技术工具的掌握。通过HeightMap案例,我们可以看到TS如何在地形细节上发挥作用,但具体应用到实际项目中的细节仍需进一步学习和实践。
unityshaderforge和自带的shadergraph,有哪些优缺点?
Unity 的 Shader 图形化编程工具包括 shader forge 和 shader graph。尽管 shader forge 作为第三方插件较为老旧,不适应 Unity 的轻量级渲染管线和高清渲染管线等新特性,但 shader graph 成为了主流选择。
让我们深入探讨 shader graph 的优势与劣势。
优势之一在于可视化功能,简化了 shader 工具的操作流程。通过图形化拖拽,用户能快速预览 shader 效果,极大地提高了开发效率。
然而,对于初学者而言,仅仅依赖图形化工具可能难以真正掌握 shader 开发。初学者在掌握基础原理后,通过手动编写 shader,有助于深入理解其底层逻辑。之后,当项目需求或工作效率要求时,再适当结合 shader graph 工具。
值得注意的是,shader graph 自动生成的代码在性能方面可能并不理想,尤其是在 shader forge 中表现尤为明显。最终可能还需要手动检查生成的代码,以确保 shader 性能达到预期。
因此,从经验丰富的游戏开发者角度来看,手写 shader 是打下坚实基础的首选。在确保了基础知识的掌握后,再适时引入图形化的 shader 开发工具,如 shader graph,以提升开发效率和产出质量。