Shader知识普及之:实现边缘高亮效果
我们经常会看到很多游戏中出现类似模型边缘发光的效果,给人一种科技感爆棚高大上的感觉,其实用shader实现起来还是蛮简单的,本篇我们大家一起来看一下边缘发光(高亮)效果的实现。
本篇还是以Unity的一段实例代码开始:
Shader "Custom/Rim Light" {
Properties {
_MainTex("Base (RGB)", 2D) = "white" {}
_RimColor("_RimColor", Color) =(0.81,0.17,0.30,0.0)
_RimWidth("_RimWidth", Range(0.6,9.0)) = 0.9
}
SubShader {
Tags{ "RenderType" = "Opaque"}
LOD 150
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
float3 viewDir;
};
sampler2D _MainTex;
fixed4 _RimColor;
fixed _RimWidth;
void surf (Input IN, inout SurfaceOutput o) {
fixed4 t = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = t.rgb;
o.Alpha = t.a;
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission= _RimColor.rgb * pow (rim, _RimWidth);
}
ENDCG
}
Fallback "Diffuse"
}
现在我们对代码中的定义的变量做一下解释和说明:
_MainTex:2D纹理图片
_RimColor:高亮边缘呈现的颜色
_RimWidth:高亮光的宽度,也可以理解为高光强度
Tags{ "RenderType" = "Opaque"}:渲染的类型为Opaque,即不透明
CGPROGRAM:开始CG着色器编程语言段
#pragma surface surf Lambert:使用兰伯特光照模式
struct Input:输入结构
float2 uv_MainTex:纹理贴图
float2 uv_BumpMap:法线贴图
float3 viewDir:观察方向
sampler2D _MainTex:主纹理
sampler2D _BumpMap:凹凸纹理
float4 _RimColor:边缘颜色
float _RimPower:边缘颜色的强度
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):边缘颜色强度
ENDCG:结束CG着色器编程语言段
Fallback "Diffuse":当我们的shader无法运行时即执行Diffuse Shader
我们观察代码可以发现,对高亮效果其决定性作用的语句是如下两句代码
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
o.Emission= _RimColor.rgb * pow (rim, _RimWidth);
逻辑就是以视角方向和模型各位置着手区分当前位置是否处于边缘或中心。
老规矩,我们在Unity中新建一个默认的球体,将shader文件拖到我们新创建的材质球中(上一篇文中我们有详细的操作,这里就不做图片演示了),观察效果如下:
感觉边缘过渡过渡太平滑,不是很陡峭,想一想我们之前定义过边缘光的强度_RimWidth,还有边缘光呈现的颜色参数_RimColor,找一下球体的材质组件,我们找到了这两个参数:
我们来修改一下这两个参数,看一下效果的变化如何:将边缘颜色修改为草绿色,边缘发光强度修改为2.4,这时我们再来看一下球体的表面颜色发光情况:
这样外发光效果就感觉很明显了,小伙伴们快把代码放到Unity里运行一下,一个炫彩夺目的外边缘发光shader在等着你哦!
页:
[1]