Я пытаюсь реализовать 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 /
Это правильно? Текстура кажется правильной, но, может быть, это не так?
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;
Верно или Неправильно?