博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity Shader 边缘光
阅读量:783 次
发布时间:2019-03-24

本文共 2857 字,大约阅读时间需要 9 分钟。

RinLight 边缘光

核心:

根据点积来判断模型的边缘,在模型的边缘位置着色一层颜色光。

着色边缘光原理:

通过视角方向点积法线方向得到的结果,来判断该片元是否处于模型边缘,点积得到的值在0-1之间,当结果等于0时说明该片元处于模型的边缘,这个时候,视角方向与法线方向相互垂直,与切线方向共线,可以理解为,当视角方向与法线垂直,或与切线共线时,说明该片元为边缘。反之,结果越靠近1片元则越处于模型中心。因此我们可以我们可以根据点积的值来计算边缘光的强弱。

边缘光核心计算公式:

float rim =1-saturate(dot(worldNormalDir,WorldViewDir));

float3 rimColor=_RimColor*pow(rim,1/_RimPower);

开启边缘光效果:在这里插入图片描述

Shader源码:

漫反射边缘光

Shader "Unity/RimLight"{
Properties {
_MainTex ("Texture", 2D) = "white" {
} _Diffuse("Diffuse",Color) =(1,1,1,1) //边缘光颜色 _RimColor("RimColor",Color)=(1,1,1,1) _RimPower("RimPower",Range(0,1)) =0 } SubShader {
Tags {
"RenderType" = "Transparent" } Pass {
CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" sampler2D _MainTex; float4 _MainTex_ST; float4 _Diffuse; float4 _RimColor; float _RimPower; struct v2f {
float4 vertex:SV_POSITION; float2 uv:TEXCOORD0; float3 worldLightNormal:TEXCOORD1; float3 worldNormal:TEXCOORD2; float3 worldViewNormal:TEXCOORD3; }; v2f vert(appdata_base v) {
v2f o; o.vertex=UnityObjectToClipPos(v.vertex); o.uv=TRANSFORM_TEX(v.texcoord,_MainTex); float3 worldPos=mul(unity_ObjectToWorld,v.vertex); //获取世界法线 视角方向 光源防线 o.worldLightNormal= UnityWorldSpaceLightDir(worldPos); o.worldViewNormal=UnityWorldSpaceViewDir(worldPos); o.worldNormal=UnityObjectToWorldNormal(v.normal); return o; }; fixed4 frag(v2f i):SV_TARGET {
//归一化法线 因为从顶点着色器到片源着色器阶段有差值处理,所以在顶点着色器归一化并不是最好的选择 float3 worldNormalDir=normalize(i.worldNormal); float3 WorldLightDir=normalize(i.worldLightNormal); float3 WorldViewDir=normalize(i.worldViewNormal); float3 texColor=tex2D(_MainTex,i.uv).rgb; float3 ambient=UNITY_LIGHTMODEL_AMBIENT.rgb*texColor.rgb; //计算半兰伯特漫反射 float3 diffuse=_LightColor0.rgb*_Diffuse.rgb*texColor.rgb*(dot(worldNormalDir,WorldLightDir)*0.5+0.5); //计算边缘光颜色 Dot结果为0-1之间 结果越靠近0说明越靠近边缘颜色越重,故1-Dot float rim =1-saturate(dot(worldNormalDir,WorldViewDir)); //计算RimLight float3 rimColor=_RimColor*pow(rim,1/_RimPower); //输出片源颜色 float3 color=diffuse+ambient+rimColor; return fixed4(color,1); }; ENDCG } } Fallback "Diffuse"}

转载地址:http://gxtkk.baihongyu.com/

你可能感兴趣的文章