《Unity Shader入门精要》笔记:基础篇(1)

  3.2 游戏引擎技术
  • 本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载。
  • 在大部分书籍中总会有一些通病,作者总会下意识或者想当然的以为读者会对一些专有名词有详尽的了解,实则不然。例如本书开篇就提到的片元,采样,插值。那么这些词的含义如果不去百度那么只能通过上下文去猜测(恼)。
    因此本篇博客会补充一些扩展内容(例如其他博客链接)
  • 篇博客还会提供一些边读边做的效果截图。文章内所有数学公式都由Latex在线编辑器生成。
  • 篇博客主要提供一个“glance”,知识点的总结。如有需要请到书店购买正版。
  • 在阅读本篇之前你可能需要掌握以下知识点
    1、Unity的入门级编写经验,使用Unity学习完成过几个小游戏的制作。
    2、高数知识点(线性代数、微积分),了解概念即可,无需推导计算。
    3、图形学基础知识
  • 博客提及所有官方文档基于2022.2版本,博客会更新一些书中的旧的知识点到2022.2版本。
  • 如有不对之处欢迎指正。
  • 我创建了一个游戏制作交流群:637959304 进群密码:(CSGO的拆包密码)欢迎各位大佬一起学习交流,不限于任何平台(U3D、UE、COCO2dx、GamesMaker等),以及欢迎编程,美术,音乐等游戏相关的任何人员一起进群学习交流。

渲染流水线

  • (本篇部分内容在HLSL的笔记中也有所提及)
  • 什么是渲染流水线传送门
  • CPU和GPU之间的通信:1、把数据加载到显存中 2、设置渲染状态 3、调用Draw Call
  • GPU流水线:(这个部分在HLSL文章第一篇中有详尽的描述)
    顶点数据->
    (几何阶段)顶点着色器->曲面细分着色器->几何着色器->裁剪->屏幕映射->
    (光栅化阶段)三角形设置->三角形遍历->片元着色器->逐片元操作->
    屏幕图像
  • 几何阶段主要解决坐标转换问题,光栅化阶段朱亚奥解决图元覆盖哪些像素,以及颜色计算问题。
  • 顶点着色器(Vertex Shader):坐标变换(模型空间坐标到齐次裁剪坐标)和逐顶点光照计算。
image 94 - 《Unity Shader入门精要》笔记:基础篇(1)
image 93 1024x79 - 《Unity Shader入门精要》笔记:基础篇(1)

小插曲:看到具体数学冷汗直冒,细一看,嗷不是那本书呀。《具体数学》:别听《Unity Shader入门精要》里面说什么程序员的三大浪漫,真程序员就该手撕《具体数学》!

  • 裁剪:裁剪不出现在摄像机视野内的像素。
  • 屏幕映射(Screen Mapping):图元坐标中的x,y转换为屏幕坐标系,z轴不进行处理。
  • 三角形设置(Triangle Setup):计算三角网格所需信息。
  • 三角形遍历(Triangle Traversal):检查每个像素是否被一个三角网格覆盖,如果覆盖则生成片元(fragment),该阶段也称之为扫描变换(Scan Conversion)。
    片元:片元是光栅化过程的产物;光栅化是将一个图元转变为一个二维图象,二维图象上每个点都包含了颜色、深度和纹理数据,将该点和相关信息叫做一个片元;片元和像素等价,但它比像素多了其它信息,如位置,法线,颜色,纹理坐标等。
  • 片元着色器(Fragment Shader):可编程着色阶段。
    插值传送门
  • 逐片元操作:1、决定每个片元的可见性,2、如果一个片元通过所有测试,则需要把该片元颜色值和存储在颜色缓冲区的颜色进行合并。(测试、混合部分可进行高自由度的编写)
    片元->模板测试->深度测试->混合->颜色缓冲区。(模板测试可以用于渲染阴影,轮廓等)
  • 经过上述操作后,图像最终显示在屏幕上。屏幕显示为颜色缓冲区中的颜色值,为了避免被看到正在进行光栅化的图元,GPU会使用双重缓冲(Double Buffering)策略
    双重缓冲:对场景的渲染在后置缓冲(Back Buffer)中进行。等到渲染完成后GPU会交换后置缓冲区和前置缓冲(Front Buffer)中的内容。前置缓冲就是显示在屏幕上的图像。

额外补充

  • OpenGl/DirectX:两者都为图像应用编程借口,用于渲染图像。OpenGL是由多个公司创建的,DirectX由微软创建。
  • HLSL、GLSL、CG:着色器语言。(HLSL教程就陈列在博主的博客中)
  • Draw Call:CPU调用图像编程接口。
  • 固定管线渲染:在较旧的GPU上实现的渲染流水线。这种流水线只给开发者提供配置操作。

