HLSL: эффект размытия по Гауссу

Я пытаюсь добиться размытия по Гауссу с помощью постобработки. У меня есть два прохода рендеринга; первый проход визуализирует сцену, а второй используется для эффекта.

Это мой код пиксельного шейдера:

const float offset[] = {
    0.0, 1.0, 2.0, 3.0, 4.0
    };
    const float weight[] = {
      0.2270270270, 0.1945945946, 0.1216216216,
      0.0540540541, 0.0162162162
    };
    ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
    float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);

    for (int i = 1; i < 5; i++) {
        // Horizontal-pass
        FragmentColor +=
            SceneTexture.Sample(PointSample, ppIn.UV + float2(0.0f, offset[i]))*weight[i] +
            SceneTexture.Sample(PointSample, ppIn.UV - float2(0.0f, offset[i]))*weight[i];      
            // Vertical-pass
        FragmentColor +=
            SceneTexture.Sample(PointSample, ppIn.UV + float2(offset[i], 0.0f))*weight[i] +
            SceneTexture.Sample(PointSample, ppIn.UV - float2(offset[i], 0.0f))*weight[i];
        }
ppColour += FragmentColor;
return (ppColour,1.0);

Я получаю строковый вид, как видно: введите описание изображения здесь

Что я делаю неправильно?


person Salah Alshaal    schedule 30.03.2016    source источник


Ответы (1)


Я думаю, вам нужно отображать горизонтальный и вертикальный проходы отдельно, используя код шейдера, как показано ниже, но с другим направлением (см. dir юниформ-переменная). Итак, вам нужно 3 шага

  • Рендеринг сцены в текстуру A с использованием шейдера по умолчанию
  • Визуализация текстуры A в текстуру B с использованием шейдера размытия по Гауссиону по горизонтали (dir={1.0,0.0})
  • Визуализация текстуры B на экране с использованием того же шейдера размытия по Гауссиону по вертикали (dir={0.0,1.0})
uniform vec2 dir;

const float offset[] = {0.0, 1.0, 2.0, 3.0, 4.0};
const float weight[] = {
  0.2270270270, 0.1945945946, 0.1216216216,
  0.0540540541, 0.0162162162
};
ppColour = SceneTexture.Sample(PointSample, ppIn.UV) * weight[0];
float3 FragmentColor = float3(0.0f, 0.0f, 0.0f);

//(1.0, 0.0) -> horizontal blur
//(0.0, 1.0) -> vertical blur
float hstep = dir.x;
float vstep = dir.y;

for (int i = 1; i < 5; i++) {
    FragmentColor +=
        SceneTexture.Sample(PointSample, ppIn.UV + float2(hstep*offset[i], vstep*offset[i]))*weight[i] +
        SceneTexture.Sample(PointSample, ppIn.UV - float2(hstep*offset[i], vstep*offset[i]))*weight[i];      
    }
ppColour += FragmentColor;
return (ppColour,1.0);

См. Эффективное размытие по Гауссу с линейной выборкой

person Zamrony P. Juhara    schedule 30.03.2016
comment
Вы имеете в виду, что мне нужен третий проход рендеринга? - person Salah Alshaal; 01.04.2016
comment
Насколько я понимаю, автор предоставленной статьи показывает некоторые подходы для оптимизации производительности. Но это не классическое размытие по Гауссу, просто аналогичный результат после нескольких проходов. - person nicolay.anykienko; 27.11.2016