最近团队培养的shader程序员离队了,项目还是需要有人来完成的,所以最近我开始着手来做
现在最缺的是时间
为了强迫自己坚持把这个学完,在这里决定每天完成一个shader,坚持2个月。
第一节 最简单的shader程序----漫反射
在过去的计算机图形学中,漫反射的着色过程(diffuse shading)是通过所谓的固定功能光照模型来完成的,它只允许图形程序员通过一些参数或纹理来对单一的光照模型进行
调整。而现在,我们可以通过 Cg 语言更加灵活地控制渲染细节,特别是使用 Unity 中的表面着色器。
Shader "Unlit/testShader1"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf(Input IN, inout SurfaceOutput o)
{
half4 c = tex2D(_MainTex,IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
fallback "Diffuse"
}
对大多数学过shader的人来说,这是一个非常简单的啥的shader程序,但对于没有接触过的人,还是需要研读一下里面的具体的含义。
Shader "Unlit/testShader1"
最上面的一句话指的是这个将这个shader注册在Unlit目录下,显示的名字叫testShader1,这个Unlit目录在材质球添加shader的地方。
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
这部分是面向unity编辑器的,它告诉编辑器界面上有一个_MainTex接口,可以传进来一个名字叫_MainTex的Texture,属性是2D的。
在这里可以申请很多的参数
name ("display name", Range (min, max)) = number
定义浮点数属性,在检视器中可通过一个标注最大最小值的滑条来修改。
name ("display name", Color) = (number,number,number,number)
定义颜色属性。
name ("display name", 2D) = "name" { options }
定义2D纹理属性
name ("display name", Rect) = "name" { options }
定义长方形(非2次方)纹理属性
name ("display name", Cube) = "name" { options }
定义立方贴图纹理属性
name ("display name", Float) = number
定义浮点数属性
name ("display name", Vector) = (number,number,number,number)
定义四个向量组成的属性
其中name是变量名 display name是显示在unity界面里面的名字,color,2D这样的则是数据类型。
SubShader
SubShader是运行的主体,看到很多人称之为shader列表,Sub其实就是集合么,SubShader就是shader集,简化一下它应该是下面的样子
SubShader {
Pass {
}
Pass{
</pre><pre code_snippet_id="1770095" snippet_file_name="blog_20160719_8_7871736" name="code" class="csharp"> }
}
每个Pass可以认为是子任务,多个子任务结合就可以完成一个SubShader任务。
Tags { "RenderType" = "Opaque" }
LOD 100
这个里面的内容比较多,稍后再研究吧,他总的概念就是告诉我们当前的渲染模式设定,LOD层级设定
CGPROGRAM
.....
ENDCG
表示的是这里面的代码用的是CG语言,shader有很多种语言版本,常见的是HLSL,CG
#pragma surface surf Lambert
声明了一个surf函数
sampler2D _MainTex;
声明了一个2D 图片变量_MainTex,这个_MainTex跟上面_MainTex同名,这样shader会自动将两者关联起来
struct Input
{
float2 uv_MainTex;
};
定义了一个输入类型的结构体,其中的参数是纹理的UV;float2是数据类型,表示这个变量由2个float型变量组成
void surf(Input IN, inout SurfaceOutput o)
{
half4 c = tex2D(_MainTex,IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
执行的主题函数,对输入的纹理继续运算,将纹理的颜色值和半透明值逐像素依次传送给输出纹理;这个输出纹理SurfaceOutput将最后显示在模型上