Unity Shader基础

  • Unity中Shader需要配合材质(Material)和Unity Shader一起使用,流程
    1、创建材质,Unity Shader
    2、把Unity Shader挂载到材质
    3、把材质挂载到游戏中的物体(一般会把贴图挂载到材质上)
    4、在材质面板调整Unity Shader
  • Unity中的材质:Unity才只需要结合GameObject(游戏中物体)的Mesh或者Particle System(粒子系统)组件来工作。具体操作如下图所示。
  • Tip:Unity Shader和渲染管线中的Shader有很大区别,在阅读时请区分两者,具体内容会在之后表述。
image 96 1024x580 - 《Unity Shader入门精要》笔记:基础篇(1)
面板
image 97 - 《Unity Shader入门精要》笔记:基础篇(1)
结果示例
  • 创建Unity Shader:Stand Surface Shader。
  • 其中,
    1、Stand Surface Shader:产生包含一个标准光照模型的表面着色器面板
    2、Unlit Shader:产生一个不包含光照,包含雾气效果的基本顶点/片元着色器
    3、Image Effect Shader:提供实现各种屏幕后处理效果的模板
    4、Compute Shader:产生特殊的Shader文件,该文件旨在利用GPU的并行性来进行一些与常规渲染流水线无关的计算
    5、Ray Tracing Shader:光线追踪着色器。支持光追的着色器,在书中的Unity版本中还没有出现。
image 98 - 《Unity Shader入门精要》笔记:基础篇(1)
  • Unity Shader结构:(下方代码只解释结构,代码意思后文再叙)
    1、Shader名称,位置
    2、Properies
    3、SubShader
//1、在Shader下拉列表中的CustomShader选项中显示名为Shader_1的Unity Shader
Shader "Custom/Shader_1"
{
//2、Properties语义块:包含一系列属性(property),主要作用为把想要的属性显示到材质面板中,材质面板示例可以在上方“面板”图片中查看
    Properties
    {
//示例:Name("display name",propertyType) = DefaultValue
    }
//可以包含多个SubShader但至少要有一个。Unity加载Shader时会扫描所有的SubShader并选择第一个能运行的SubShader运行,如果都不可以运行则使用Fallback指定的UnityShader
    SubShader
    {
//标签[Tags]:可选项
        [Tags]

//状态[RenderSetup]:可选项
        [RenderSetup]

//每一个pass定义了一次完整的渲染流程,如果Pass数目过多会造成渲染性能下降。状态和标签可以在pass中声明
        Pass{}
    }
    FallBack "Diffuse"
}
image 100 1024x505 - 《Unity Shader入门精要》笔记:基础篇(1)
Properties支持的类型(更新自官方文档)
image 101 - 《Unity Shader入门精要》笔记:基础篇(1)
  • SubShader标签传送门,是一个键值对,都为字符串类型。这些键值对用于告诉Unity渲染引擎,怎样以及何时渲染这个对象。(新增了:RenderPipeline,所有标签使用示例都在手册中有)
image 102 - 《Unity Shader入门精要》笔记:基础篇(1)
  • Pass语义块
  • Pass标签:传送门,包含LightMode,PassFlags,RequireOptions三种。
Pass
{
        [Name]
        Name "Mypass"//定义pass名称,可以在其他地方使用UsePass “shader名称/大写pass名称”,unity会自动把pass名称全部转换为大写
        [Tags]
        [RenderSetup]
//Code
}
  • Fallback:设置一个保底选项,也可以不设置。
  • Unity Shader的形式:表面着色器,顶点/片元着色器,固定函数着色器。
    表面着色器(Surface Shader):Unity自创的着色器代码类型。代码编写量少,Unity准备工作多,渲染代价大。
    顶点/片元着色器(Vertex/Fragment Shader):代码复杂,但灵活性高。
    固定函数着色器(Fixed Fuction Shader):针对不支持可编程渲染管线的着色器。

额外补充

  • UnityShader不等于Shader,UnityShaderLab比传统Shader可以做的事情更多。
    1、可以在同一个文件里同时包含需要的顶点着色器和片元着色器
    2、可以设置是否开启混合、深度测试等指令。
    3、便捷的输入输出处理,模型自带数据可以直接访问。
  • 在Unity中,CG和HLSL语法从写法上基本一直。所以在Unity中CG基本等价HLSL。

LEAVE A COMMENT