[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 赋给模型,得到的效果就是这样~
BasicDiffuse 效果
这是一个 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

经过调整颜色的材质如下
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值