2012-08-24 42 views
8

Tôi đã xem bộ đổ bóng FxAA ​​này để chống răng cưa và có vẻ hoạt động khá tốt. Nhưng, bằng cách nào đó không thể hiểu được logic. Ai đó có thể giải thích?FxAA ​​đơn giản này hoạt động như thế nào?

[[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

whoa ở xa FAAAAR từ đơn giản –

Trả lời

9

FxAA ​​là thuật toán lọc thực hiện khử răng cưa trên hình ảnh. Trái với các kỹ thuật AA khác, nó được áp dụng trên các pixel của một hình ảnh, không phải trong khi vẽ nó nguyên thủy. Trong các ứng dụng 3D như trò chơi, nó được áp dụng như một bước xử lý bài đăng ở đầu cảnh được hiển thị.

Ý tưởng cơ bản là: Tìm các cạnh thẳng đứng và nằm ngang. Làm mờ theo hướng trực giao nếu ở cuối cạnh.

Dưới đây là good descriptionoriginal paper về chủ đề.

+1

Tôi đoán có nhiều phiên bản của FxAA, phiên bản mà tôi đã đăng ở đây khác với phiên bản mô tả. Bạn muốn biết ở đây rgbA và rgbB biểu hiện ở đây. Bất kỳ ý nghĩa logic nào sau đây, 'if ((lumaB lumaMax)) { gl_FragColor.xyz = rgbA; } else { gl_FragColor.xyz = rgbB; } ' – Subhransu

Các vấn đề liên quan