欢迎来到皮皮网网首页

【音乐留言源码】【localappstore源码】【ichart源码】unity shader源码

来源:高开不破均线源码 时间:2024-12-23 01:28:46

1.【UnityShader】3D拾取(PickBuffer)(19)
2.UnityShader 基础(29)-球面朝向映射(Matcap)-视角法线与平面反射
3.UnityShader 透明度混合(Alpha Blend)
4.unity urp源码学习一(渲染流程)
5.UnityShaderBillBoard(公告牌)原理和实现
6.UnityShader 基础(13)-高光渐变-Phong-Blinn高光与Shader分支

unity shader源码

【UnityShader】3D拾取(PickBuffer)(19)

       这篇文章讲述了如何在Unity URP 环境中使用PickBuffer技术实现3D场景中的鼠标拾取物体功能。首先,作者提到尽管射线检测常被提及,但通过渲染方式也能达成目标,这被称为PickBuffer。核心思想是音乐留言源码将每个渲染物体赋予一个唯一的ID,编码为颜色并渲染到RenderTexture上。

       具体步骤包括创建PickBufferManager来管理颜色与物体映射,将物体ID直接与颜色数组对应,然后在渲染时通过Input类处理鼠标事件。接下来,需要创建自定义的PickBufferRenderFeature和RenderPass,将PickBufferManager的数据渲染到RenderTexture中,同时保持深度信息的准确性。创建一个Shader用于处理颜色渲染,以及一个RenderTexture用于存放PickBuffer数据。

       在GPU Image回读阶段,通过Unity的接口读取RenderTexture,然后在PickBufferManager的Update函数中根据鼠标坐标获取目标物体的ID。通过在场景中添加辅助元素(如quad和标志物)进行调试,确保拾取功能正常工作。此外,文章还简要介绍了Unity原版描边功能的实现方法。

       性能优化部分,通过对比PickBuffer和射线检测的性能,发现GPU Image回读是一个性能瓶颈。为了解决这个问题,作者考虑了只回读单个像素而非整个,利用Compute Shader来实现这一目标。最终,通过Compute Shader将鼠标坐标映射到单个像素颜色,成功地减少了性能开销。

       总的来说,尽管Unity内置的PickBuffer功能可能在实际项目中并不常见,但它提供了一个学习和实践Unity渲染技术的好机会,鼓励读者在自己的渲染器中实现类似的功能。

UnityShader 基础()-球面朝向映射(Matcap)-视角法线与平面反射

       在Unity Shader中,有一种叫做Matcap的技术,它是一种快速模拟反射效果的便捷方法。Matcap源自于ZBrush,其原理是通过让物体表面的视角法线与Matcap球体表面的坐标方向对应,实现直观的反射效果展示。视角法线是一种特殊的法线,它依据摄像机视角定义,例如物体正面朝向正左时,视角法线的X值为1,正右则为-1,localappstore源码以此类推。

       在处理法线数据时,需要注意缩放可能带来的影响,通过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 透明度混合(Alpha Blend)

       透明度混合,即Alpha Blend,是Unity Shader中实现半透明效果的关键技术。其原理在于,利用当前片段的透明度值与已有颜色缓冲中的颜色进行混合,生成新的颜色值。值得注意的是,进行透明度混合时需要关闭深度写入,以确保正确渲染。在Unity Shader中,ichart源码通过Blend混合命令来实现这一功能。

       BlendOp命令决定了混合操作的类型,若未指定,则默认为Add操作。例如,使用传统透明度混合命令:

       上图与下方命令效果一致。通用混合公式为:finalValue = sourceFactor * sourceValue operation destinationFactor * destinationValue

       具体到Blend SrcAlpha OneMinusSrcAlpha命令,即:源Alpha通道与反Alpha通道进行混合。

       为了实现传统透明效果,需考虑关闭深度写入可能产生的错误渲染问题。解决方法是分两个Pass渲染模型:第一个Pass开启深度写入,但不输出颜色,仅记录深度值;第二个Pass执行正常透明度混合。此方案虽增加渲染开销,但确保了模型间的正确透明效果。

       使用ColorMask命令可控制颜色通道的写入,例如设置为ColorMask 0,表示该Pass不写入任何颜色通道,不输出颜色。

       若需观察正方体内部或背面形状,需使用Cull指令控制剔除面的渲染。在Unity中,Cull指令默认执行背面剔除(Cull Back)。通过将渲染分为两个Pass,分别渲染背面和正面,确保正确的深度关系,实现双面渲染。

       本文基于《Unity Shader入门精要》的学习笔记,加入了个人理解。如有错误,欢迎指正。

