1 Shader "Hidden/FXAA Preset 3" {
2 Properties {
3     _MainTex (
"Base (RGB)", 2D) = "white" {}
4 }
5
6 SubShader {
7     Pass {
8         ZTest Always Cull Off ZWrite Off
9
10 CGPROGRAM
11 #pragma vertex vert
12 #pragma fragment frag
13 #include
"UnityCG.cginc"
14 #pragma target
3.0
15
16 // Not very practical
on consoles/mobile, and PS3 Cg takes ages to compile this :(
17 #pragma exclude_renderers xbox360 ps3 gles
18
19 #define FXAA_HLSL_3
1
20 #define FXAA_PRESET
3
21
22
23 // Copyright (c)
2010 NVIDIA Corporation. All rights reserved.
24 //
25 // TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
26 // *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
27 // OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
28 // AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
29 // BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
30 // WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
31 // BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
32 // ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
33 // BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34
35 /*============================================================================
36  
37                                     FXAA
38  
39 ============================================================================*/

40  

41 /*============================================================================
42                                  API PORTING
43 ============================================================================*/

44 #ifndef FXAA_GLSL_120
45     #define FXAA_GLSL_120
0
46 #endif
47 #ifndef FXAA_GLSL_130
48     #define FXAA_GLSL_130
0
49 #endif
50 #ifndef FXAA_HLSL_3
51     #define FXAA_HLSL_3
0
52 #endif
53 #ifndef FXAA_HLSL_4
54     #define FXAA_HLSL_4
0
55 #endif

56 /*--------------------------------------------------------------------------*/

57 #
if FXAA_GLSL_120
58     
// Requires,
59     
// #version 120
60     
// #extension GL_EXT_gpu_shader4 : enable
61     #define int2 ivec2
62     #define float2 vec2
63     #define float3 vec3
64     #define float4 vec4
65     #define FxaaBool3 bvec3
66     #define FxaaInt2 ivec2
67     #define FxaaFloat2 vec2
68     #define FxaaFloat3 vec3
69     #define FxaaFloat4 vec4
70     #define FxaaBool2Float(a) mix(
0.0, 1.0, (a))
71     #define FxaaPow3(x, y) pow(x, y)
72     #define FxaaSel3(f, t, b) mix((f), (t), (b))
73     #define FxaaTex sampler2D
74 #endif

75 /*--------------------------------------------------------------------------*/

76 #
if FXAA_GLSL_130
77     
// Requires "#version 130" or better
78     #define int2 ivec2
79     #define float2 vec2
80     #define float3 vec3
81     #define float4 vec4
82     #define FxaaBool3 bvec3
83     #define FxaaInt2 ivec2
84     #define FxaaFloat2 vec2
85     #define FxaaFloat3 vec3
86     #define FxaaFloat4 vec4
87     #define FxaaBool2Float(a) mix(
0.0, 1.0, (a))
88     #define FxaaPow3(x, y) pow(x, y)
89     #define FxaaSel3(f, t, b) mix((f), (t), (b))
90     #define FxaaTex sampler2D
91 #endif

92 /*--------------------------------------------------------------------------*/

93 #
if FXAA_HLSL_3
94     #define int2 float2
95     #define FxaaInt2 float2
96     #define FxaaFloat2 float2
97     #define FxaaFloat3 float3
98     #define FxaaFloat4 float4
99     #define FxaaBool2Float(a) (a)
100     #define FxaaPow3(x, y) pow(x, y)
101     #define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
102     #define FxaaTex sampler2D
103 #endif

104 /*--------------------------------------------------------------------------*/

105 #
if FXAA_HLSL_4
106     #define FxaaInt2 int2
107     #define FxaaFloat2 float2
108     #define FxaaFloat3 float3
109     #define FxaaFloat4 float4
110     #define FxaaBool2Float(a) (a)
111     #define FxaaPow3(x, y) pow(x, y)
112     #define FxaaSel3(f, t, b) ((f)*(!b) + (t)*(b))
113     
struct FxaaTex { SamplerState smpl; Texture2D tex; };
114 #endif

115 /*--------------------------------------------------------------------------*/

116 #define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))

117 /*--------------------------------------------------------------------------*/

118 float4 FxaaTexLod0(FxaaTex tex, float2 pos) {
119     #
if FXAA_GLSL_120
120         
return texture2DLod(tex, pos.xy, 0.0);
121     #endif
122     #
if FXAA_GLSL_130
123         
return textureLod(tex, pos.xy, 0.0);
124     #endif
125     #
if FXAA_HLSL_3
126         
return tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
127     #endif
128     #
if FXAA_HLSL_4
129         
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0);
130     #endif
131 }

132 /*--------------------------------------------------------------------------*/

133 float4 FxaaTexGrad(FxaaTex tex, float2 pos, float2 grad) {
134     #
if FXAA_GLSL_120
135         
return texture2DGrad(tex, pos.xy, grad, grad);
136     #endif
137     #
if FXAA_GLSL_130
138         
return textureGrad(tex, pos.xy, grad, grad);
139     #endif
140     #
if FXAA_HLSL_3
141         
return tex2Dgrad(tex, pos.xy, grad, grad);
142     #endif
143     #
if FXAA_HLSL_4
144         
return tex.tex.SampleGrad(tex.smpl, pos.xy, grad, grad);
145     #endif
146 }

147 /*--------------------------------------------------------------------------*/

148 float4 FxaaTexOff(FxaaTex tex, float2 pos, int2 off, float2 rcpFrame) {
149     #
if FXAA_GLSL_120
150         
return texture2DLodOffset(tex, pos.xy, 0.0, off.xy);
151     #endif
152     #
if FXAA_GLSL_130
153         
return textureLodOffset(tex, pos.xy, 0.0, off.xy);
154     #endif
155     #
if FXAA_HLSL_3
156         
return tex2Dlod(tex, float4(pos.xy + (off * rcpFrame), 0, 0));
157     #endif
158     #
if FXAA_HLSL_4
159         
return tex.tex.SampleLevel(tex.smpl, pos.xy, 0.0, off.xy);
160     #endif
161 }

162
163 /*============================================================================
164                                  SRGB KNOBS
165 ------------------------------------------------------------------------------
166 FXAA_SRGB_ROP - Set to
1 when applying FXAA to an sRGB back buffer (DX10/11).
167                 This will
do the sRGB to linear transform,
168                 
as ROP will expect linear color from this shader,
169                 and
this shader works in non-linear color.
170 ============================================================================*/

171 #define FXAA_SRGB_ROP
0
172
173 /*============================================================================
174                                 DEBUG KNOBS
175 ------------------------------------------------------------------------------
176 All debug knobs draw FXAA-untouched pixels
in FXAA computed luma (monochrome).
177  
178 FXAA_DEBUG_PASSTHROUGH - Red
for pixels which are filtered by FXAA with a
179                          yellow tint
on sub-pixel aliasing filtered by FXAA.
180 FXAA_DEBUG_HORZVERT - Blue
for horizontal edges, gold for vertical edges.
181 FXAA_DEBUG_PAIR - Blue/green
for the 2 pixel pair choice.
182 FXAA_DEBUG_NEGPOS - Red/blue
for which side of center of span.
183 FXAA_DEBUG_OFFSET - Red/blue
for -/+ x, gold/skyblue for -/+ y.
184 ============================================================================*/

185 #ifndef FXAA_DEBUG_PASSTHROUGH
186     #define FXAA_DEBUG_PASSTHROUGH
0
187 #endif
188 #ifndef FXAA_DEBUG_HORZVERT
189     #define FXAA_DEBUG_HORZVERT
0
190 #endif
191 #ifndef FXAA_DEBUG_PAIR
192     #define FXAA_DEBUG_PAIR
0
193 #endif
194 #ifndef FXAA_DEBUG_NEGPOS
195     #define FXAA_DEBUG_NEGPOS
0
196 #endif
197 #ifndef FXAA_DEBUG_OFFSET
198     #define FXAA_DEBUG_OFFSET
0
199 #endif

200 /*--------------------------------------------------------------------------*/

201 #
if FXAA_DEBUG_PASSTHROUGH || FXAA_DEBUG_HORZVERT || FXAA_DEBUG_PAIR
202     #define FXAA_DEBUG
1
203 #endif
204 #
if FXAA_DEBUG_NEGPOS || FXAA_DEBUG_OFFSET
205     #define FXAA_DEBUG
1
206 #endif
207 #ifndef FXAA_DEBUG
208     #define FXAA_DEBUG
0
209 #endif
210   

211 /*============================================================================
212                               COMPILE-IN KNOBS
213 ------------------------------------------------------------------------------
214 FXAA_PRESET - Choose compile-
in knob preset 0-5.
215 ------------------------------------------------------------------------------
216 FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required
217                       to apply algorithm.
218                       
1.0/3.0 - too little
219                       
1.0/4.0 - good start
220                       
1.0/8.0 - applies to more edges
221                       
1.0/16.0 - overkill
222 ------------------------------------------------------------------------------
223 FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm
from processing darks.
224                           Perf optimization.
225                           
1.0/32.0 - visible limit (smaller isn't visible)
226                           
1.0/16.0 - good compromise
227                           
1.0/12.0 - upper limit (seeing artifacts)
228 ------------------------------------------------------------------------------
229 FXAA_SEARCH_STEPS - Maximum number of search steps
for end of span.
230 ------------------------------------------------------------------------------
231 FXAA_SEARCH_ACCELERATION - How much to accelerate search,
232                            
1 - no acceleration
233                            
2 - skip by 2 pixels
234                            
3 - skip by 3 pixels
235                            
4 - skip by 4 pixels
236 ------------------------------------------------------------------------------
237 FXAA_SEARCH_THRESHOLD - Controls
when to stop searching.
238                         
1.0/4.0 - seems to be the best quality wise
239 ------------------------------------------------------------------------------
240 FXAA_SUBPIX_FASTER - Turn
on lower quality but faster subpix path.
241                      Not recomended, but used
in preset 0.
242 ------------------------------------------------------------------------------
243 FXAA_SUBPIX - Toggle subpix filtering.
244               
0 - turn off
245               
1 - turn on
246               
2 - turn on full (ignores FXAA_SUBPIX_TRIM and CAP)
247 ------------------------------------------------------------------------------
248 FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal.
249                    
1.0/2.0 - low removal
250                    
1.0/3.0 - medium removal
251                    
1.0/4.0 - default removal
252                    
1.0/8.0 - high removal
253                    
0.0 - complete removal
254 ------------------------------------------------------------------------------
255 FXAA_SUBPIX_CAP - Insures fine detail
is not completely removed.
256                   This
is important for the transition of sub-pixel detail,
257                   like fences and wires.
258                   
3.0/4.0 - default (medium amount of filtering)
259                   
7.0/8.0 - high amount of filtering
260                   
1.0 - no capping of sub-pixel aliasing removal
261 ============================================================================*/

262 #ifndef FXAA_PRESET
263     #define FXAA_PRESET
3
264 #endif

265 /*--------------------------------------------------------------------------*/

266 #
if (FXAA_PRESET == 0)
267     #define FXAA_EDGE_THRESHOLD (
1.0/4.0)
268     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/12.0)
269     #define FXAA_SEARCH_STEPS
2
270     #define FXAA_SEARCH_ACCELERATION
4
271     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
272     #define FXAA_SUBPIX
1
273     #define FXAA_SUBPIX_FASTER
1
274     #define FXAA_SUBPIX_CAP (
2.0/3.0)
275     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
276 #endif

