0%

Shader框架结构

前言

Shader 也称着色器其实属于应用程序层,用于调用和使用图形API,以编程的形式来控制图形渲染。
本文将初探 Shader

Shader 分类

这里的分类是主流的大体分类。

  1. Vertex Shader (顶点着色器),模型的顶点决定了模型的形状以及位置。更像是模型框架结构。
  2. Fragment Shader (片元着色器) ,也叫像素着色,相比顶点片元着色器负责颜色的渲染,将模型的贴图转换为一个个像素点渲染,大量的像素显示不同的颜色,最终展示出贴图的样式。

Shader 编程语言

  1. 基于 OpenGL 的 OpenGL Shader Language,简称 GLSL 。
  2. 基于 DirectX 的 High Level Shader Language,简称 HLSL 。
  3. NVIDIA 公司提供给的 C for Graphic,简称 CG 。

GLSL 与 HLSL 相互间是互斥的,因为其分别基于 OpenGL 接口 和 DirectX 接口。图形接口只能使用一个。
OpenGL 更多应用在移动端,其轻便,高性能的特点,能在低端性能设备上保证良好的性能与效果。
DirectX 是微软公司提供的图形接口,也是 PC端 最常见最主要的图形接口。

CG语言如同其全称 C for Graphic ,使用 C语言 对图形编程,其初衷是让基于图形硬件的编程变得和C语言编程一样强大,方便,自由。对于程序开发人员来讲非常容易上手。
CG语言是 Microsoft 和 NVIDIA 相互合作在标准硬件光照语言和语法语义上达成一致,所以 HLSL 与 CG 是同一种语言。

ShaderLab 语法结构

ShaderLab 是 Unity 封装了一层 CG/HLSL/GLSL 接口,但为了跨平台 Unity 重点支持 CG 语言。

基本结构

1
2
3
4
5
6
7
Shader "Custom/myShader"{
Properties{}

SubShader{}

Fallback "VertexLit"
}
  1. 外部结构 Shader "name"{} ,其中的 name 不需要保证与文件名相同,其表示 Unity 的 Meteria 面板中的 shader目录名。’/‘ 用于表示目录父子关系。
  2. Properties{} 其中负责声明定义 Shader 属性,将会显示在 Material 的面板中,以便自定义属性。可以为空,可以没有,但最多只有一个此结构。
  3. SubShader{} 至少要有一个,显卡通过 SubShader 来决定渲染方式,是程序入口,因此至少要有一个,可以有多个。当有多个时,会先从第一个 SubShader 编译,当编译不通过,会选择第二个,以此类推。而当有一个可以编译通过,就不再运行后面的 SubShader 。有些时候,一些设备版本不支持的渲染编码,会使得SubShader 无法编译通过,这可以称作是替代方案。
  4. Fallback "ShaderName" 当所有的 SubShader 都无法通过时,会执行此方案中的 Shader 。ShaderName 必须是系统提供或者自建存在的 shader,当有重名时考虑其目录名。被称为后备方案。

Properties 结构

定义在Properties{} 的属性会显示在 Inspector面板中。可以理解为全局属性。

属性定义方式

属性名("外部显示名",属性类型),属性名为内部编程调用的属性名称;外部属性名可以任意命名是 Inspector 面板中显示的属性名称;属性类型,则是变量的数据类型。

Properties{} 中定义的属性必须初始化,并且不需要分号结尾。

基础数据类型

类型 描述 示例
Color 颜色类型,一个四维向量,主要前三维表示RGB
取值范围是在 0-1 之间。
_Color("Color",Color) = (1,1,1,1)
Vector Vector 向量类型,一般为四维向量,其取值是浮点类型。可以说 Color 是 Vector 的一个特例。 _Vector("Vector",Vector) = (1,2,3,4)
Int Int 类型(整型),整数类型属性。 _Int("Int",Int) = 40
Float Floar 类型,浮点数类型属性。 _Float("Float",Float) = 4.5
Rangle Rangle 类型,范围类型,用于指定属性的取值范围,其类型是浮点型。 _Rangle("Rangle",Rangle(10,22)) = 11.5

特殊数据类型

类型 描述 示例
2D 2D 类型,往往用于指定图片,纹理。
而不指定图片源,可以是设置的默认颜色。
注意颜色名是字符串。
_2D("Texture",2D) = "red"{}
Cube Cube 类型,是多个纹理图片组成的立方体6面,可以看作是 2D 类型的数组类型,往往多用于天空盒。 _Cube("Cube",Cube) = "White"{}
3D 3D类型,目前我还没找到一些资料解释,这里称作 3D 纹理。 _3D("3D",3D)="blue"{}

SubShader 结构

SubShader 表示一种渲染方案,也是我们编程的主要入口。
结构:

1
2
3
4
5
6
7
SubShader{
Pass{
CGPROGRAM

ENDCG
}
}

在 SubShader 中至少要有一个 Pass 。Pass 可以看作是一个编译入口,或者一个工作空间。

而 shader 代码在 CGPROGRAM-ENDCG中编写,表示使用 CG语言编程。也可以是 HLSLPROGRAM-ENDHLSL