Shader Language
CG
NV和Microsoft搞的C语言格式的Shader language
GSGL
OpenGL的Shader Langugae
ShaderLab
Unity编译后的底层Shader语言
Unity Shader分类
Surface Shaders 表面着色器
影响光影效果的着色器,与Unity的光照管线交互,大多数自动支持直接光照(forward lighting)和延迟光照(Deferred Lighting). Surface Shaders会自动生成和光照有关的运算,如果用不到光照,就不要使用它。
Vertex and Fragment Shaders 定点面片着色器
底层的Shader,常用来做与光无关或者表面着色器无法实现的效果
Fixed Function Shaders
用于早期不支持Shader Language的硬件。使用ShaderLab语言
ShaderLab
上述各种Shader最终会生成ShaderLab代码,详见http://docs.unity3d.com/Documentation/Components/SL-Shader.html
注:呵呵,Minko的ShaderLab命名难道源于这里?
Unity Shader的性能
主要的影响因素:Shader本身和渲染路径(Rendering Path)
Deferred Lighting: 每个对象绘制两次
Vertex Lit: 每个对象绘制两次
开销排行,从低到高
- Unlit. This is just a texture, not affected by any lighting.
- VertexLit.
- Diffuse.
- Normal mapped. This is a bit more expensive than Diffuse: it adds one more texture (normal map), and a couple of shader instructions.
- Specular. This adds specular highlight calculation.
- Normal Mapped Specular. Again, this is a bit more expensive than Specular.
- Parallax Normal mapped. This adds parallax normal-mapping calculation.
- Parallax Normal Mapped Specular. This adds both parallax normal-mapping and specular highlight calculation.
Rendering Paths渲染通道
Unity有多重不同的通道,有不同的性能和特性
在Player Settings中选择通道,每个摄像机(Camera)可以有单独的配置
当硬件不支持某个通道时,Unity自动选择效果次之的。如果GPU不支持Deferred Lighting是,Forward Rendering会被使用。如果Forward Rendering不支持,则会选择Vertex Lit。
- Deferred Lighting:高真实度,效果最丰富,适合动态光照,对硬件有要求,只支持Unity Pro,不支持移动设备
- Forward Rendering:支持一个产生阴影的光源,详见下文
- Vertex Lit:低真实度,不支持动态阴影
Deferred Lighting
Forward Rendering
Vertex Lit
Per-pixel
Yes
Yes
-
Realtime shadows
Yes
1
-
Dual Lightmaps
Yes
-
-
Depth&Normals Buffers
Yes
Additional render passes
-
Soft Particles
Yes
-
-
Semitransparent objects
-
Yes
Yes
Anti-Aliasing
-
Yes
Yes
Lighting Culling Masks
Limited
Yes
Yes
Lighting Fidelity
All per-pixel
Some per-pixel
All per-vertex
Cost of a per-pixel Light
Npixel
Npixel * Nobjs
-
PC
Shader Model 3.0+
Shader Model 2.0+
Any
Mobile(IOS/Android)
-
OpenGL ES 2.0
OpenGL ES 2.0 & 1.1
Consoles
360, PS3
360, PS3
-
Forward Rendering Path Details (前向渲染路径细节)
不得不佩服很赞的优化,光照系统的整体解决方案,兼顾了性能和效果。详见:http://docs.unity3d.com/Documentation/Components/RenderTech-ForwardRendering.html
三种光源的绘制方式:
- per-pixel lit: 每像素点光照,支持shadow,normal mapping,开销大
- per-vertex lit: 每定点光照,开销小,Unity只有四个光源,不支持Console,不支持每像素效果(shadow,normal mapping,light cookie)
- Spherical Harmonics (SH): 球谐函数,无GPU开销,任意数量,有少量CPU开销,缺乏细节,光源变化度低,不支持每像素效果,对Lightmapped对象没有照明,当光源接近物体时,看起来有问题
光源分派原则:
- 标为“不重要”的光源总是使用per-vertex或SH
- 最亮的方向光总是用per-pixel
- 标为”重要“的光源总是用per-pixel
- 如果使用的per-pixel小于Quality Setting里的设置,更多的光源会使用per-pixel模式
通道分派:
- 基础通道(Base Pass)处理一个per-pixel的方向光和所有per-vertex/SH(此外还有Lightmap,环境光,发射光(emissive lighting),基础通道产生阴影
- 其它每个per-pixel使用一个单独的通道,额外通道不产生阴影
注意:前向渲染只支持产生一个主光源的阴影
Deferred Lighting Rendering Path (延迟光照渲染通道)
详见:http://docs.unity3d.com/Documentation/Components/RenderTech-DeferredLighting.html
Unity Shader 语法(CG)
Shader "CTD/DiffuseSimple" // 名称,会在编辑器中出现
{
SubShader// 渲染时选中第一个匹配的SubShader用于绘制
{
Properties
{
// _Name ("DisplayName", Type) = DefaultValue
_ColorTint("Color Tint", Color) = (1,1,1,1)
}
// 详见 http://docs.unity3d.com/Documentation/Components/SL-SubshaderTags.html
Tags { “RenderType” = "Opaque" } // Tags用于说明何时及如何渲染,Tag有Queue,RenderType,ForceNoShadowCasting,IgnoreProjector
CGPROGRAM // CG的开始标志
// #pragma surface 标明为Surface Shader(使用光照),surf为函数名,Lambert为lightModel, 内建的有Lambert(diffuse), BlinnPhong(specular)
#pragma surface surf Lambert
struct Input
{
float4 color : COLOR;
};
// SurfaceOutput 标准surface shader输出结构
// struct SurfaceOutuput {
// half3 Albedo; 反照,是不是就是Diffuse?
// half3 Normal; 法线
// half3 Emission; 发射
// half Specular; 反射率
// half Gloss; 发光
// half Alpha; 透明度
// };
void surf (Input IN, inout SurfaceOuput o)
{
IN.color = _ColorTint;
o.Albedo = IN.color;
}
Fallback "Diffuse" // 如果上面的Shader不能用,改用"Diffuse" Shader
ENDCG // CG的结束标志
}
}