之前写的一个类似Photoshop中的图层的 内发光 效果
管线:built-in 管线
unity 版本:2019.4.30f1
思路
- 得到内轮廓边缘:只要某个像素的 kernal size 范围内的,如 5x5 的 kernal size,只要某个 pixel(x,y) 像素不是全黑,并且 kernal size 核内的 sum 值小于 kernal size 平方,都算是边缘
- 将内轮廓边缘模糊
- 将模糊的边缘与 _SrcTex 做像素交集才显示
Shader
// jave.lin 2021/02/25
Shader "PP/InnerGlowPP"
{
CGINCLUDE
#include "UnityCG.cginc"
// pure col
float4 vert_pure_col(float4 vertex : POSITION) : SV_POSITION
{
return UnityObjectToClipPos(vertex);
}
fixed4 frag_pure_col() : SV_Target
{
return 1;
}
// inner glow
Sampler2D _InnerGlowOrginTex;
float4 _InnerGlowOrginTex_TexelSize;
F _InnerGlowKernelSize;
F _InnerGlowSize;
struct a2v_inner_glow
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f_inner_glow
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f_inner_glow vert_inner_glow (a2v_inner_glow v) {
v2f_inner_glow o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag_inner_glow(v2f_inner_glow i) : SV_Target
{
fixed originV = 0;
F sum = 0;
int start = -_InnerGlowKernelSize;
int count = _InnerGlowKernelSize + 1;
int delta = count - start;
int threhold = delta * delta;
for (int x = start; x < count; x++)
{
for (int y = start; y < count; y++)
{
float2 temp_uv = i.uv + float2(x, y) * _InnerGlowOrginTex_TexelSize.xy * _InnerGlowSize;
fixed v = tex2D(_InnerGlowOrginTex, temp_uv);
if (x == 0 && y == 0) originV = v;
sum += v;
}
}
return originV > 0 && sum < threhold ? 1 : 0;
}
/////////////// blur /////////////////
struct a2v_blur
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f_blur
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float4 uv01 : TEXCOORD1;
float4 uv23 : TEXCOORD2;
};
Sampler2D _BlurOrginTex;
float4 _BlurOrginTex_TexelSize;
F _BlurSize;
v2f_blur vert_blur_h (a2v_blur v) {
v2f_blur o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
float2 ts = _BlurOrginTex_TexelSize.xy;
float2 offset1 = float2(1, 0);
float2 offset2 = float2(2, 0);
o.uv01.xy = v.uv + offset1 * ts * _BlurSize; // 左1
o.uv01.zw = v.uv + offset1 * -ts * _BlurSize; // 右1
o.uv23.xy = v.uv + offset2 * ts * _BlurSize; // 左2
o.uv23.zw = v.uv + offset2 * -ts * _BlurSize; // 右2
return o;
}
v2f_blur vert_blur_v (a2v_blur v) {
v2f_blur o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
float2 ts = _BlurOrginTex_TexelSize.xy;
float2 offset1 = float2(0, 1);
float2 offset2 = float2(0, 2);
o.uv01.xy = v.uv + offset1 * ts * _BlurSize; // 上1
o.uv01.zw = v.uv + offset1 * -ts * _BlurSize; // 下1
o.uv23.xy = v.uv + offset2 * ts * _BlurSize; // 上2
o.uv23.zw = v.uv + offset2 * -ts * _BlurSize; // 下2
return o;
}
fixed4 frag_blur (v2f_blur i) : SV_Target {
fixed4 sum = tex2D(_BlurOrginTex, i.uv) * 0.4026;
sum += tex2D(_BlurOrginTex, i.uv01.xy) * 0.2442; // 左1 | 上1
sum += tex2D(_BlurOrginTex, i.uv01.zw) * 0.2442; // 右1 | 下1
sum += tex2D(_BlurOrginTex, i.uv23.xy) * 0.0545; // 左2 | 上2
sum += tex2D(_BlurOrginTex, i.uv23.zw) * 0.0545; // 右2 | 下2
return sum;
}
/////////////// final /////////////////
Sampler2D _MaskTex;
Sampler2D _BlurTex;
Sampler2D _SrcTex;
fixed4 _InnerGlowColor;
struct a2v_final
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f_final
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f_final vert_final (a2v_final v) {
v2f_final o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag_final (v2f_final i) : SV_Target {
fixed blur_col = tex2D(_BlurTex, i.uv).r;
fixed mask_col = tex2D(_MaskTex, i.uv).r;
blur_col *= (mask_col > 0 ? 1 : 0);
fixed4 combinedCol = saturate(tex2D(_SrcTex, i.uv));
combinedCol.rgb += (blur_col * _InnerGlowColor.a) * _InnerGlowColor.rgb;
return combinedCol;
}
ENDCG
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass // pure col 0
{
ColorMask R
CGPROGRAM
#pragma vertex vert_pure_col

最低0.47元/天 解锁文章
7112

被折叠的 条评论
为什么被折叠?



