Реализация FXAA в Opencl ничего не меняет
Я пытался реализовать FXAA в проекте, над которым я работал, математика, похоже, выдержала, но каким-то образом результат абсолютно идентичен входному. Я сузил проблему до "обнаружения границ", так как люмы каждого конца почти всегда превосходят масштаб градиента (который всегда довольно мал), что создает неправильное смещение пикселей (слишком маленькое, чтобы его можно было использовать)).
Вот моя функция обнаружения границ
void find_edges(global t_config const *const config, t_anti_aliasing *luma, float2 uv, global float4 const *pixels, int2 size)
{
float2 currentuv = uv;
float2 offset;
int reached1 = 0;
int reached2 = 0;
int reachedboth = 0;
int i = FXAA_SEARCH_START;
if (luma->is_horizontal)
currentuv.y += luma->step_length * 0.5;
else
currentuv.x += luma->step_length * 0.5;
offset = luma->is_horizontal ? (float2)(1.f / (float)size.x, 0.0) : (float2)(0.0, 1.f / (float)size.y);
luma->end_one.uv = currentuv - offset;
luma->end_two.uv = currentuv + offset;
luma->end_one.luma = get_luma(get_pixel_xy(pixels, luma->end_one.uv, size)) - luma->local_average;
luma->end_two.luma = get_luma(get_pixel_xy(pixels, luma->end_two.uv, size)) - luma->local_average;
reached1 = fabs(luma->end_one.luma) >= luma->gradscaled;
reached2 = fabs(luma->end_two.luma) >= luma->gradscaled;
reachedboth = reached1 && reached2;
if (!reached1)
luma->end_one.uv -= offset;
if (!reached2)
luma->end_two.uv += offset;
if (!reachedboth)
{
while (i < FXAA_SEARCH_STEPS && !reachedboth)
{
if (!reached1)
luma->end_one.luma = get_luma(get_pixel_xy(pixels, luma->end_one.uv, size)) - luma->local_average;
if (!reached2)
luma->end_two.luma = get_luma(get_pixel_xy(pixels, luma->end_two.uv, size)) - luma->local_average;
reached1 = fabs(luma->end_one.luma) >= luma->gradscaled;
reached2 = fabs(luma->end_two.luma) >= luma->gradscaled;
reachedboth = reached1 && reached2;
if (!reached1)
luma->end_one.uv -= offset * get_interval(i);
if (!reached2)
luma->end_two.uv += offset * get_interval(i);
i++;
}
}
}
Эта функция основана на этом руководстве http://blog.simonrodriguez.fr/articles/30-07-2016_implementing_fxaa.html
Я изменил только незначительные вещи, я хотел посмотреть, смогу ли я заставить это работать, прежде чем менять это.
Вот пример того, почему он не работает должным образом (на обычной горизонтальной линии с псевдонимом)
center = 373.000000:134.000000 at 0.743888 luma
end1 = 372.998596:134.000702 (0.001404) at -0.091179 luma
end2 = 373.001404:134.000702 (0.001404) at -0.091179 luma
is horizontal ? 1, gradscale = 0.045589, local_average = 0.835066
Не стесняйтесь спрашивать что-нибудь.
Я также подозреваю, что виновата моя функция билинейной фильтрации, скажите мне, если вы видите что-то, что выделяется
float4 bilinear_interpolation(global float4 const *pixels, float2 uv, int2 size)
{
float4 area[4];
int2 area_rect[2];
int2 pos;
float2 interp;
pos = (int2)(uv.x, uv.y);
area_rect[0] = (int2)(pos.x, pos.y);
area_rect[1] = (int2)(pos.x + (pos.x + 1 < size.x), pos.y + (pos.y + 1 < size.y));
interp = (float2)(uv.x - (float)pos.x, uv.y - (float)pos.y);
area[0] = get_pixel(area_rect[0].x, area_rect[0].y, pixels, size);
area[1] = get_pixel(area_rect[1].x, area_rect[0].y, pixels, size);
area[2] = get_pixel(area_rect[0].x, area_rect[1].y, pixels, size);
area[3] = get_pixel(area_rect[1].x, area_rect[1].y, pixels, size);
area[1] = area[1] * interp.x + area[0] * (1.f - interp.x);
area[2] = area[3] * interp.x + area[2] * (1.f - interp.x);
return (area[2] * interp.y + area[1] * (1.f - interp.y));
}