1 Shader "Hidden/FXAA Preset 2" {
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 // doesn
't make sense to have this on consoles, it'll fallback to FXAA2
17 #pragma exclude_renderers xbox360 ps3 gles
18
19
20 #define FXAA_HLSL_3
1
21 #define FXAA_PRESET
2
22
23
24 // Copyright (c)
2010 NVIDIA Corporation. All rights reserved.
25 //
26 // TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
27 // *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
28 // OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
29 // AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
30 // BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
31 // WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
32 // BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS)
33 // ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS
34 // BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
35
36 /*============================================================================
37  
38                                     FXAA
39  
40 ============================================================================*/

41  

42 /*============================================================================
43                                  API PORTING
44 ============================================================================*/

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

57 /*--------------------------------------------------------------------------*/

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

76 /*--------------------------------------------------------------------------*/

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

93 /*--------------------------------------------------------------------------*/

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

105 /*--------------------------------------------------------------------------*/

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

116 /*--------------------------------------------------------------------------*/

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

118 /*--------------------------------------------------------------------------*/

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

133 /*--------------------------------------------------------------------------*/

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

148 /*--------------------------------------------------------------------------*/

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

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

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

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

201 /*--------------------------------------------------------------------------*/

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

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

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

266 /*--------------------------------------------------------------------------*/

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

278 /*--------------------------------------------------------------------------*/

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

290 /*--------------------------------------------------------------------------*/

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

302 /*--------------------------------------------------------------------------*/

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

314 /*--------------------------------------------------------------------------*/

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

326 /*--------------------------------------------------------------------------*/

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

338 /*--------------------------------------------------------------------------*/

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

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

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

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

370 /*============================================================================
371                                 VERTEX SHADER
372 ============================================================================*/

373 float2 FxaaVertexShader(

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

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

385 float3 FxaaPixelShader(

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

389 // Input texture.

390 FxaaTex tex,

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

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

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

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

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

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

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

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

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

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

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

566     gradientN *= FXAA_SEARCH_THRESHOLD;
567     

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

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

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

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

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

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

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

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

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


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