Shader和渲染管线

什么是Shader

Shader,中文翻译即着色器,是一种较为短小的程序片段,用于告诉图形硬件如何计算和输出图像,过去由汇编语言来编写,现在也可以使用高级语言来编写。一句话概括:

  • Shader是可编程图形管线的算法片段。

它主要可以分成以下两类:

  • Vertex Shader
  • Fragment Shader

什么是渲染管线

渲染管线也称为渲染流水线,是显示芯片内部处理图形信号相互独立的并行处理单元。一个流水线是一序列可以并行和按照固定顺序进行的阶段。就像一个在同一时间内,不同阶段不同的汽车一起制造的装配线,传统的图形硬件流水线以流水的方式处理大量的顶点、几何图元和片段。

注意理解的是这里有一个前后关系,前一个阶段的输入会到后一个阶段去输出。比如在顶点程序当中,顶点程序计算的数据就会作为片段程序再进一步加工的材料。

为了更形象地理解渲染管线:
在这里插入图片描述
最上面的是:

  • 【3D应用或者游戏】
    3D应用或者游戏会直接调用 【3D应用接口】,也就是OpenGL或者DirectX等。OpenGL和DirectX是方便应用程序去进行硬件访问和调用的中间层。如果没有他们,我们就需要为硬件去编写一个非常复杂的专门针对硬件的驱动程序。

再往下,则是:

  • 【CPU和GPU的分界线】
    在此之上都是CPU的操作,一下进行GPU的运算。

GPU的运算是 从左往右进行的,最开始是 【GPU前段模块】【图元装配】 这中间如果在过去T&L流水线的过程当中是由硬件设计好的运算过程,也就是集成的,它不能够进行编程控制。

当图形硬件有了可编程能力之后,我们就可以在这个阶段使用 【顶点着色器】 进行编写运算逻辑,用于取代过于直接集成在硬件中的运算。在这个阶段完成之后,会到**【光栅化以及插值】**阶段。

光栅化就是把计算机显卡当中运算的数据进行一个细分,用于去适配屏幕上具体的每一个像素的显示,但是光栅化并不等同于像素显示,像素显示最终反映的是颜色,而光栅化过后得到的结果是 【帧缓存】,在这个过程当中,我们可以插入 【片段着色器】,这个部分就可以使用可编程化运算。所以 【片段着色器】 的目标是为屏幕上最终要显示的每一个像素去计算它最后需要什么样的颜色。

对于Unity而言,上面的流程可以由下面的图表示:
在这里插入图片描述
最上面 【Geometry】 是几何模型,几何模型进入 【Unity】,可以理解为把几何模型Mesh、网格等数据交给Unity,Unity导入后就通过Unity引擎去调用 【Grphics APU】 图形API,调用图形API的过程就是在驱动GPU进行处理运算。

进入GPU运算首先进行的是 【Vertex Processor】 顶点处理器,这个部分就需要我们使用 【Vertex Shader】 顶点着色器,顶点着色器运算的结果会交给 【Pixel Processor】 像素处理器,也就是片段处理器,在这个部分我需要为像素处理编写 【Pixel Shader】 像素着色器程序,这部分计算完后就输出了最终我们可以用于在屏幕上的颜色信息,我们把它叫做 【Frame Buffer】 帧缓冲。帧缓冲存储的是计算机依次显示所要的数据,但也不仅仅是这些数据,它还有其他的附加信息,比如深度值等。

下面是Unity官方手册中的一张渲染管线图示在这里插入图片描述
渲染管道线中最左边的这个部分中Transform指的是模型的空间变换,主要针对的是顶点的空间几何变换;TexGen即Texture Generator,表示的是纹理坐标的生成,主要用于在顶点当中去取得纹理坐标,再转换为UV取值的范围;Lighting指的是光照。因此这个部分就是过去就是T&L几何变换光照流水线,当图形硬件具有了可编程能力后,这个固定的模块就被 【Vertex Shader】 顶点着色器代替了。

在顶点着色器处理过后,Unity就进入 【Culling & Depth Test】 裁剪和深度测试过程。裁剪和深度测试描述的是如果一个物体在摄像机前展示,它向着摄像机的面会被观察到,它背对着摄像机的面不会被观察到,在这样的情况下,为了减少GPU处理数据量就进行了一个裁剪(Culling),把看不见的面直接剔除,不需要去处理的这些面所涉及的顶点数据,从而加速图形处理。第二个方面深度测试(Depth Test),指的是摄像机有一个特性,在计算机当中没有无限这个概念,计算机处理的数据都是离散化的,它有一个范围,当超过最近和最远这个范围的这部分会被剔除。

