2011-10-12 3 views
1

저는 컴퓨터 과학 학생이며 현재 제 교과목을위한 제 2의 게임을하고 있습니다. 나는 그것이 불필요하다고 알고 있지만, 게임의 AA에 FXAA 알고리즘을 구현하려고했습니다. 내가 사용하고있는 쉐이더는 단순한 쉐이더 셰이더를 사용하는 것이 괜찮을 것이라고 생각했기 때문에 이것을 사용하고 있습니다. 나는 또한 on Github을 찾을 수 있습니다.OpenGL FXAA 문제

#version 120 
#define FXAA_REDUCE_MIN (1.0/128.0) 
#define FXAA_REDUCE_MUL (1.0/8.0) 
#define FXAA_SPAN_MAX 8.0 
uniform sampler2D sampler0; 
uniform vec2 resolution; 

void main(){ 
    vec2 inverse_resolution=vec2(1.0/resolution.x,1.0/resolution.y); 
    vec3 rgbNW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,-1.0)) * inverse_resolution).xyz; 
    vec3 rgbNE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,-1.0)) * inverse_resolution).xyz; 
    vec3 rgbSW = texture2D(sampler0, (gl_FragCoord.xy + vec2(-1.0,1.0)) * inverse_resolution).xyz; 
    vec3 rgbSE = texture2D(sampler0, (gl_FragCoord.xy + vec2(1.0,1.0)) * inverse_resolution).xyz; 
    vec3 rgbM = texture2D(sampler0, gl_FragCoord.xy * inverse_resolution).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)) * inverse_resolution; 
    vec3 rgbA = 0.5 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (1.0/3.0 - 0.5)).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * (2.0/3.0 - 0.5)).xyz); 
    vec3 rgbB = rgbA * 0.5 + 0.25 * (texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * - 0.5).xyz + texture2D(sampler0, gl_FragCoord.xy * inverse_resolution + dir * 0.5).xyz); 
    float lumaB = dot(rgbB, luma); 
    if((lumaB < lumaMin) || (lumaB > lumaMax)) { 
     gl_FragColor = vec4(rgbA,1.0); 
    } else { 
     gl_FragColor = vec4(rgbB,1.0); 
    } 
} 

내가, 내 화면에 쉐이더를 켤 때마다 거꾸로 뒤집힌 것을 ... 나는이 문제를 어떻게 해결합니까됩니다에 실행 문제? 아마도 Orthographic Projection 때문일 수도 있지만, 저는 학생 일뿐입니다. 그래서 해결책을 찾을 수 없습니다.

+0

방금 ​​참고 사항 : 문제를 테스트하기 위해 전체 화면 질감에 fxaa 쉐이더를 사용하고 있습니다 (단지 metalslug 스크린 샷) – niktehpui

답변

1

텍스처 좌표 문제 인 것 같습니다. 미러 이미지를 뒤집으려면 V 대신 1-V을 사용하십시오.

vec2 correctedFragCoord; 

correctedFragCoord.x = gl_FragCoord.x; 
correctedFragCoord.y = resolution.y - gl_FragCoord.y; 

그런 다음 쉐이더에서 correctedFragCoord에 의해 gl_FragCoord를 교체합니다.

+0

접근 방식처럼 들리지만 여전히 glsl이 부족하여 책을 읽었습니다. 하지만 지금 게시 한 복잡한 조각 셰이더에서 1-V를 구현하는 방법은 무엇입니까? 정말 도움이 될 것입니다, 감사합니다 ... – niktehpui

+0

Ì've 위의 답변을 편집했습니다. – crazyjul