277 /*--------------------------------------------------------------------------*/

278 #
if (FXAA_PRESET == 1)
279     #define FXAA_EDGE_THRESHOLD (
1.0/8.0)
280     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/16.0)
281     #define FXAA_SEARCH_STEPS
4
282     #define FXAA_SEARCH_ACCELERATION
3
283     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
284     #define FXAA_SUBPIX
1
285     #define FXAA_SUBPIX_FASTER
0
286     #define FXAA_SUBPIX_CAP (
3.0/4.0)
287     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
288 #endif

289 /*--------------------------------------------------------------------------*/

290 #
if (FXAA_PRESET == 2)
291     #define FXAA_EDGE_THRESHOLD (
1.0/8.0)
292     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/24.0)
293     #define FXAA_SEARCH_STEPS
8
294     #define FXAA_SEARCH_ACCELERATION
2
295     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
296     #define FXAA_SUBPIX
1
297     #define FXAA_SUBPIX_FASTER
0
298     #define FXAA_SUBPIX_CAP (
3.0/4.0)
299     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
300 #endif

301 /*--------------------------------------------------------------------------*/

302 #
if (FXAA_PRESET == 3)
303     #define FXAA_EDGE_THRESHOLD (
1.0/8.0)
304     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/24.0)
305     #define FXAA_SEARCH_STEPS
16
306     #define FXAA_SEARCH_ACCELERATION
1
307     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
308     #define FXAA_SUBPIX
1
309     #define FXAA_SUBPIX_FASTER
0
310     #define FXAA_SUBPIX_CAP (
3.0/4.0)
311     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
312 #endif

