Unity Shader 基础
unity shader在5.2版本以上能够直接从项目中创建4个shader模板:standard surface shader、Unlit shader、Image Effect shader,computer shader.
standard shader:包含标准光照模型(使用了基于物理的渲染方法)
Unlit shader:不含光照的基本的顶点/片元着色器
Image Effect shader:处理屏幕效果
Computer shader:将一些计算放置到GPU中计算
shaderLab:这是unity 对我们封装了大部分的渲染实现细节,向开发者提供的一种着色器语言。
shaderLab的基本结构:
shader"ShaderName"
{
properties{
//放置unity界面能访问到的数据
}
subshader{
//子着色器
}
subshader{
//子着色器
}
...
Fallback"Vertexlit"
}
子着色器是为了shader能够适应不同的GPU环境,unity在shader中查找,直到找到最适合的,如果没找到,就在fallback中去找。
properties
为了能让shader中的变量在面板中调控,需要在properties中定义属性,格式为:
Name("display name",propertytype) = defaultValue
Name是属性的名称,用来和着色器进行关联,display name用作在材质面板上显示。propertytype是属性的类型。defaultValue是属性的默认值。
每个属性的默认值是不同的,格式也是不同的,详情见书:30页。
subshader是着色器的具体的实现部分,格式为:
subshader{
[tags]//标签设置
[rendersetup]//状态设置
pass{
}
}
tag用来设置标签,通常是键值对的形式,这个就是之前在shader中看到一些设置比如:Tags{“TagName1”=”value” “TagName2”=”Value2”}
rendersetup 是渲染状态设置,用来处理深度测试、深度写入等的设置。
tags和rendersetup都是设置渲染流水线中的可配置部分。
Pass
pass定义了一个完整的渲染流程,pass过多的话会影响渲染效率。
pass中也定义了一些tag和rendersetup。pass中的tag==于rendersetup基本相同==,但是==tag基本不同==。
同时可以给pass定义一个名称,通过以下方法定义:
Name"MyPassName"
定义名称很大程度上是为了方便其他的shader调用,调用是需要注意所有的英文单词需要大写!:
UsePass"MyShader/MYPASSNAME"
表面着色器与顶点面片着色器之间的区别
表面着色器其实是unity的一种封装,为的是让开发者尽量减少开发的难度,而只需要去通过简单的设置就能开发出想要的效果。减少开发的一些细节。这样的好处是开发简单,但是自由度很低。
开发语言是cg/HLGL,所有的代码需要在subshader中实现:
subshader{
CGPROGRAM
//cg code
ENDCG
}
开发者只需要关注很少的一部分就可以了,但是这样的效率并不高。
表面着色器有一个很明显的特征,那就是具体实现代码是在:
void surf(Input IN,inout SurfaceOutput o)
{
}
中实现。这里不需要写pass,因为具体的渲染细节已经被unity所隐藏了。
顶点/片元着色器
这个于表面着色器最大的区别在于用户需要自定义渲染过程,并且所有的代码都需要写在pass代码块中:
subshader{
pass{
CGPROGRAM
//
ENDCG
}
}
这样的代价是我们需要写很多渲染相关的代码,但是具有很高的自由度。