Unity Shader入门精要 第一、二章

  1. 1. 1.1 Shader是什么
    1. 1.0.1. shader就是着色器
  • 2. 2.1 渲染流水线(概念上)
    1. 2.0.1. 渲染流水线的工作任务在于由一个三维场景出发,生成(渲染)一张二维图像。
    2. 2.0.2. 一般分为三个阶段:
  • 3. 2.2 CPU和GPU之间的通信
    1. 3.0.1. 2.2.1 把数据加载到显存中
    2. 3.0.2. 2.2.2 设置渲染状态
    3. 3.0.3. 2.2.3 调用Draw Call
  • 4. 2.3 GPU流水线
    1. 4.0.1. 2.3.1 概述
    2. 4.0.2. 2.3.2 顶点着色器(几何阶段)
    3. 4.0.3. 2.3.3 裁剪(几何阶段)
    4. 4.0.4. 2.3.4 屏幕映射(几何阶段)
    5. 4.0.5. 2.3.5 三角形设置(光栅化阶段)
    6. 4.0.6. 2.3.6 三角形遍历(光栅化阶段)
    7. 4.0.7. 2.3.7 片元着色器(光栅化阶段)
    8. 4.0.8. 2.3.8 逐片元操作(光栅化阶段)
  • 5. 2.4 一些容易困惑的地方
    1. 5.0.1. 2.4.1 什么是OpenGL/DirectX
    2. 5.0.2. 2.4.2 什么是HLSL、GLSL、CG
    3. 5.0.3. 2.4.3 什么是Draw Call
    4. 5.0.4. 2.4.3 什么是固定管线渲染
  • 6. 2.5 那么,你明白什么是Shader了吗

  • 1.1 Shader是什么

    shader就是着色器


    2.1 渲染流水线(概念上)

    渲染流水线的工作任务在于由一个三维场景出发,生成(渲染)一张二维图像。

    一般分为三个阶段:

    • 应用阶段:输出渲染图元(点、线、三角面等)
    • 开发者任务:
    1. 准备好场景数据(摄像机位置、视锥体、场景中包含的模型、光源);
    2. 做一个粗粒度剔除工作,把不可见的物体剔除,不交给几何阶段处理;
    3. 设置好每个模型的渲染状态(材质、纹理、shader)。
    • 几何阶段:输出屏幕的顶点信息
    • 开发者任务:
      1.处理所有和我们要绘制的几何相关的事物(决定需要绘制的图元是什么、怎样绘制它们、在哪里绘制)
    • 光栅化阶段:使用上一阶段的数据来阐述屏幕上的像素。并渲染出最终的图像

    2.2 CPU和GPU之间的通信

    2.2.1 把数据加载到显存中

    • 从硬盘加载到内存
      -然后网格和纹理等数据又被加载到显卡上的存储空间–显存

    2.2.2 设置渲染状态

    • 定义场景中的网格是怎样被渲染的

    2.2.3 调用Draw Call

    • 是一个命令,发起方是CPU,接收方是GPU,仅仅指向一个需要被渲染的图元列表,不会包含任何材质信息

    2.3 GPU流水线

    2.3.1 概述

    • 几何阶段和光栅化阶段可以分成若干个更小的流水线阶段,这些流水线阶段由GPU来实现,每个阶段GPU提供了不同的可配置性和可编程性
    • 顶点数据:输入
    • 顶点着色器:实现顶点的空间变换、顶点着色等功能
    • 曲面细分着色器:用于细分图元
    • 几何着色器:用于执行逐图元的着色操作,或用于产生更多图元
    • 裁剪:将不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元的面片
    • 屏幕映射:负责把每个图元的坐标转换到屏幕坐标系中
    • 三角形设置:固定函数阶段
    • 三角形遍历:固定函数阶段
    • 片元着色器:实现逐片元的着色操作
    • 逐片元操作:修改颜色、深度缓冲、进行混合等
    • 屏幕图像

    2.3.2 顶点着色器(几何阶段)

    • 输入进来的每个顶点都会调用一次顶点着色器
    • 工作:坐标变换、逐顶点光照
    • 把顶点坐标从模型空间转换到齐次裁剪空间(如(5,10,8)->(.6,.4,.2) 0-1之间)

    2.3.3 裁剪(几何阶段)

    • 不处理不在相机范围内的物体
    • 三种关系:
    1. 完全在视野内 – 将图元传递给下一流水线
    2. 部分在视野内 – 在视野交界处用新的顶点代替
    3. 完全在视野外 – 不会传递图元

    2.3.4 屏幕映射(几何阶段)

    • 把每个图元的x和y坐标转换到屏幕坐标系下
    • 屏幕坐标系和z坐标一起构成了一个坐标系,叫做窗口坐标系

    2.3.5 三角形设置(光栅化阶段)

    • 计算光栅化一个三角网格所需的信息

    2.3.6 三角形遍历(光栅化阶段)

    • 检查每个像素是否被一个三角网格所覆盖
    • 是的话就生成一个片元

    2.3.7 片元着色器(光栅化阶段)

    • 也被称为像素着色器
    • 将上一个片元数据处理为颜色值

    2.3.8 逐片元操作(光栅化阶段)

    • 也被称为输出合并阶段
    • 1.决定每个片元的可见性:
      · 模板测试:将模板缓冲区中该片元的值和参考值进行比较;限制渲染区域
      · 深度测试:将该片元的深度值和已经存在于缓冲区中的深度值进行比较
    • 2.混合颜色——混合:
      · 关闭-就会直接覆盖
      · 开启:就会对片元颜色和缓冲区颜色进行混合
    • 双重缓冲:交换后置缓冲和前置缓冲的内容;后置缓冲进行光栅化;前置缓冲进行显示

    2.4 一些容易困惑的地方

    2.4.1 什么是OpenGL/DirectX

    • 显卡驱动把OpenGL和DX的函数调用翻译成GPU执行命令
    • 应用程序通过调用OpenGL和DX的图形接口将渲染所需的数据,如顶点数据、纹理数据、材质参数等数据存储在显存的特定区域

    2.4.2 什么是HLSL、GLSL、CG

    • HLSL:
      · DX的着色语言,着色语言是专门用来编写着色器的
      · 微软的
    • GLSL:
      · OpenGL的着色语言
      · 跨平台
    • CG:
      · 英伟达的C for graphic
      · 跨平台

    2.4.3 什么是Draw Call

    • CPU调用图像编程接口,以命令GPU进行渲染的操作
    • 通过命令缓冲区来并行工作
    • Draw Call多了会影响帧率
    • 使用批处理可以有效较少Draw Call数量(类比多个小文件打成压缩包复制到别处会快很多)

    2.4.3 什么是固定管线渲染

    • 只提供配置操作
    • 没有对流水线阶段的完全控制权

    2.5 那么,你明白什么是Shader了吗

    • GPU流水线上一些可高度编程的阶段,而由着色器编译出来的最终代码会在GPU上运行
    • 有一些特定类别的着色器,比如顶点着色器、片元着色器
    • 依靠着着色器,我们可以控制流水线中的渲染细节,例如用顶点着色器进行顶点变换以及传递数据,用片元着色器来逐像素的渲染
    • 操作包括:设置适当的渲染状态,使用合适的混合函数,开启还是关闭深度测试/深度写入