1.UE4学习笔记 使用插件添加一个ShadingModel
2.ShaderToy系列:零
3.像素着色器(Pixel Shader)是屏幕什么 是硬件还是软件
4.Re:从零开始的UE渲染学习-4Shader与材质
5.unity urp源码学习一(渲染流程)
6.UGUI源码阅读之Mask
UE4学习笔记 使用插件添加一个ShadingModel
此文章借鉴了以下三篇文章,在此对分享者表示感谢。源码
1. [UE4]插件添加ShadingModel
2. Ue4 使用MaterialCustomOutput自定义ShadingModel
3. UE4(虚幻)学习笔记--虚幻4.自定义shadermodel
在学习UE4渲染管线过程中,屏幕发现添加ShadingModel时,源码通常需要修改源码版引擎的屏幕源码。本文介绍一种无需修改引擎源码的源码源码红杉方式,添加自定义ShadingModel,屏幕并定制延迟渲染的源码光照计算。
第一篇文章已详细介绍了修改思路,屏幕本文重点记录插件创建与添加模块的源码步骤。
以4..2版本为例,屏幕首先新建一个插件,源码模板选择Blank。屏幕新建完成后,源码打开plugins所在位置,屏幕进入source文件夹。
将ToonShader文件夹复制一份,改名为ToonShaderBootstarp,并将ToonShaderBootstarp文件夹中的ToonShader全部改成ToonShaderBootstarp(包括文件名与其中变量名)。
注意:在ToonShaderBootstrap.Build.cs文件中,需要在PrivateDependencyModuleNames.AddRange中加入"Projects","DeveloperSettings",否则在之后的修改和编译中会产生错误。
之后在插件根目录中的ToonShader.uplugin中添加该模块,然后重新生成sln,该模块就添加完成了。
编译成功后,将ToonShader.uplugin中ToonShaderBootstarp模块的Type改为"UncookedOnly",LoadingPhase改为"EarliestPossible",否则会报关联不上插件源码的错误。
编译成功后,进入引擎,新建C++ Class,选择MaterialExpressionCustomOutput类,再新建一个Class,选择developerSettings类。
接下来修改ToonShaderOutput.h与ToonShaderOutput.cpp,编译通过后,继续修改ToonShaderBootstarp.cpp。
修改ToonShaderBootstrapSettings.h,增加插件的启动和关闭参数,然后修改配置文件的方法和正常修改源码添加ShadingModel的方法相似。
插件成功加载后,可以在Material里面看见ToonShader节点。突破的公式源码
自定义ShadingModel添加完成。
总结:
1. ToonShader模块实现了UMaterialExpressionCustomOutput的子类,为运行时模块。
2. ToonShaderBootstrap模块在引擎启动Shader编译前加载,用以向虚幻引擎Shader文件夹中替换默认Shader文件。
ShadersOverride文件夹下存放了shader文件,Default文件用来恢复,Override用来做替换,新增的Shader文件都需要存放在Toon目录下。
本文记录了在UE4中踩的坑,希望对大家有所帮助。
ShaderToy系列:零
ShaderToy是一个展示创意和效果的平台,其中的作品通常基于片断着色器,形式丰富、风格独特。这些作品的源代码公开,为学习者提供了直接研究和借鉴的机会。本系列文章旨在将ShaderToy上的效果移植到Unity环境中,通过这一过程深入理解Shader思维与代码编写技巧。
为了在Unity中展示ShaderToy效果,我们将采用后处理技术,利用`OnRenderImage`方法。这个内置方法在所有渲染步骤完成后执行,常用于实现屏幕后处理特效。`OnRenderImage`方法接收两个`RenderTexture`参数,分别表示当前帧渲染的图像和最终渲染处理后的图像。通过`Graphs.Blit`函数处理当前画面,结合特定的Shader进行渲染,最终将结果呈现于屏幕上。
在本系列中,我们不关心当前帧的原始渲染面片,仅关注将Shader效果展示到屏幕上。这意味着在`Graphs.Blit`中,源可以指定为`null`。移植过程涉及编写Shader代码,以实现特定效果。以ShaderToy中的默认背景效果为例,这是一个基础的顶点片断着色器,通过简单的计算实现目标效果。
片断着色器中的核心语句返回的是一个四维向量,对应为`finalCol`,其值最终设定为`float4(col,虚拟键盘 源码 html1.0)`,表示颜色RGB的值为`col`,Alpha值为1。这表明片段最终返回的是`col`的值。进一步分析`col`的构成,可以发现其是一个三维向量,通过将其分解为R通道进行观察,便于理解其表现效果。最终,三个通道的组合实现了初始效果。
在解读他人Shader代码时,建议从下向上进行,这样有助于理解实现方法。关注代码逻辑和结构,理解其如何协同工作实现特定效果。通过详细分析,我们可以学习并掌握Shader中的各种操作和技巧,如颜色操作、纹理映射、光照计算等。
本系列文章侧重于通过ShaderToy实例分析学习Shader语法和技巧,对于GLSL编程细节不做过多讨论,而是关注于其在Unity环境中的操作表现和应用。对于在编写过程中遇到的疑问,初学者可以参考提供的源文件或加入QQ交流群获取帮助。欢迎关注公众号“Unity技术美术”获取更多技术干货。
像素着色器(Pixel Shader)是什么 是硬件还是软件
什么是像素着色器?
1 像素着色器也是一组指令,这组指令在顶点中像素被渲染时执行。在每个执行时间,都会有很多像素被渲染。(像素的数目依靠屏幕的分辨率决定)
2像素着色器的指令和顶点着色器的指令非常接近。像素着色器不能像顶点着色器那样,单独存在。他们在运行的时候,必须有一个顶点着色器被激活。
为什么大家要使用像素着色器?
1 像素着色器过去是一种高级图形技术,专门用来提高渲染速度。
2 和顶点着色器一样,使用像素着色器,程序员能自定义渲染每个像素。
像素着色器如何运作?
一个像素着色器操作顶点上单独的像素。和顶点着色器一样,像素着色器源代码也是ios注册登录 源码通过一些API加载到硬件的。
Re:从零开始的UE渲染学习-4Shader与材质
通过前面的学习,我们知道在UE中渲染网格时需要指定一个shader。本文将深入讲解UE的Shader、材质系统以及它们之间的关联。所涉及的源码版本为UE5.3,所有配图已上传至Github,便于查看高清图。
顶点工厂的作用在于处理模型网格上的顶点信息,如位置、法线、UV等,UE通过顶点工厂使shader能够直接获取所需顶点数据,这简化了自定义网格信息的解释工作。
Shader是控制渲染物体在屏幕上的关键,通常需要指定VertexShader和PixelShader。在编写shader时,需要遵循特定的编程语言和标准,例如DirectX使用HLSL,OpenGL使用GLSL。UE通过一套规范来管理shader体系,最后将shader编译到支持的平台上。
Shader类是shader文件与实际渲染系统之间的桥梁。UE中有三种主要的shader类,分别针对材质编辑器的使用情况和顶点工厂类型。Shader实现主要依赖RDG提供的宏和函数,如声明宏、用于对着色器参数表达的宏等,以及为着色器类型声明必要的数据和函数的宏,实现将shader文件与shader类绑定。
材质系统是UE中用于定义物体属性的界面,包括质感、颜色、透明度等。shader提供材质属性的计算方式,而材质则通过指定shader来实现这些计算。UE的材质编辑器允许用户通过直观的操作设置材质属性,这些属性最终被转化为HLSL函数,由shader调用以计算光照效果。
在渲染过程中,材质、shader和顶点工厂紧密关联,形成渲染流程。nginx源码事件模块UE会根据材质所使用的shader类型和顶点工厂类型编译出特定的组合结果,存储在材质的ShaderMap中。当使用BuildMeshDrawCommands()时,传入的shader是针对特定pass的完整shader。
材质类涉及游戏线程、代理和渲染线程相关的类,与材质蓝图的关联主要体现在UMaterialGraph上,它用于存储和管理材质节点和参数。UMaterialExpression管理节点的表达式,包括节点输入、名称和编译逻辑。拓展材质节点通常需要继承UMaterialExpression并实现相关函数,尤其是Compile()函数,直接决定节点如何被编译。
在进行材质编译时,UE首先翻译材质蓝图到HLSL代码,然后根据不同的组合进行编译,并存储到ShaderMap中。编译过程涉及环境设置,这影响宏的使用,进而影响shader效果。在将材质蓝图翻译到HLSL时,UE使用不同的翻译帮助函数,如FHLSLMaterialTranslator。
总的来说,Shader与材质是UE中不可或缺的部分,它们共同决定了物体如何在屏幕上呈现。本文介绍了UE中Shader和材质的基本概念、关联方式以及编译流程,同时也简要提及了自定义Shader和拓展材质节点的方法。
unity urp源码学习一(渲染流程)
sprt的一些基础:
绘制出物体的关键代码涉及设置shader标签(例如"LightMode" = "CustomLit"),以确保管线能够获取正确的shader并绘制物体。排序设置(sortingSettings)管理渲染顺序,如不透明物体从前至后排序,透明物体从后至前,以减少过绘制。逐物体数据的启用、动态合批和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,并按顺序提交渲染操作。
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在相同参数情况下将获得同一个材质球。
Shader内实现四叉树压缩贴图
四叉树在Shader中实现压缩贴图的效率和效果令人印象深刻。通过使用x像素(实际可压缩)的RGBAFLOAT格式,可以实现高质量的静态阴影,即使是大型场景或需要极高精度的场景,也能显著减少对实时shadowmap的频繁绘制调用,节省资源。
尽管实际项目中通常采用八叉树进行体积阴影,但理解四叉树的实现方式有助于建立清晰的思路。开始时,作者从二叉树扩展到四叉树,但尝试过程中遇到了代码合并的困难,导致数据冗余。经过调整,作者采用均匀四叉树结构,其中每个节点包含x、z坐标、区域大小、子节点信息和flag状态,以表示阴影区域。
关键部分在于节点的创建和插入函数,确保节点是完满四叉树,以便通过偏移计算子节点索引。当节点大小减小到1时,表示达到最小细化级别,flag设置为1。绘制函数则递归地在阴影内绘制红色,外部绘制绿色,避免重复绘制。在合并节点时,通过检查子节点的flag值,可以有效减少重复数据。
Shader部分的解析相对简单,通过两个pass绘制屏幕阴影和主相机混合。在写入图形时,根据世界坐标和节点位置,使用flag来判断并确定查找的下一层节点。源码的详细部分在最后部分提供。
Cocos Creator 3.x 开发2D水面波纹Shader
使用 cocos Creator 3.8 开发 2D 水面波纹 Shader 的过程和相关技术点总结如下:
2D 波浪基本原理:给定正选波边界,范围内的片元 uv 显示,范围外的片元 uv 不显示。利用正弦波表达式:y = A * sin(w * t + offset)。将片元的 uv 坐标 uv.x 带入公式计算 y0 值。Cocos 的 uv 左上角为 (0, 0),在上方做水波纹,片元的 uv.y y0 的片元丢弃,uv.y >= y0 的片元正常显示。
实现动态水波:不断改变相同位置的 offset,得到不同的 y0 值,决定不同片元的显示和丢弃,使水波动起来。
编写 Shader 步骤:
第步:新建标准 2D Shader 模板,正常显示。复制 buildin-sprite Shader 模板,创建材质并设置到 Sprite 组件上。
第步:定义控制参数:baseLine、振幅 A、角速度 wSpeed。
第步:修改 Fragment 着色代码,实现基准线功能。基准线以上的片元丢弃,基准线以下的片元保留。
第步:将基准线加上正弦波处理,offset 为 uv.x,值为 A * sin(offset),将 baseLine 转换为正弦波分界线。
第步:让正弦波动起来。在 sin 表达式中加上 w*t,其中 cc_time.x 为从启动后到现在的累计时间,随时间变化,value = A * sin(uv.x * .0 + wSpeed * cc_time.x),实现波形周期变化。
完整 Shader 代码:在 cocos Creator 3.8.0 中编写。
欲获取项目工程源码和更多教学视频,请关注我们。
笔记UE5 Shader 调试工具 - Microsoft PIX
为了有效地调试使用DX的着色器,开发者通常需要一个高效且可靠的工具,微软的PIX调试工具就是这样一个理想的选择。与RenderDoc相比,PIX能够提供更全面、准确的调试信息,具体包括:
- 强大的性能分析和回放功能
- 显示着色器符号,方便调试源代码
- 精确的渲染时间duration值
在开始之前,需要确保你的渲染引擎使用的是DX RHI(渲染硬件接口),这是成功使用PIX的基础。为了避免插件冲突导致的崩溃,必须先禁用RenderDoc插件,确保PIX插件被正确配置。
在配置文件ConsoleVariables.ini中,调整Shader编译相关设置,为接入PIX打下良好的基础。
按下PrintScreen或F键进行截帧操作,观察系统提示完成截图。在不同系统下,可能需要调整快捷键以避免与系统功能冲突。
利用PIX附着到Unreal的进程,同时开启Analysis模式,确保进行开发者模式设置,以获取详尽的调试信息。
在打开的游戏或编辑器中,截帧后进行分析,选择需要调试的DrawCall和具体Shader资源,以深入了解渲染管线的工作过程。深色主题的视觉体验虽然酷炫,但在读取代码时可能不够清晰,因此,调整主题到更利于阅读的白底配色。
记得检查在编译设置中已启用Shader符号信息,以获取额外的调试支持。当启用Shader符号信息时,确保编译选项中不包含某些不必要的优化标志。
Pix目前不支持调试DX或Vulkan,但这并不意味着它不是一个强大的调试工具,其在DX上的功能强大且实用。
最后,深入理解和应用DirectX 管道中的关键概念,如Pipeline State、Root Signature、Input Assembler、Vertex Shader和Pixel Shader以及Output Merger,对优化和调试有着重要影响。它们共同构成了渲染流程的核心,理解它们将帮助你在开发过程中更加得心应手。
要深入使用这些知识和工具,参考微软官方文档和教程,比如微软的GPU捕获、Pix下载指南、如何将开发者设备配置为启用Pix、如何职业游戏开发者使用Pix提高在Xbox和Windows上的游戏质量等相关文章。
这便是PIX为DirectX 着色器调试提供的全面支持和深究其功能以优化性能的过程概览,希望对你的开发旅程有所帮助。