2012-08-24 25 views
8

मैं इस एफएक्सएए शेडर में आया जो एंटी-एलियासिंग करता है और लगता है कि यह काफी अच्छा काम कर रहा है। लेकिन, किसी भी तरह तर्क को समझ नहीं सका। क्या कोई समझा सकता है?यह सरल FxAA ​​कैसे काम करता है?

[[FX]] 

// Samplers 
sampler2D buf0 = sampler_state { 
    Address = Clamp; 
    Filter = None; 
}; 

context FXAA { 
    VertexShader = compile GLSL VS_FSQUAD; 
    PixelShader = compile GLSL FS_FXAA; 
} 



[[VS_FSQUAD]] 

uniform mat4 projMat; 
attribute vec3 vertPos; 
varying vec2 texCoords; 

void main(void) { 
    texCoords = vertPos.xy; 
    gl_Position = projMat * vec4(vertPos, 1); 
} 


[[FS_FXAA]] 

uniform sampler2D buf0; 
uniform vec2 frameBufSize; 
varying vec2 texCoords; 

void main(void) { 
    //gl_FragColor.xyz = texture2D(buf0,texCoords).xyz; 
    //return; 

    float FXAA_SPAN_MAX = 8.0; 
    float FXAA_REDUCE_MUL = 1.0/8.0; 
    float FXAA_REDUCE_MIN = 1.0/128.0; 

    vec3 rgbNW=texture2D(buf0,texCoords+(vec2(-1.0,-1.0)/frameBufSize)).xyz; 
    vec3 rgbNE=texture2D(buf0,texCoords+(vec2(1.0,-1.0)/frameBufSize)).xyz; 
    vec3 rgbSW=texture2D(buf0,texCoords+(vec2(-1.0,1.0)/frameBufSize)).xyz; 
    vec3 rgbSE=texture2D(buf0,texCoords+(vec2(1.0,1.0)/frameBufSize)).xyz; 
    vec3 rgbM=texture2D(buf0,texCoords).xyz; 

    vec3 luma=vec3(0.299, 0.587, 0.114); 
    float lumaNW = dot(rgbNW, luma); 
    float lumaNE = dot(rgbNE, luma); 
    float lumaSW = dot(rgbSW, luma); 
    float lumaSE = dot(rgbSE, luma); 
    float lumaM = dot(rgbM, luma); 

    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); 
    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 

    vec2 dir; 
    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 
    dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 

    float dirReduce = max(
     (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), 
     FXAA_REDUCE_MIN); 

    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); 

    dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), 
      max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), 
      dir * rcpDirMin))/frameBufSize; 

    vec3 rgbA = (1.0/2.0) * (
     texture2D(buf0, texCoords.xy + dir * (1.0/3.0 - 0.5)).xyz + 
     texture2D(buf0, texCoords.xy + dir * (2.0/3.0 - 0.5)).xyz); 
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
     texture2D(buf0, texCoords.xy + dir * (0.0/3.0 - 0.5)).xyz + 
     texture2D(buf0, texCoords.xy + dir * (3.0/3.0 - 0.5)).xyz); 
    float lumaB = dot(rgbB, luma); 

    if((lumaB < lumaMin) || (lumaB > lumaMax)){ 
     gl_FragColor.xyz=rgbA; 
    }else{ 
     gl_FragColor.xyz=rgbB; 
    } 
} 
+2

जो कि बहुत आसान है –

उत्तर

9

FxAA ​​एक फिल्टर एल्गोरिदम है जो छवियों पर एंटीअलाइजिंग करता है। अन्य एए तकनीकों के विपरीत यह किसी छवि के पिक्सेल पर लागू होता है, न कि इसके प्राइमेटिव्स को चित्रित करते समय। गेम जैसे 3 डी अनुप्रयोगों में इसे प्रस्तुत दृश्य के शीर्ष पर पोस्ट प्रोसेसिंग चरण के रूप में लागू किया जाता है।

मूल विचार यह है: लंबवत और क्षैतिज किनारों की तलाश करें। अगर किनारे के अंत में ऑर्थोगोनल दिशा में धुंधला हो।

यहां पर good description और original paper है।

+1

से FAAAAR मुझे लगता है कि FxAA ​​के कई संस्करण हैं, जो संस्करण मैंने यहां पोस्ट किया है वह पेपर का वर्णन करने से अलग है। यहां जानना चाहते हैं कि आरजीबीए और आरजीबीबी यहां क्या संकेत देते हैं। निम्न तर्क का अर्थ क्या है, 'if ((lumaB lumaMax)) { gl_FragColor.xyz = rgbA; } अन्य { gl_FragColor.xyz = rgbB; } ' – Subhransu