Unity Shader 表面着色器边缘光(Rim Lighting)一

上一节我们发现给小球加上板砖的法线贴图后,小球变暗了,我们这一节将会使小球边缘亮起来。

效果图:



然后通过"Create->Shader->Standard Surface Shader"创建一个表面着色器,并修改名字为Rim Lighting

然后通过"Create->Material"创建一个材质,并修改名字为MaterialRimLighting,材质使用的shader指定为我们刚创建的Rim Lighting

我们来看看Shader代码

Shader "Custom/Rim Lighting" {
	 //属性域
	Properties {
	  //主纹理属性
      _MainTex ("Texture", 2D) = "white" {}
      //法线贴图纹理属性
      _BumpMap ("Bumpmap", 2D) = "bump" {}
      //边缘光颜色值
      _RimColor ("Rim Color", Color) = (1,1,1,1)
      //边缘光强度值
      _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
    }
    SubShader {
      //标明渲染类型是不透明的物体
      Tags { "RenderType" = "Opaque" }
      //标明CG程序的开始
      CGPROGRAM
      //声明表面着色器函数
      #pragma surface surf Lambert
      //定义着色器函数输入的参数Input
      struct Input {
      	  //主纹理坐标值
          float2 uv_MainTex;
          //法线贴图坐标值
          float2 uv_BumpMap;
          //视图方向
          float3 viewDir;
      };
      //声明对属性的引用
      sampler2D _MainTex;
      sampler2D _BumpMap;
      float4 _RimColor;
      float _RimPower;
      //表面着色器函数
      void surf (Input IN, inout SurfaceOutput o) {
      	  //赋值颜色信息
          o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
          //赋值法线信息
          o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
          half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
          //赋值自发光颜色信息
          o.Emission = _RimColor.rgb * pow (rim, _RimPower);
      }
      //标明CG程序的结束
      ENDCG
    } 
    Fallback "Diffuse"
}
我们来看看我们的Shader代码和 上一节有什么不同

首先在属性域Properties多了两个属性

//边缘光颜色值
      _RimColor ("Rim Color", Color) = (1,1,1,1)
      //边缘光强度值
      _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0

我们来看看这两个属性 unity的Inspector面板中我们会看到什么



颜色Color这个属性我们在前面讲过了,下面我们来解释一下这句代码

 //边缘光强度值
      _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
属性名_RimPower, unity的Inspector面板中显示的名字"Rim Power",属性类型是Range,这个类型允许我们声明一个范围的变量,例如这里我们的_RimPower值的范围是0.5到8.0之间,默认值是3.0,我们可以通过unity的Inspector面板中的对应的滑块来调整这个值。

在表面着色器函数surf中我们多了梁行代码

half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
          //赋值自发光颜色信息
          o.Emission = _RimColor.rgb * pow (rim, _RimPower);
首先我们来分析一下这行代码

half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));

normalize(..)函数表示把向量标准化,既响亮的长度变为1

dot (..)函数表示向量点乘,这里是把视图方向和法线点乘,这里得到的实际是一个夹角的余弦值。

saturate(..)函数看这里


下面我们来分析一下这句话

o.Emission = _RimColor.rgb * pow (rim, _RimPower);

pow(..)函数看这里

剩余的就好理解了,至于这两句代码为什么这么写,只能说有一部分是以前前辈的经验告诉我们这样得到的光照效果最好,其他的原因待我深入研究计算机图形学的一些东西后再来给大家分享。
我们把材质MaterialRimLighting赋值给小球后我们会看到下面的效果


我们来调整一下颜色属性即可得到我们想要的效果






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值