RPG游戏里现在基本都会有捏脸功能,捏脸也肯定会有妆容的选择。而在妆容上,比如眼妆,或者唇彩,加上blingbling的亮片效果会出色不少。
亮片效果:
主要实现思路就是用视角与法线的点积作为offset去干扰noise贴图的采样,这样noise贴图就会随着视角而变化了。
float ndotv = dot(normal, viewDir);
half noise0 = tex2D(_NoiseTex, half2(i.uv.x + ndotv, i.uv.y)).r;
half noise1 = tex2D(_NoiseTex, half2(i.uv.x, i.uv.y + ndotv)).r;
把两次求得的noise相乘,并做幂运算,使亮片更精细,得到亮度值
float sparkle = pow(noise0 * noise1, _Sparkle);
除此之外,注视中心的范围的亮片也会更亮。通过视角与法线的点积的幂运算,简易求得高光范围。
float highlight = pow(ndotv, _HighlightRange);
最后把亮片颜色与亮度值以及高光范围相乘,并加上初始颜色即可。
half3 sparkleColor = sparkle * _SparkleColor.rgb * highlight;
half3 finalColor = _Color.rgb + sparkleColor;
Shader全部代码:
Shader "Custom/Actor/Sparkle"
{
Properties
{
_NoiseTex ("Noise Tex", 2D) = "white" {
}
_Color ("Color", Color) = (1,1,1,1)
_Sparkle ("_Sparkle", Range(0.75, 5)) = 1
_HighlightRange ("Highlight Range", Range(0, 5)) = 1
[HDR]_SparkleColor ("Sparkle Color", Color) = (1,1,1,1)
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 200
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _NoiseTex;
float4 _NoiseTex_ST;
half4 _Color;
float _Sparkle;
half4 _SparkleColor;
float _HighlightRange;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 normal : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float2 uv : TEXCOORD2;
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.normal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _NoiseTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
half3 normal = normalize(i.normal);
half3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
float ndotv = dot(normal, viewDir);
half noise0 = tex2D(_NoiseTex, half2(i.uv.x + ndotv, i.uv.y)).r;
half noise1 = tex2D(_NoiseTex, half2(i.uv.x, i.uv.y + ndotv)).r;
float sparkle = pow(noise0 * noise1, _Sparkle);
float highlight = pow(ndotv, _HighlightRange);
half3 sparkleColor = sparkle * _SparkleColor.rgb * highlight;
return half4(_Color.rgb + sparkleColor, _Color.a);
}
ENDCG
}
}
}