边缘光在游戏中是很常用到的,比如角色受到攻击,模型边缘会有一圈红色的边框,这些都是边缘光得到的奇妙效果。下图展现了边缘光的效果
边缘关的原理如下图所示
代码如下图
- Shader "Custom/Rim" {
- Properties {
- //对边缘光做一个衰减
- _Scale("RIM_SCALE", range(1, 8)) = 2
- }
- SubShader {
- pass{
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "unitycg.cginc"
- float _Scale;
- struct v2f{
- float4 pos: SV_POSITION;
- float3 normal: TEXCOORD0;
- float4 vertex: TEXCOORD1;
- };
- //收集模型法线和顶点,并返回
- v2f vert(appdata_base v){
- v2f vf;
- vf.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- vf.normal = v.normal;
- vf.vertex = v.vertex;
- return vf;
- }
- fixed4 frag(v2f IN):color{
- //下面的两个函数都是unitycg.cginc的,
- //UnityObjectToWorldNorm 作用是把 法线 转到 世界空间
- float3 N = UnityObjectToWorldNorm(IN.normal);
- //WorldSpaceViewDir 作用是计算相机到物体定点的向量
- float3 V = WorldSpaceViewDir(IN.vertex);
- V=normalize(V);
- //计算边缘光
- float bright = 1 - saturate(dot(N, V));
- //衰减计算
- bright = pow(bright, _Scale);
- //返回固定色
- return fixed4(1,1,1,1) * bright;
- }
- ENDCG
- }
- }
- }
然后可以通过简单的代码进行shader的切换,进行模拟角色被攻击的效果 (略)
可能还有这样一个情景,当角色受到攻击的时候,不仅要边缘高光,而且可以从身体看穿,看到身后的物体,这样可以增加真实感。这里实现这个其实很简单 (如下效果)
左边的是边缘光带透明的,右边是只有边缘光的 代码如下,只需要加入简单的混合方式和 队列顺序
- Shader "Custom/Rim_tranpernet" {
- Properties {
- _Scale("RIM_SCALE", range(1, 8)) = 2
- }
- SubShader {
- //渲染队列为透明
- tags {"Queue" = "Transparent"}
- pass{
- //混合方式
- Blend SrcAlpha oneMinusSrcAlpha
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "unitycg.cginc"
- float _Scale;
- struct v2f{
- float4 pos: SV_POSITION;
- float3 normal: TEXCOORD0;
- float4 vertex: TEXCOORD1;
- };
- v2f vert(appdata_base v){
- v2f vf;
- vf.pos = mul(UNITY_MATRIX_MVP, v.vertex);
- vf.normal = v.normal;
- vf.vertex = v.vertex;
- return vf;
- }
- fixed4 frag(v2f IN):color{
- float3 N = UnityObjectToWorldNorm(IN.normal);
- float3 V = WorldSpaceViewDir(IN.vertex);
- V=normalize(V);
- float bright = 1 - saturate(dot(N, V));
- bright = pow(bright, _Scale);
- return fixed4(1,1,1,1) * bright;
- }
- ENDCG
- }
- }
- }