接下来就进入到纹理采样(Texturing)和雾化处理(Fog)阶段。在这阶段实际上就是在进行光栅化处理,描述的就是如何在屏幕上显示每一个像素的颜色。这里需要去纹理采样,一张贴图有很多数据,我们去采集纹理上某一点的颜色值,这个就叫做纹理采样。雾化就是根据最后计算的数据后需不需要进行一个雾化处理,近处的很清晰,远处的有种朦胧感,这个部分就是片段着色器可编程的能力范围。

之后还需要 【Alpha Test】,指的是去绘制那些半透明的或全透明的物体。经过【Alpha Test】之后还需要进行 【Blending】 处理,这阶段会混合最终的图像。

以上介绍的是渲染管线的流程,要把握的主要的过程就是我们可编程能力是两个部分,一个就是几何变换和光照使用的顶点着色器部分,另一个就是关于如何去采样,去计算颜色以及雾化处理等使用的片段着色器部分。

这里需要注意的是Unity优化当中有一个主要部分就是减少Draw Call的调用,Draw Call就指的是应用程序去调用图形硬件GPU去进行渲染的调度过程。应用程序需要准备很多的数据,包括顶点数据、矩阵、向量等数据,都需要通过应用程序传递给GPU,这样个调度过程CPU必须要去收集数据以后才产生一个API的调用,这个过程的消耗是高昂的,如果反复地启动这个调用,那么就仅仅收集和传递参数这样的过程相当耗时耗力,就会造成了应用程序或游戏运行的瓶颈。因此要尽量减少Draw Call,尽量减少CPU对GPU这样的调用。

Shader和材质、贴图的关系

Shader(着色器)实际上就是一小段程序,它负责将输入的顶点数据以指定的方式和输入的贴图或者颜色等组合起来,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质),之后,我们便可以将材质赋予三维物体来进行渲染(输出)了。

材质好比引擎最终使用的商品,Shader好比是生产这种商品的加工方法,而贴图就是原材料。

小结

  • Shader是图形可编程方案的程序片段。主要分为顶点着色器和片段着色器。

  • 渲染管线是一种计算机从数据到最终图形成像的形象描述。

  • 材质可以理解为商品,Shader是加工这种商品的方法,而贴图是加工过程中需要的材料。

参考文章:
shader和渲染管线

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以为您提供一个基本的Unity URP渲染管线镜面Shader示例。这个Shader将为物体表面创建一个镜面反射效果。 首先,您需要在Unity中创建一个新的URP项目。然后,您可以创建一个新的Shader文件并将以下代码添加到其中: ```csharp Shader "Custom/URP Mirror" { Properties { _Color ("Color", Color) = (1, 1, 1, 1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Metallic ("Metallic", Range(0, 1)) = 0.5 _Smoothness ("Smoothness", Range(0, 1)) = 0.5 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Standard fullforwardshadows #include "UnityCG.cginc" struct Input { float2 uv_MainTex; }; sampler2D _MainTex; fixed4 _Color; float _Metallic; float _Smoothness; void surf (Input IN, inout SurfaceOutputStandard o) { fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Metallic = _Metallic; o.Smoothness = _Smoothness; o.Alpha = c.a; o.Specular = 1; // 启用高光 o.Specular *= c.a; // 根据纹理透明度调整高光强度 } ENDCG } FallBack "Diffuse" } ``` 这个示例中的Shader使用了标准的SurfaceOutputStandard结构,以便与Unity URP渲染管线兼容。它具有_Color(颜色)、_MainTex(主纹理)、_Metallic(金属度)和_Smoothness(光滑度)属性,您可以在材质面板中调整它们。 Shader中的surf函数定义了如何计算表面输出。在这个例子中,我们首先从_MainTex纹理中采样颜色,并将其乘以_Color属性。然后,我们将乘以纹理透明度后的结果设置为表面的漫反射颜色(o.Albedo)。_Metallic和_Smoothness属性用于设置金属度和光滑度。 在这个示例中,我们还启用了高光(o.Specular),并根据纹理透明度调整了高光强度。 最后,请将此Shader文件保存,并将其应用于您想要添加镜面反射效果的物体上。您可以通过创建一个新材质,然后将其Shader属性设置为您创建的Shader来实现这一点。 希望这可以帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值