首先,什么是Shader?
简单来说,用来计算3D图形的渲染方法,就是Shader
Unity有自带的Shader,为什么还要写Shader?
自带的shader确实已经可以模拟不少物体的质感,如金属、木头、塑料之类,但是有些特殊的效果却不能达到,像外轮廓、皮肤之类的……因此我们需要自己来写个算法,达到我们需要的特殊效果。
Unity里的Shader要怎么写?要不要什么基础?
基础自然是要的,如果有点程序基础就可以很容易上手,有点计算机图形算法知识那上手就更快啦!如果都没有……别担心,这篇详解就是为你准备的~进正题吧!
正题
首先创建一个Shader,这里我们就拿Unity5.4.0自带的StandardSurfaceShader来举例
方法:在Unity的Project中右键Create>Shader>StandardSurfaceShader
重命名为TestSurfaceShader
双击打开脚本,第一行会有:
Shader "Custom/TestSurfaceShader" {
引号中的字段表示该Shader在Unity中Inspector的下拉菜单位置和名字,如一开始我们重命名为TestSurfaceShader,则这里会把TestSurfaceShader作为该Shader的名字
在这行代码下面则是Properties:
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
Properties里的这些属性则是出现在Inspector窗口里的GUI属性
以_Color ("Color", Color) = (1,1,1,1)为例子,详细解释一下脚本的构造
_Color为属性名,后面括号里为其属性
括号里的"Color"为GUI名,将显示在Inspector窗口里
括号里的Color为该属性的值类型,这里的类型为Color
等号后面的(1,1,1,1)为该属性的默认值
如果尝试修改这些东西,会发现,属性名、GUI名、默认值都可以随便改,但是值类型却不行,值类型到底有哪些呢?
下面列出值类型种类:
Range(min,max) 限定最小值和最大值的滑竿,值为float
Color 是个float4的值,可以再Inspector窗口中选取颜色,值为(float,float,float,float)
2D 创建纹理,通过往Shader中拖拽Texture方式获得
Rect 创建一个非2次幂的Texture,类似于2D GUI
Cube 创建一个CubeMap,和创建纹理一样,通过拖拽CubeMap方式获得
Float 创建一个不限定范围的float
Vector 创建一个float4,可以用来表示颜色,或者方向等
那么,如何通过Properties的各种值来计算图形渲染呢?
SubShader则是图形渲染的代码:
SubShader {
Tags { "RenderType"="Opaque" } Tags为标签,后面大括号内表示渲染类型为不透明
LOD 200 LOD是渲染细节等级,随着距离越远,渲染精度则会越低,从而提高系统性能
CGPROGRAM 关键字,CG程序指令
pragma surface surf Standard fullforwardshadows #pragma为CG编译指令,指令后的字段表示使用标准模式,打开所有正向渲染灯光投影
pragma target 3.0 该指令是使用Shader model 3.0 target,将会获得更好的照明效果
sampler2D _MainTex; 2D纹理采样,下面获取纹理UV
struct Input {
float2 uv_MainTex;
};
half _Glossiness; 获取Properties里的属性,下同
half _Metallic;
fixed4 _Color;
下面的void surf中,则是该Shader的算法。输入值IN,即输入又输出的双向端口o
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 通过Texture对应UV乘以Color来计算纹理颜色,并保存到临时变量c中
o.Albedo = c.rgb; 输出c的RGB颜色给输出o的反射颜色
o.Metallic = _Metallic; 直接把Properties的属性赋予o并输出金属质感
o.Smoothness = _Glossiness; 同上,输出光滑度
o.Alpha = c.a; 把c的Alpha作为o的Alpha输出
}
ENDCG 结束CG程序
}
FallBack "Diffuse" 返回漫射类型
}
到此 Shader脚本结束
网友评论