先上效果
结果看起来是一样的,你肯定好奇为啥要用两种方式实现呢?其实我之前也是这样想的,直到遇到了一个诡异的需求?一个模型有两个部分本来都用的同一个shader实现,但是呢需求方需要下半部分要用菲涅尔的半透效果?上半部门呢不能有透明效果但是需要边缘光,如果修改本身的菲涅尔效果会影响到其它地方,不使用的话实现这个需求有点困难我此时内心wcccccc.?所以就又研究了一下另一种边缘光效果?最后完美的实现了,因为公司项目保密最终效果无法展示.
?下面是菲涅尔边缘光shader代码
Shader "Custom/Shader-边缘光"
{
Properties
{
_MainColor ("MainColor", Color) = (1,1,1,1)
_FrenelsColor("FrenelsColor",Color) = (1,1,1,1)
_FrenelsPower("FrenelsPower",Range(0.1,10)) =1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct VertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1;
};
float4 _MainColor;
float4 _FrenelsColor;
float _FrenelsPower;
VertexOutput vert (VertexInput v)
{
VertexOutput o = (VertexOutput)0;
o.normalDir = UnityObjectToWorldNormal(v.normal);
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos( v.vertex );
return o;
}
float4 frag(VertexOutput i) : COLOR
{
i.normalDir = normalize(i.normalDir);
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
float3 normalDirection = i.normalDir;
float3 emissive = (_FrenelsColor.rgb*pow(1.0-max(0,dot(normalDirection, viewDirection)),_FrenelsPower))+_MainColor.rgb;
return fixed4(emissive,1);
}
ENDCG
}
}
}
这个是RimColor的Shader代码
Shader "Custom/Shader-边缘光RimColor"
{
Properties
{
_MainColor("MainColor",Color)=(0,0,0,1)
_RimColor("RimColor", Color) = (0,0,0,1)
_RimPower("RimPower", Range(0.0001, 5.0)) = 0.0001
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct VertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct VertexOutput {
float4 pos : SV_POSITION;
float4 posWorld : TEXCOORD0;
float3 normalDir : TEXCOORD1;
};
fixed4 _MainColor;
fixed4 _RimColor;
float _RimPower;
VertexOutput vert (VertexInput v)
{
VertexOutput o = (VertexOutput)0;
o.normalDir = UnityObjectToWorldNormal(v.normal);
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
o.pos = UnityObjectToClipPos( v.vertex );
return o;
}
float4 frag(VertexOutput i) : COLOR
{
i.normalDir = normalize(i.normalDir);
float3 normalDirection = i.normalDir;
float3 viewReflectDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
float rim = 1 - max(0, dot(viewReflectDirection, normalDirection));
fixed3 rimColor = _RimColor * pow(rim, 1 / _RimPower);
return fixed4(rimColor+_MainColor.rgb,1);
}
ENDCG
}
}
}
这个是基础版?需要什么效果直接在上面堆功能就行啦!
|