Реализация OpenGL GLSL SSAO

Я пытаюсь реализовать Ambient Occlusion в экранном пространстве (SSAO) на основе демонстрации R5, которую можно найти здесь: http: //blog.nextrevision .com /? p = 76

На самом деле я пытаюсь адаптировать их SSAO - линейный шейдер, чтобы он вписался в мой собственный маленький движок.

1) Я вычисляю нормали поверхности View Space и значения линейной глубины. Я сохраняю их в текстуре RGBA, используя следующий шейдер:

Vertex:

varNormalVS = normalize(vec3(vmtInvTranspMatrix * vertexNormal));
depth = (modelViewMatrix * vertexPosition).z;
depth = (-depth-nearPlane)/(farPlane-nearPlane);
gl_Position = pvmtMatrix * vertexPosition;

Fragment:

gl_FragColor = vec4(varNormalVS.x,varNormalVS.y,varNormalVS.z,depth)

Для моего вычисления линейной глубины я ссылался на: http://www.gamerendering.com/2008/09 / 28 / linear-depth-texture /

Это правильно? Текстура кажется правильной, но, может быть, это не так?

enter image description here

2) Фактическая реализация SSAO: Как упоминалось выше, оригинал можно найти здесь: http://blog.nextrevision.com/?p=76

или быстрее: на pastebin http: // pastebin.com / KaGEYexK

В отличие от оригинала, я использую только 2 входные текстуры, так как одна из моих текстур хранит обе, нормали как RGB и Linear Depht als Alpha.

Моя вторая текстура, случайная текстура нормалей, выглядит так: ​​http://www.gamerendering.com/wp-content/uploads/noise.png

Я использую почти точно такую ​​же реализацию, но мои результаты неверны.

Прежде чем вдаваться в подробности, я хочу сначала прояснить некоторые вопросы:

1) шейдер ssao использует projectionMatrix и его обратную матрицу.

Поскольку это эффект постобработки, визуализированный на выровненный по экрану четырехугольник с помощью ортогональной проекции, projectionMatrix является ортографической матрицей. Правильно или неправильно?

2) Наличие комбинированной текстуры нормали и глубины вместо двух отдельных.

На мой взгляд, это самая большая разница между реализацией R5 и моей попыткой реализации. Я думаю, что это не должно быть большой проблемой, однако из-за различной текстуры глубины это, скорее всего, вызовет проблемы.

Обратите внимание, что R5_clipRange выглядит так

vec4 R5_clipRange = vec4(nearPlane, farPlane, nearPlane * farPlane, farPlane - nearPlane);

Оригинал:

float GetDistance (in vec2 texCoord)
{
//return texture2D(R5_texture0, texCoord).r * R5_clipRange.w;
const vec4 bitSh = vec4(1.0 / 16777216.0, 1.0 / 65535.0, 1.0 / 256.0, 1.0);
return dot(texture2D(R5_texture0, texCoord), bitSh) * R5_clipRange.w;
}

Должен признаться, я не понимаю фрагмент кода. Моя глубина его сохранена в альфе моей текстуры, и я подумал, что этого должно быть достаточно, чтобы просто сделать это

return texture2D(texSampler0, texCoord).a  * R5_clipRange.w;

Верно или Неправильно?

13
задан Peter O. 17 April 2015 в 20:07
поделиться