313 /*--------------------------------------------------------------------------*/

314 #
if (FXAA_PRESET == 4)
315     #define FXAA_EDGE_THRESHOLD (
1.0/8.0)
316     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/24.0)
317     #define FXAA_SEARCH_STEPS
24
318     #define FXAA_SEARCH_ACCELERATION
1
319     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
320     #define FXAA_SUBPIX
1
321     #define FXAA_SUBPIX_FASTER
0
322     #define FXAA_SUBPIX_CAP (
3.0/4.0)
323     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
324 #endif

325 /*--------------------------------------------------------------------------*/

326 #
if (FXAA_PRESET == 5)
327     #define FXAA_EDGE_THRESHOLD (
1.0/8.0)
328     #define FXAA_EDGE_THRESHOLD_MIN (
1.0/24.0)
329     #define FXAA_SEARCH_STEPS
32
330     #define FXAA_SEARCH_ACCELERATION
1
331     #define FXAA_SEARCH_THRESHOLD (
1.0/4.0)
332     #define FXAA_SUBPIX
1
333     #define FXAA_SUBPIX_FASTER
0
334     #define FXAA_SUBPIX_CAP (
3.0/4.0)
335     #define FXAA_SUBPIX_TRIM (
1.0/4.0)
336 #endif

337 /*--------------------------------------------------------------------------*/

