1
2 Shader "Hidden/NFAA" {
3 Properties {
4 _MainTex ("Base (RGB)", 2D) = "white" {}
5 _BlurTex ("Base (RGB)", 2D) = "white" {}
6
7 }
8
9 CGINCLUDE
10
11 #include "UnityCG.cginc"
12
13 uniform sampler2D _MainTex;
14 uniform float4 _MainTex_TexelSize;
15 uniform float _OffsetScale;
16 uniform float _BlurRadius;
17
18 struct v2f {
19 float4 pos : SV_POSITION;
20 float2 uv[8] : TEXCOORD0;
21 };
22
23 v2f vert( appdata_img v )
24 {
25 v2f o;
26 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
27
28 float2 uv = v.texcoord.xy;
29
30 float2 up = float2(0.0, _MainTex_TexelSize.y) * _OffsetScale;
31 float2 right = float2(_MainTex_TexelSize.x, 0.0) * _OffsetScale;
32
33 o.uv[0].xy = uv + up;
34 o.uv[1].xy = uv - up;
35 o.uv[2].xy = uv + right;
36 o.uv[3].xy = uv - right;
37 o.uv[4].xy = uv - right + up;
38 o.uv[5].xy = uv - right -up;
39 o.uv[6].xy = uv + right + up;
40 o.uv[7].xy = uv + right -up;
41
42 return o;
43 }
44
45 half4 frag (v2f i) : SV_Target
46 {
47 // get luminance values
48 // maybe: experiment with different luminance calculations
49 float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
50 float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
51 float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
52 float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
53 float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
54 float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
55 float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
56 float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
57
58 // 2 triangle subtractions
59 float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
60 float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
61 float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
62 float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
63
64 // figure out "normal"
65 float2 blurDir = half2((sum0-sum1), (sum3-sum2));
66 blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
67
68 // reconstruct normal uv
69 float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
70
71 float4 returnColor = tex2D(_MainTex, uv_);
72 returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
73 returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
74 returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
75 returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
76
77 return returnColor * 0.2;
78 }
79
80 half4 fragDebug (v2f i) : SV_Target
81 {
82 // get luminance values
83 // maybe: experiment with different luminance calculations
84 float topL = Luminance( tex2D(_MainTex, i.uv[0]).rgb );
85 float bottomL = Luminance( tex2D(_MainTex, i.uv[1]).rgb );
86 float rightL = Luminance( tex2D(_MainTex, i.uv[2]).rgb );
87 float leftL = Luminance( tex2D(_MainTex, i.uv[3]).rgb );
88 float leftTopL = Luminance( tex2D(_MainTex, i.uv[4]).rgb );
89 float leftBottomL = Luminance( tex2D(_MainTex, i.uv[5]).rgb );
90 float rightBottomL = Luminance( tex2D(_MainTex, i.uv[6]).rgb );
91 float rightTopL = Luminance( tex2D(_MainTex, i.uv[7]).rgb );
92
93 // 2 triangle subtractions
94 float sum0 = dot(float3(1,1,1), float3(rightTopL,bottomL,leftTopL));
95 float sum1 = dot(float3(1,1,1), float3(leftBottomL,topL,rightBottomL));
96 float sum2 = dot(float3(1,1,1), float3(leftTopL,rightL,leftBottomL));
97 float sum3 = dot(float3(1,1,1), float3(rightBottomL,leftL,rightTopL));
98
99 // figure out "normal"
100 float2 blurDir = half2((sum0-sum1), (sum3-sum2));
101 blurDir *= _MainTex_TexelSize.xy * _BlurRadius;
102
103 // reconstruct normal uv
104 float2 uv_ = (i.uv[0] + i.uv[1]) * 0.5;
105
106 float4 returnColor = tex2D(_MainTex, uv_);
107 returnColor += tex2D(_MainTex, uv_+ blurDir.xy);
108 returnColor += tex2D(_MainTex, uv_ - blurDir.xy);
109 returnColor += tex2D(_MainTex, uv_ + float2(blurDir.x, -blurDir.y));
110 returnColor += tex2D(_MainTex, uv_ - float2(blurDir.x, -blurDir.y));
111
112 blurDir = half2((sum0-sum1), (sum3-sum2)) * _BlurRadius;
113 return half4(normalize( half3(blurDir,1) * 0.5 + 0.5), 1);
114 return returnColor * 0.2;
115 }
116
117 ENDCG
118
119 SubShader {
120 Pass {
121 ZTest Always Cull Off ZWrite Off
122
123 CGPROGRAM
124
125 #pragma vertex vert
126 #pragma fragment frag
127 #pragma exclude_renderers d3d11_9x
128
129 ENDCG
130 }
131 Pass {
132 ZTest Always Cull Off ZWrite Off
133
134 CGPROGRAM
135
136 #pragma vertex vert
137 #pragma fragment fragDebug
138 #pragma exclude_renderers d3d11_9x
139
140 ENDCG
141 }
142 }
143
144 Fallback off
145
146 }