unityshader shaderforge 轮廓内发光

来源:互联网 发布:淘宝卖家账号怎么注销 编辑:程序博客网 时间:2024/06/05 04:05

本篇使用unity shaderforge插件和编写unity shader code两种方式来实现轮廓内发光

发光效果

内发光:发光效果不能超出模型的范围,模型中心最暗向着边缘方向逐渐变亮
innerGlow

内发光效果的实现原理:

  • 我们要塑造物体边缘反射光比较亮,物体中央反射光比较暗的效果,这里给出两种实现方法:
    1)将物体法线(Normal Dir)和视角(View Dir)点积,得到从视角看过去从中心最亮逐渐衰减的效果,再做一个1减的操作,最终得到中间最暗逐渐变亮的效果
    2)使用菲涅尔法线
  • 边缘颜色:
    乘以颜色值
  • 边缘光强度:
    乘以强度值
    垂直于表面时,反射较弱,而当视线非垂直表面时,夹角越小,反射越明显。如果你看向一个圆球,那圆球中心的反射较弱,靠近边缘较强,这就是“菲涅尔效应”。

shaderforge实现内发光:

设定灯光模式(使用自定义灯光,不接受环境光)

设定方式有两种 1)直接创建customlighting shader 2)创建shader,在Lighting属性栏中将Light Mode设定为Unlit/Custom

绘制节点树,自定义灯光

方案1 使用视角法线和物体表面法线实现轮廓光

  • Geometry Data->fresnel从物体上获取fresnel反射
  • Fresnel乘以color,乘以强度
  • 乘法结果+texture2d->输出到custom lighting

normalview

方案2 菲涅尔边缘发光

  • Geometry Data->Normal Dir.和Geometry Data->View Dir.做点积操作
  • One Minus点积值
  • 乘以color乘以发光强度
  • 乘法结果+tecture2d->输出到custom lighting

fresnel

然后将shaderforge生成的shader加载到物体的material上,模型就会有内发光效果了!!!
qiushader propertyhuoxing

手写Unity Shader实现内发光

对着shaderforge生成的shader练习自己写unity shader

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Shader Learn/InneGlow" { //Shader文件索引路径    //属性    Properties    {        _MainTex("main tex", 2D) = "gray"{} //表面贴图        [HDR]_RimColor("rim color", Color) = (0.7426471, 0.07644895, 0.07644895, 1)//边缘颜色        _RimPower("rim power", range(1, 10)) = 2//边缘强度    }    SubShader        {            // Pass通道主要是解决一些顶点和片段着色器功能            Pass            {                //CG程序开始                CGPROGRAM//声明顶点着色器函数为vert#pragma vertex vert//声明片段着色器函数为frag#pragma fragment frag#include"UnityCG.cginc"                //顶点着色器的输入                struct VertexInput                {                    float4 vertex:POSITION;                    float3 normal:NORMAL;                    float4 texcoord:TEXCOORD0;                };                //顶点着色器的输出                struct VertexOutput                {                    float4 vertex:POSITION;                    float4 uv:TEXCOORD0;                    float4 NdotV:COLOR;                };                sampler2D _MainTex;                float4 _RimColor;                float _RimPower;                //顶点着色器函数                VertexOutput vert(VertexInput v)                {                    VertexOutput o;                    o.vertex = UnityObjectToClipPos(v.vertex);                    o.uv = v.texcoord;                    float3 V = WorldSpaceViewDir(v.vertex);                        V = mul(unity_WorldToObject, V);//视方向从世界到模型坐标系的转换                    o.NdotV.x = dot(v.normal, normalize(V));//必须在同一坐标系才能正确做点乘运算                    return o;                }                //片段着色器函数                float4 frag(VertexOutput IN) :COLOR                {                    float4 c = tex2D(_MainTex, IN.uv);                    //用视方向和法线方向做点乘,越边缘的地方,法线和视方向越接近90度,点乘越接近0.                    //用(1- 上面点乘的结果)*颜色,来反映边缘颜色情况                    c.rgb += (1 - IN.NdotV.x)* _RimPower * _RimColor.rgb;                    return c;                }                    //CG程序结束                    ENDCG            }        }        FallBack "Diffuse"}

可以实现同样的效果!
我们可以使用shaderforge快速直观的调出我们想要的效果,但是如果遇到效率问题还是需要自己去优化shader代码!

参考:

角色内发光
shaderforge发光
Shader实例:边缘发光和描边

以上,
我们已经实现了轮廓内发光shader,接下来我们再进一步,在轮廓内发光的基础上加上从中心向四周衰减的色彩光

效果

这里写图片描述

节点树

在轮廓内发光的基础上加上(1减fresnel)*color
这里写图片描述

原创粉丝点击