unity urp源码学习一(渲染流程)

       sprt的一些基础:

       绘制出物体的关键代码涉及设置shader标签(例如"LightMode" = "CustomLit"),以确保管线能够获取正确的shader并绘制物体。排序设置(sortingSettings)管理渲染顺序,如不透明物体从前至后排序,透明物体从后至前,以减少过绘制。逐物体数据的启用、动态合批和gpuinstance支持,以及主光源索引等配置均在此进行调整。

       过滤规则(filteringSettings)允许选择性绘制cullingResults中的几何体,依据RenderQueue和LayerMask等条件进行过滤。

       提交渲染命令是关键步骤,无论使用context还是commandbuffer,调用完毕后必须执行提交操作。例如,nanohttpd源码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,并按顺序提交渲染操作。

UnityShaderBillBoard(公告牌)原理和实现

       公告牌技术

       公告牌技术是基于视角确定纹理矩形朝向的一种图形处理方法。它广泛应用于实现诸如草、烟、火、雾、爆炸、云等特殊效果。这一技术的核心在于建立一个基于视角的坐标系,通过旋转物体来保持纹理矩形在特定方向上固定,从而模拟各种动态效果。

       公告牌原理

       在实现公告牌技术时,需要记录物体在物体空间的顶点相对于原点的各方向位移。利用相机位置确定视线方向,从而确定物体的法向量(与视线方向相反且平行)。通过指定一个向上向量重建新的坐标系,并将顶点在原坐标系的位移转移至新坐标系建立旋转后的顶点位置,完成在物体空间下的旋转。

       公告牌分类

       屏幕对齐的广告牌是最简单的一种形式,其图像总是平行于屏幕,具有恒定的向上向量。摄像机将物体投影到与远近平面平行的cabal源码视图平面上。在这种类型的广告牌中,物体表面的法线为视图平面法线的相反方向。通常用于粒子系统或总是面向屏幕的文本。

       Viewpoint-oriented广告牌则更为复杂。在这种情况下,向上的向量由相机本身的向上向量变为世界空间下的向上向量。通过与物体法向(与视线方向相反且平行)叉乘求得向右向量,最后使用物体法向与该向右向量叉乘求得物体最终准确的向上向量,完成新的坐标系的重建。这使得广告牌能够更好地模拟真实世界中的运动。

       公告牌实现

       在UnityShader中,实现公告牌技术可以通过编写特定的着色器代码来完成。参考《UnityShader入门精要(冯乐乐)》等资源,可以学习到具体的实现方法。在Unity中,物体的scale属性必须等比例缩放,且rotation属性全为0,才能确保广告牌达到预期效果。这确保了物体空间的向上向量与世界空间的向上向量同向平行。

       公告牌技巧

       虽然等比例缩放和旋转属性为0是推荐的做法,但也可以利用这些属性达到一些特殊效果,例如特定视角下的物体缩放。通过调整物体的scale属性在不同坐标轴上的比例,可以实现特定视角下物体形状的变化。这展示了公告牌技术的灵活性和多用途性。

UnityShader 基础()-高光渐变-Phong-Blinn高光与Shader分支

       本节将深入探讨UnityShader的基础,特别是关于高光渐变的两种实现方式:Phong高光模式与Blinn高光模式。首先,制作光照效果时,我们需要获取物体表面的法线向量,以及灯光方向与摄像机视角。

       为了规范化矢量,我们将使用`normalize()`函数。在高光计算过程中,Phong与Blinn两种模式各有特点。Phong高光模式中,我们通过`reflect()`函数求取反射向量,并翻转灯光方向,接着计算反射方向与视角方向的点乘,将其结果与数值1对应红色,-1对应蓝色,以便直观观察计算结果。

       而Blinn高光模式则提供了一种快速简化的方法。其核心在于将灯光与视角相加以获得高光方向,然后计算高光方向与表面法线之间的点乘,最终通过着色查看高光渐变的过程。

       在总结部分,我们发现Phong算法在准确性方面具有优势,而Blinn算法则在速度上表现更快。无论是Phong还是Blinn算法,都能依据摄像机与视角的不同,产生不同的高光效果。

       为了实现高光模式的灵活切换,可以使用Shader分支开关来控制Phong与Blinn高光模式的使用,需确保名称一致性。

       接下来,我们将深入高光的调整,通过`pow()`函数对渐变过程进行修改,调整`_specularRange`的数值可以控制高光范围的大小。同时,通过调整`_specularIntensity`参数,可以提高高光的亮度。为了实现卡通硬边高光效果,可以使用`step()`阈值函数将数据转换为0或1。

       最后,通过为高光添加`_specularColor`参数,我们可以为高光着色。将调整后的Shader代码与上一节的照明过程相加,即可实现高光与照明的混合效果。

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,用于最后将模板值还原

       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在相同参数情况下将获得同一个材质球。

