大家好! 我叫Grigory Dyadichenko,是Foxsys Studios的创始人兼CTO。 今天,我想谈谈着色器。 如果要实现出色的图形效果,则在为移动平台或AR / VR开发时,编写着色器(通常与渲染一起使用)的能力非常重要。 许多开发人员认为着色器是魔术。 关于它们的信息很少,要编写它们,您至少需要拥有科学候选人的头衔。 是的,根据其原理进行着色器的开发与客户开发有很大不同。 但是最主要的是要了解着色器的基本原理,并了解其本质,因此没有神奇的事物,并且搜索有关此主题的信息是一项简单的任务。 本系列文章仅供初学者使用,因此,如果您擅长对着色器进行编程,那么本系列对您来说不会很有趣。 任何想了解此主题的人-欢迎参加!

这是一篇介绍性文章,其中我将描述编写着色器的一般原理。 如果主题很有趣,那么我们将在单独的文章中进行更详细的分析:顶点着色器,几何着色器,片段/像素着色器,三边形着色器,屏幕空间效果和计算机着色器(OpenCL,CUDA等)。 通常,所有可以在GPU上完成的魔术。 这将在Unity标准管道的上下文中进行整理。 因此,到目前为止,LWRP和HDRP对我来说似乎有些潮湿。
什么是着色器?
资料来源: www.shadertoy.com/view/MsGSRd实际上,这是在GPU上运行的程序,其输出是不同的信息。 在顶点着色器中,这些是网格顶点的参数。 像素着色器逐像素执行。
要了解着色器的工作原理,您需要知道什么是图形管线。 人们经常用相当复杂的语言谈论这个话题,但是我们会让它更容易理解。 以OpenGL为例。 在这方面,我真的很喜欢这张照片。

如果省略与照明等有关的零件。 通常,从在hlsl上编写相同的Unlit着色器的角度出发,其实质如下。 我们有一个着色器
#pragma vertex vert #pragma fragment frag
我们确定着色器的顶点部分将写入vert函数,而片段部分将写入frag函数。
我们在着色器中描述的结构确定了从网格中获取的数据,以及使用悬挂在MeshRenderer和MeshFilter对象上的顶点着色器进行处理后的数据。
struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; };
接下来,顶点着色器通过接收appdata数据作为输入进行计算,并以v2f结构的形式给出结果,然后将其转到片段着色器。 依次将已经计算出像素的颜色。 由于v2f信息仅写入顶点(小于像素),因此对片段部分中的数据进行插值。 所有这些都可以表示为在每个顶点中独立考虑vert的事实。 然后将结果传输到片段部分,其中每个像素的碎片被视为独立的。 由于计算是并行进行的,因此在这些部分中,没有关于邻居的信息(如果您不以某种方式巧妙地传输它)。
更详细地讲,Unity
docs.unity3d.com/Manual/SL-Reference.html文档中描述了所有细微差别以及许多示例。
着色器编程语言
资料来源: www.shadertoy.com/view/WsS3Dc还有重要的是不要忘记。 现在,着色器是用三种与统一性无关的编程语言编写的。 CG,GLSL和HLSL。 在单元中编写着色器的最简单方法是通过HLSL,因为它是写入具有.shader权限的着色器文件的位置。 而且,如果在一个单元的上下文中关于着色器的信息相对较少,那么关于HLSL,GLSL和CG的单独信息就是很多。 着色器的文档描述了如何将用这些语言编写的内容传输到Unity。 因此,事实证明,几乎所有有关这些编程语言的信息都是有效的。 三种语言都与C非常相似,但是每种都有自己的特点。
此外,从研究着色器的角度来看,当这些语言不再引起问题时,您可以看到“ UnityCG.cginc”和其他由unity编写的库本身提供了哪些机会来简化其工作。
为什么在着色器中不好?
资料来源: www.shadertoy.com/view/Md3cWr重要的是要了解着色器是如何在Iron级别执行的,以及为什么着色器如此之快以至于它们可以执行数百万次操作而不会造成负担。
GPU的主要思想是计算的最大并行度。 在这里有必要引入诸如“波前”的概念。 实际上,这很简单,波前是一组执行相同操作序列的着色器。 也就是说,从GPU的角度来看,最好的选择是同时执行相同的指令。 执行上的唯一区别是输入。 分支的问题是,在单个着色器组中,着色器必须调用不同的操作时,可能会发生这种情况。 反过来导致创建新的波前,将数据复制到其中,等等。 而且非常昂贵。
有细微差别和例外,但是为了安全地编写if,您必须了解它在图形api的目标版本上的行为。 由于相同的OpenGL ES 2或DX11在这方面有很大的不同。
为什么要知道这一点,因为有节点编辑器?

重要的是要了解节点编辑器主要是技术艺术家的工具。 这些是在数学方面具有专长的专家,但设计师更多。 像许多物理材料的数学模型一样,使用线框类型的着色器(需要了解重心坐标)或将其转换为用于棘手投影的笛卡尔坐标,更容易使用代码完成。 同时,从着色器程序员的角度来看,您实际上是为技术人员创建了自定义节点和工具,以创造真正的魔力。 从这个角度来看,节点编辑器的功能有限。 因此,能够使用hlsl之类的语言编写着色器很重要。 了解渲染的工作原理等。
有用的学习资源
资料来源: www.shadertoy.com/view/4tlcWj在学习着色器编程方面,一个很好的练习是从
www.shadertoy.com或
glslsandbox.com重写着色器。 此外,还有来自Unity的专家的
出色介绍 ,您可以在其中看到很多有趣的
github.com/keijiro其他所有内容都是数学和对效果物理的理解。 如果没有解决物理建模的特定问题,则这有点类似于混合成分。 通过混合噪声,折射,光的地下散射,苛性碱,菲涅耳效应,扩散反应和物体的其他物理特性,可以完成很多有趣的事情。 通常,着色器编程当然不是基础知识,并且有需要深入研究的地方。
如果着色器主题很有趣,那么我将尝试发布有关该主题的一系列文章,其中已经包含有关创建不同效果的主题的特定示例和教程。 在评论中建议您要阅读的内容和学习的主题。 感谢您的关注!
本文中的所有效果都记录了带有shadertoy的着色器效果。