338 #define FXAA_SUBPIX_TRIM_SCALE (
1.0/(1.0 - FXAA_SUBPIX_TRIM))
339
340 /*============================================================================
341                                    HELPERS
342 ============================================================================*/
343 // Return the luma, the estimation of luminance
from rgb inputs.
344 // This approximates luma
using one FMA instruction,
345 // skipping normalization and tossing
out blue.
346 // FxaaLuma() will range
0.0 to 2.963210702.
347 float
FxaaLuma(float3 rgb) {
348     
return rgb.y * (0.587/0.299) + rgb.x; }
349 /*--------------------------------------------------------------------------*/

350 float3 FxaaLerp3(float3 a, float3 b,
float amountOfA) {
351     
return (FxaaToFloat3(-amountOfA) * b) +
352         ((a * FxaaToFloat3(amountOfA)) + b); }

353 /*--------------------------------------------------------------------------*/
354 // Support any extra filtering before returning color.

355 float3 FxaaFilterReturn(float3 rgb) {
356     #
if FXAA_SRGB_ROP
357         
// Do sRGB encoded value to linear conversion.
358         
return FxaaSel3(
359             rgb * FxaaToFloat3(
1.0/12.92),
360             FxaaPow3(
361                 rgb * FxaaToFloat3(
1.0/1.055) + FxaaToFloat3(0.055/1.055),
362                 FxaaToFloat3(
2.4)),
363             rgb > FxaaToFloat3(
0.04045));
364     #
else
365         
return rgb;
366     #endif
367 }
368  

369 /*============================================================================
370                                 VERTEX SHADER
371 ============================================================================*/

372 float2 FxaaVertexShader(

373 // Both x and y range {-
1.0 to 1.0 across screen}.
374 float2 inPos) {
375     float2 pos;
376     pos.xy = (inPos.xy * FxaaFloat2(
0.5, 0.5)) + FxaaFloat2(0.5, 0.5);
377     
return pos; }
378  

379 /*============================================================================
380  
381                                 PIXEL SHADER
382                                 
383 ============================================================================*/

384 float3 FxaaPixelShader(

385 // Output of FxaaVertexShader interpolated across screen.
386 // xy -> actual texture position {
0.0 to 1.0}
387 float2 pos,

388 // Input texture.

389 FxaaTex tex,