如何更高效的学习和编写UnityShader(工具+收藏分享帖)

       分享一些高效编写Unity Shader的学习技巧和工具,希望能对大家有所帮助。以下工具与插件,均非与我有商业关系,不包含任何推广链接。

       工具与插件:

       1. 使用VScode + Shaderlab插件进行Shader编写。VScode快速且轻量,Shaderlab插件功能强大且持续更新。其引用查找功能极为便捷,如下图所示。

       2. 使用翻译插件,如彩云小译,实现网页翻译、文献翻译、在线翻译,具备双语对照功能,帮助理解晦涩词汇。同时,支持PDF云端翻译,功能虽不完美,但在某些场景下仍能使用。

       3. 推荐使用Github插件Sourcegraph,免费提供,用于查找引用和关键字,操作方便,效率高。

       4. 笔记类软件方面,原本使用有道,但mac版本的搜索功能不佳,后改为语雀,体验良好。对于有道笔记能否一键迁移至语雀,目前未找到解决方案。

       5. 使用taecg/ShaderReference工具,查询Shader语法大全,可联系作者请求新版本。

       6. JetBrains Rider是一款强大的编辑器,最新版本支持Shader跳转功能,可快速查找引用和文件,功能强大。

       白嫖圣地及学习资源:

       1. 在个人书签中分享各种资源链接,由于篇幅限制,已移至Git仓库。

       2. 探索其他白嫖资源,自行发掘和体验。

       3. killop的书签,是一个宝藏资源,收藏了大量总结文档,值得深入学习。

       持续更新中...

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如何在地形细节上发挥作用,但具体应用到实际项目中的细节仍需进一步学习和实践。

UnityShaderBlur 模糊(5)

       本节介绍模糊算法。模糊、边沿查找本质是一个滤波器,使用低通滤波/高通滤波来完成图像处理的目的。这些似乎涉及CV(计算机视觉)的研究范围,本文旨在展示如何在Unity中实现模糊效果,而非深入研究“信号与系统”的理论知识。做工程讲究实用性,能用即可。

       后续更新:在Unity中实现模糊算法的步骤。

       一、在Unity中的前期准备

       在上一节中,我们了解到如何在Unity URP中实现后处理效果。为了扩展PostProcessing相关组件(现在称为Volume),我们需要编写一个cs脚本,继承于VolumeComponent。Volume组件包含了常用的后处理特效,如Bloom(辉光)与ToneMapping(色调映射),可以显著提升画面效果。尽管Volume组件本身没有提供模糊功能,我们可以通过自定义实现。

       二、模糊算法实现

       虽然高斯模糊是模糊算法的代表,但还有其他方式,如方框模糊、径向模糊、双重模糊、Kawase模糊等。本节将实现其中几种自认为实用的模糊效果。

       1. 模糊的本质

       当我们感觉图像“模糊”时,实际上是因为像素点的颜色受到周围区域颜色的影响,使得像素点的“对比度”下降,颜色特征不鲜明。这种现象可以类比于人眼在远视状态下的视觉体验,物体反射的光线无法聚焦在视网膜上,形成多个“重影”,增加了模糊感。在图像处理中,模糊算法通过“污染”像素点的颜色,达到“模糊”效果。

       2. Kawase Blur

       Kawase模糊采用动态卷积核来提升效率,不同于高斯模糊或方框模糊中的恒定卷积核。其核心思路是对距离当前像素较远的位置进行采样,并在两个大小相等的纹理之间进行乒乓式的blit操作。通过随迭代次数移动的blur kernel,实现更加灵活且高效的模糊效果。

       3. Dual Blur

       双重模糊通过降采样和升采样过程实现,即在blit过程中进行图像大小的调整。相比于Kawase模糊,双重模糊在实现上更加复杂,但能提供不同场景下的模糊效果。

       4. Radial Blur

       为了在图像中产生“速度感”和“打击感”,径向模糊是最常用的技术。通过在指定方向上进行模糊处理,可以模拟出物体移动或光线照射的效果。实现径向模糊时,需要调整纹理和采样方向,以达到预期的视觉效果。

       小结

       通过上述方法,我们能够在Unity URP中实现常见的模糊算法。在实际应用中,可以根据需求选择最合适的模糊类型,例如,Kawase模糊在性能和效果上通常被认为是一个不错的选择。模糊算法在后处理中有着广泛的应用,如体积光处理,能够有效提升场景的视觉效果。