[UnityShaderCookbook 读书笔记] [01] Unity Shader 基础

创建 Shader

一个好的Shader总是从一个基本的 diffuse 光照模型开始
因此,我们从 Diffuse 入手开始写 Shader ~

Shader 中的 Diffuse 部分描述从一个表面上向各个方向反射的光

在Unity中创建 Shader 并打开
得到了一个 Unity 的 Shader 模板

Shader "HineNotes/CookbookCh_01/BasicDiffuse" {
     Properties {
          _MainTex ("Base (RGB)", 2D) = "white" {}
     }
     SubShader {
          Tags { "RenderType"="Opaque" }
          LOD 200

          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 关键字后的字符串 “Cookbook_01/BasicDiffuse”
为 Shader 名,利用 / 可以为 Shader 设置分级菜单

新建一个 Material, 也起名 BasicDiffuse 把这个Shader赋给它
再把这个 Material 赋给模型,得到的效果就是这样~
[UnityShaderCookbook 读书笔记] [01] Unity Shader 基础_第1张图片
这是一个 Surface Shader, Unity 为我们做了很多幕后工作
随着我们深入学习,对于其背后的 Cg 语言,以及 Unity 如何处理背后的底层 GPU 任务,会有更多的了解

有关 Unity 内置的 Cg 函数,参考 Unity安装目录\Editor\Data\CGIncludes
目前值得我们关注的有
UnityCG.cginc, Lighting.cginc, UnityShaderVariables.cginc
我们当前的这个 Shader 用到了这些文件

为 Shader 添加属性

选中刚刚的 BasicDiffuse 材质,在 Inspector 面板中,我们可以看到 Shader 属性 Base (RGB)

也就是 BasicDiffuse 中的这一段

Properties {
     _MainTex ("Base (RGB)", 2D) = "white" {}
}

定义属性的语法为
Properties { Property [Property …] }

而通常的写法为
_name (“display name”, type) = “defaulttexture” {}

name 为属性名,在Unity中属性名通常以下划线 _开始,display name 为该属性在 Inspector 面板中显示的名字,type 表示属性的类型(具体见下面的表格)赋值符号后面的字符串是默认值,根据不同属性类型来提供,而最后的大括号中则是可选的选项

属性类型 描述
Range (min, max) 在 Inspector 面板中创建一个滑条,在最大最小值之间滑动,接受 float 参数
Color 在 Inspector 面板中创建一个颜色面板,可以打开拾色器,获取颜色 float4 = (float,float,float,float)
2D 在 Inspector 面板中创建一个贴图面板,允许用户为 Shader 指定贴图对于 2D 和 Cube 类型,默认值可以使用空字符串”“,或“white”,”black”,”gray”,”bump”
3D 在 Inspector 面板中创建一个贴图面板,允许用户为 Shader 指定3D贴图
Rect 在 Inspector 面板中创建一个不以2的整数幂为大小的贴图
Cube 在 Inspector 面板中创建一个 cube map 面板,允许用户为 Shader 指定 cube map
Float 在 Inspector 面板中创建一个 float 值输入框,但没有滑条
Int 在 Inspector 面板中创建一个 int 值输入框
Vector 在 Inspector 面板中创建一组4个 float 值输入框,可以用来传入方向和颜色

将初始 Shader 的标题改为
“HineNotes/CookbookCh_01/UseOfProperties”

其中的属性段改为

Properties {
     _Slider ("Slider", Range(0, 10)) = 5
     _Float ("Float", Float) = 1.0
     _Int ("Int", Int) = 1
     _Color ("Clolr", Color) = ( 0.262, 0.612, 1.0, 1.0)
     _Vector ("Vector", Vector) = (1.0, 1.0, 1.0, 1.0)
     _TwoD("2D", 2D) = "" {}
     _Cube("Cube", Cube) = "" {}
     _ThreeD("3D", 3D) = "" {}
     _MainTex ("Base (RGB)", 2D) = "white" {} 
}

存储后切换到 Unity, Unity 会对更改后的 Shder 自动进行编译,我们可以在 Inspector 中看到属性效果

Base( RGB ) 上方就是我们刚刚新添加的属性
对于 Property 部分的介绍,可以参考 Unity 官方文档
http://docs.unity3d.com/Manual/SL-Properties.html

使用 Shader 的属性

想要在 SubShader 块中使用属性,我们需要在其中创建与 Properties 块中同名的属性
将 CGPROGRAM 段修改为

CGPROGRAM
#pragma surface surf Lambert

float4 _Color;
float _Slider;

struct Input {
     float2 uv_MainTex;
};

void surf (Input IN, inout SurfaceOutput o) {
     float4 c;
     c = pow(_Color, _Slider);
     o.Albedo = c.rgb;
     o.Alpha = c.a;
}
ENDCG

即可得到由 _Color 和 _Slider 两个属性共同控制的 Shader
其中 _Color 控制漫反射颜色,_Slider 控制强度
最终的 UseOfProperties Shader 如下

Shader "HineNotes/CookbookCh_01/UseOfProperties" {
     Properties {
          _Slider ("Slider", Range(0, 10)) = 5
          _Float ("Float", Float) = 1.0
          _Int ("Int", Int) = 1
          _Color ("Clolr", Color) = ( 0.262, 0.612, 1.0, 1.0)
          _Vector ("Vector", Vector) = (1.0, 1.0, 1.0, 1.0)
          _TwoD("2D", 2D) = "" {}
          _Cube("Cube", Cube) = "" {}
          _ThreeD("3D", 3D) = "" {}
          _MainTex ("Base (RGB)", 2D) = "white" {}
     }

     SubShader {
       Tags { "RenderType"="Opaque" }
       LOD 200

          CGPROGRAM
          #pragma surface surf Lambert

          float4 _Color;
          float _Slider;

          struct Input {
               float2 uv_MainTex;
          };

          void surf (Input IN, inout SurfaceOutput o) {
               float4 c;
               c = pow(_Color, _Slider);
               o.Albedo = c.rgb;
               o.Alpha = c.a;
          }
          ENDCG
     }
     FallBack "Diffuse"
}

其中 pow(arg1, arg2) 函数是 Cg 语言内置的函数,提供指数运算
关于更多 Cg 内置函数,参考
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_appendix_e.html

经过调整颜色的材质如下
[UnityShaderCookbook 读书笔记] [01] Unity Shader 基础_第2张图片

你可能感兴趣的:(游戏,unity,shader,图形学)