390 // RCPFRAME SHOULD PIXEL SHADER CONSTANTS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
391 // {
1.0/frameWidth, 1.0/frameHeight}
392 float2 rcpFrame) {
393     

394 /*----------------------------------------------------------------------------
395             EARLY EXIT IF LOCAL CONTRAST BELOW EDGE DETECT LIMIT
396 ------------------------------------------------------------------------------
397 Majority of pixels of a typical image
do not require filtering,
398 often pixels are grouped
into blocks which could benefit from early exit
399 right at the beginning of the algorithm.
400 Given the following neighborhood,
401  
402       N
403     W M E
404       S
405     
406 If the difference
in local maximum and minimum luma (contrast "range")
407 is
lower than a threshold proportional to the maximum local luma ("rangeMax"),
408 then the shader early exits (no visible aliasing).
409 This threshold
is clamped at a minimum value ("FXAA_EDGE_THRESHOLD_MIN")
410 to avoid processing
in really dark areas.
411 ----------------------------------------------------------------------------*/

412     float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2(
0,-1), rcpFrame).xyz;
413     float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-
1, 0), rcpFrame).xyz;
414     float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2(
0, 0), rcpFrame).xyz;
415     float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2(
1, 0), rcpFrame).xyz;
416     float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2(
0, 1), rcpFrame).xyz;
417     
float lumaN = FxaaLuma(rgbN);
418     
float lumaW = FxaaLuma(rgbW);
419     
float lumaM = FxaaLuma(rgbM);
420     
float lumaE = FxaaLuma(rgbE);
421     
float lumaS = FxaaLuma(rgbS);
422     
float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
423     
float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
424     
float range = rangeMax - rangeMin;
425     #
if FXAA_DEBUG
426         
float lumaO = lumaM / (1.0 + (0.587/0.299));
427     #endif
428     
if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
429         #
if FXAA_DEBUG
430             
return FxaaFilterReturn(FxaaToFloat3(lumaO));
431         #endif
432         
return FxaaFilterReturn(rgbM); }
433     #
if FXAA_SUBPIX > 0
434         #
if FXAA_SUBPIX_FASTER
435             float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
436                 FxaaToFloat3(
1.0/5.0);
437         #
else
438             float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
439         #endif
440     #endif
441     

442 /*----------------------------------------------------------------------------
443                                COMPUTE LOWPASS
444 ------------------------------------------------------------------------------
445 FXAA computes a local neighborhood lowpass
value as follows,
446  
447   (N + W + E + S)/
4
448   
449 Then uses the ratio of the contrast range of the lowpass
450 and the range found
in the early exit check,
451 as
a sub-pixel aliasing detection filter.
452 When FXAA detects sub-pixel aliasing (such
as single pixel dots),
453 it later blends
in "blendL" amount
454 of a lowpass
value (computed in the next section) to the final result.
455 ----------------------------------------------------------------------------*/

456     #
if FXAA_SUBPIX != 0
457         
float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
458         
float rangeL = abs(lumaL - lumaM);
459     #endif
460     #
if FXAA_SUBPIX == 1
461         
float blendL = max(0.0,
462             (rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
463         blendL = min(FXAA_SUBPIX_CAP, blendL);
464     #endif
465     #
if FXAA_SUBPIX == 2
466         
float blendL = rangeL / range;
467     #endif
468     #
if FXAA_DEBUG_PASSTHROUGH
469         #
if FXAA_SUBPIX == 0
470             
float blendL = 0.0;
471         #endif
472         
return FxaaFilterReturn(
473             FxaaFloat3(
1.0, blendL/FXAA_SUBPIX_CAP, 0.0));
474     #endif
475     

476 /*----------------------------------------------------------------------------
477                     CHOOSE VERTICAL OR HORIZONTAL SEARCH
478 ------------------------------------------------------------------------------
479 FXAA uses the following local neighborhood,
480  
481     NW N NE
482     W M E
483     SW S SE
484     
485 To compute an edge amount
for both vertical and horizontal directions.
486 Note edge detect filters like Sobel fail
on single pixel lines through M.
487 FXAA takes the weighted average magnitude of the high-pass values

488 for
rows and columns as an indication of local edge amount.
489  
490 A lowpass
value for anti-sub-pixel-aliasing is computed as
491     (N+W+E+S+M+NW+NE+SW+SE)/
9.
492 This full box pattern has higher quality than other options.
493  
494 Note following
this block, both vertical and horizontal cases
495 flow
in parallel (reusing the horizontal variables).
496 ----------------------------------------------------------------------------*/

497     float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-
1,-1), rcpFrame).xyz;
498     float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2(
1,-1), rcpFrame).xyz;
499     float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-
1, 1), rcpFrame).xyz;
500     float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2(
1, 1), rcpFrame).xyz;
501     #
if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
502         rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
503         rgbL *= FxaaToFloat3(
1.0/9.0);
504     #endif
505     
float lumaNW = FxaaLuma(rgbNW);
506     
float lumaNE = FxaaLuma(rgbNE);
507     
float lumaSW = FxaaLuma(rgbSW);
508     
float lumaSE = FxaaLuma(rgbSE);
509     
float edgeVert =
510         abs((
0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
511         abs((
0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
512         abs((
0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
513     
float edgeHorz =
514         abs((
0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
515         abs((
0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
516         abs((
0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
517     
bool horzSpan = edgeHorz >= edgeVert;
518     #
if FXAA_DEBUG_HORZVERT
519         
if(horzSpan) return FxaaFilterReturn(FxaaFloat3(1.0, 0.75, 0.0));
520         
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.50, 1.0));
521     #endif
522     
float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
523     
if(!horzSpan) lumaN = lumaW;
524     
if(!horzSpan) lumaS = lumaE;
525     
float gradientN = abs(lumaN - lumaM);
526     
float gradientS = abs(lumaS - lumaM);
527     lumaN = (lumaN + lumaM) *
0.5;
528     lumaS = (lumaS + lumaM) *
0.5;
529     

530 /*----------------------------------------------------------------------------
531                 CHOOSE SIDE OF PIXEL WHERE GRADIENT IS HIGHEST
532 ------------------------------------------------------------------------------
533 This chooses a pixel pair.
534 For
"horzSpan == true" this will be a vertical pair,
535  
536     [N] N
537     [M] or [M]
538      S [S]
539  
540 Note following
this block, both {N,M} and {S,M} cases
541 flow
in parallel (reusing the {N,M} variables).
542  
543 This pair of image rows or columns
is searched below
544 in
the positive and negative direction
545 until edge status changes
546 (or the maximum number of search steps
is reached).
547 ----------------------------------------------------------------------------*/

548     
bool pairN = gradientN >= gradientS;
549     #
if FXAA_DEBUG_PAIR
550         
if(pairN) return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
551         
else return FxaaFilterReturn(FxaaFloat3(0.0, 1.0, 0.0));
552     #endif
553     
if(!pairN) lumaN = lumaS;
554     
if(!pairN) gradientN = gradientS;
555     
if(!pairN) lengthSign *= -1.0;
556     float2 posN;
557     posN.x = pos.x + (horzSpan ?
0.0 : lengthSign * 0.5);
558     posN.y = pos.y + (horzSpan ? lengthSign *
0.5 : 0.0);
559     

560 /*----------------------------------------------------------------------------
561                          CHOOSE SEARCH LIMITING VALUES
562 ------------------------------------------------------------------------------
563 Search limit (+/- gradientN)
is a function of local gradient.
564 ----------------------------------------------------------------------------*/

565     gradientN *= FXAA_SEARCH_THRESHOLD;
566     

567 /*----------------------------------------------------------------------------
568     SEARCH IN BOTH DIRECTIONS UNTIL FIND LUMA PAIR AVERAGE IS OUT OF RANGE
569 ------------------------------------------------------------------------------
570 This loop searches either
in vertical or horizontal directions,
571 and
in both the negative and positive direction in parallel.
572 This loop fusion
is faster than searching separately.
573  
574 The search
is accelerated using FXAA_SEARCH_ACCELERATION length box filter
575 via anisotropic filtering with specified texture gradients.
576 ----------------------------------------------------------------------------*/

577     float2 posP = posN;
578     float2 offNP = horzSpan ?
579         FxaaFloat2(rcpFrame.x,
0.0) :
580         FxaaFloat2(
0.0f, rcpFrame.y);
581     
float lumaEndN = lumaN;
582     
float lumaEndP = lumaN;
583     
bool doneN = false;
584     
bool doneP = false;
585     #
if FXAA_SEARCH_ACCELERATION == 1
586         posN += offNP * FxaaFloat2(-
1.0, -1.0);
587         posP += offNP * FxaaFloat2(
1.0, 1.0);
588     #endif
589     #
if FXAA_SEARCH_ACCELERATION == 2
590         posN += offNP * FxaaFloat2(-
1.5, -1.5);
591         posP += offNP * FxaaFloat2(
1.5, 1.5);
592         offNP *= FxaaFloat2(
2.0, 2.0);
593     #endif
594     #
if FXAA_SEARCH_ACCELERATION == 3
595         posN += offNP * FxaaFloat2(-
2.0, -2.0);
596         posP += offNP * FxaaFloat2(
2.0, 2.0);
597         offNP *= FxaaFloat2(
3.0, 3.0);
598     #endif
599     #
if FXAA_SEARCH_ACCELERATION == 4
600         posN += offNP * FxaaFloat2(-
2.5, -2.5);
601         posP += offNP * FxaaFloat2(
2.5, 2.5);
602         offNP *= FxaaFloat2(
4.0, 4.0);
603     #endif
604     
for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
605         #
if FXAA_SEARCH_ACCELERATION == 1
606             
if(!doneN) lumaEndN =
607                 FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
608             
if(!doneP) lumaEndP =
609                 FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
610         #
else
611             
if(!doneN) lumaEndN =
612                 FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
613             
if(!doneP) lumaEndP =
614                 FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
615         #endif
616         doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
617         doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
618         
if(doneN && doneP) break;
619         
if(!doneN) posN -= offNP;
620         
if(!doneP) posP += offNP; }
621     

622 /*----------------------------------------------------------------------------
623                HANDLE IF CENTER IS ON POSITIVE OR NEGATIVE SIDE
624 ------------------------------------------------------------------------------
625 FXAA uses the pixel
's position in the span
626 in
combination with the values (lumaEnd*) at the ends of the span,
627 to determine filtering.
628  
629 This step computes which side of the span the pixel
is on.
630 On negative side
if dstN < dstP,
631  
632      posN pos posP
633       |-----------|------|------------------|
634       | | | |
635       |<--dstN--->|<---------dstP---------->|
636                          |
637                     span center
638                     
639 ----------------------------------------------------------------------------*/

640     
float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
641     
float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
642     
bool directionN = dstN < dstP;
643     #
if FXAA_DEBUG_NEGPOS
644         
if(directionN) return FxaaFilterReturn(FxaaFloat3(1.0, 0.0, 0.0));
645         
else return FxaaFilterReturn(FxaaFloat3(0.0, 0.0, 1.0));
646     #endif
647     lumaEndN = directionN ? lumaEndN : lumaEndP;
648     

649 /*----------------------------------------------------------------------------
650          CHECK IF PIXEL IS IN SECTION OF SPAN WHICH GETS NO FILTERING
651 ------------------------------------------------------------------------------
652 If both the pair luma at the end of the span (lumaEndN)
653 and middle pixel luma (lumaM)
654 are
on the same side of the middle pair average luma (lumaN),
655 then don
't filter.
656  
657 Cases,
658  
659 (
1.) "L",
660   
661                lumaM
662                  |
663                  V XXXXXXXX <- other line averaged
664          XXXXXXX[X]XXXXXXXXXXX <- source pixel line
665         | . |
666     --------------------------
667        [ ]xxxxxx[x]xx[X]XXXXXX <- pair average
668     --------------------------
669         ^ ^ ^ ^
670         | | | |
671         . |<---->|<---------- no filter region
672         . | | |
673         . center | |
674         . | lumaEndN
675         . | .
676         . lumaN .
677         . .
678         |<--- span -->|
679         
680                         
681 (
2.) "^" and "-",
682   
683                                <- other line averaged
684           XXXXX[X]XXX <- source pixel line
685          | | |
686     --------------------------
687         [ ]xxxx[x]xx[ ] <- pair average
688     --------------------------
689          | | |
690          |<--->|<--->|<---------- filter both sides
691  
692  
693 (
3.) "v" and inverse of "-",
694   
695     XXXXXX XXXXXXXXX <- other line averaged
696     XXXXXXXXXXX[X]XXXXXXXXXXXX <- source pixel line
697          | | |
698     --------------------------
699     XXXX[X]xxxx[x]xx[X]XXXXXXX <- pair average
700     --------------------------
701          | | |
702          |<--->|<--->|<---------- don
't filter both!
703  
704          
705 Note the
"v" case for FXAA requires no filtering.
706 This
is because the inverse of the "-" case is the "v".
707 Filtering
"v" case turns open spans like this,
708  
709     XXXXXXXXX
710     
711 Into
this (which is not desired),
712  
713     x+. .+x
714     XXXXXXXXX
715  
716 ----------------------------------------------------------------------------*/

717     
if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
718         lengthSign =
0.0;
719  

720 /*----------------------------------------------------------------------------
721                 COMPUTE SUB-PIXEL OFFSET AND FILTER SPAN
722 ------------------------------------------------------------------------------
723 FXAA filters
using a bilinear texture fetch offset
724 from
the middle pixel M towards the center of the pair (NM below).
725 Maximum filtering will be half way between pair.
726 Reminder, at
this point in the code,
727 the {N,M} pair
is also reused for all cases: {S,M}, {W,M}, and {E,M}.
728  
729     +-------+
730     | |
0.5 offset
731     | N | |
732     | | V
733     +-------+....---
734     | |
735     | M...|....---
736     | | ^
737     +-------+ |
738     . .
0.0 offset
739     . S .
740     . .
741     .........
742  
743 Position
on span is used to compute sub-pixel filter offset using simple ramp,
744  
745              posN posP
746               |\ |<-------
0.5 pixel offset into pair pixel
747               | \ |
748               | \ |
749     ---.......|...\..........|<-------
0.25 pixel offset into pair pixel
750      ^ | ^\ |
751      | | | \ |
752      V | | \ |
753     ---.......|===|==========|<-------
0.0 pixel offset (ie M pixel)
754      ^ . | ^ .
755      | . pos | .
756      | . . | .
757      | . . center .
758      | . . .
759      | |<->|<---------.-------- dstN
760      | . . .
761      | . |<-------->|<------- dstP
762      | . .
763      | |<------------>|<------- spanLength
764      |
765     subPixelOffset
766     
767 ----------------------------------------------------------------------------*/

768     
float spanLength = (dstP + dstN);
769     dstN = directionN ? dstN : dstP;
770     
float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
771     #
if FXAA_DEBUG_OFFSET
772         
float ox = horzSpan ? 0.0 : subPixelOffset*2.0/rcpFrame.x;
773         
float oy = horzSpan ? subPixelOffset*2.0/rcpFrame.y : 0.0;
774         
if(ox < 0.0) return FxaaFilterReturn(
775             FxaaLerp3(FxaaToFloat3(lumaO),
776                       FxaaFloat3(
1.0, 0.0, 0.0), -ox));
777         
if(ox > 0.0) return FxaaFilterReturn(
778             FxaaLerp3(FxaaToFloat3(lumaO),
779                       FxaaFloat3(
0.0, 0.0, 1.0), ox));
780         
if(oy < 0.0) return FxaaFilterReturn(
781             FxaaLerp3(FxaaToFloat3(lumaO),
782                       FxaaFloat3(
1.0, 0.6, 0.2), -oy));
783         
if(oy > 0.0) return FxaaFilterReturn(
784             FxaaLerp3(FxaaToFloat3(lumaO),
785                       FxaaFloat3(
0.2, 0.6, 1.0), oy));
786         
return FxaaFilterReturn(FxaaFloat3(lumaO, lumaO, lumaO));
787     #endif
788     float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
789         pos.x + (horzSpan ?
0.0 : subPixelOffset),
790         pos.y + (horzSpan ? subPixelOffset :
0.0))).xyz;
791     #
if FXAA_SUBPIX == 0
792         
return FxaaFilterReturn(rgbF);
793     #
else
794         
return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
795     #endif
796 }

797
798
799
800 struct
v2f {
801     float4 pos : SV_POSITION;
802     float2 uv : TEXCOORD0;
803 };
804
805 v2f vert (appdata_img v)
806 {
807     v2f o;
808     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
809     o.uv = v.texcoord.xy;
810     
return o;
811 }
812
813 sampler2D _MainTex;
814 float4 _MainTex_TexelSize;
815
816 float4 frag (v2f i) : SV_Target
817 {
818     
return float4(FxaaPixelShader(i.uv.xy, _MainTex, _MainTex_TexelSize.xy).xyz, 0.0f);
819 }
820     
821 ENDCG
822     }
823 }
824
825 Fallback
"Hidden/FXAA II"
826 }


Gõ tìm kiếm nhanh...