Я пытаюсь реализовать Screen Space Ambient Occlusion (SSAO) на основе демонстрации R5, найденной здесь: http://blog.nextrevision.com/?p=76
В действительности я пытаюсь адаптировать свой SSAO - Linear shader, чтобы вписаться в мой собственный маленький движок.
1) Я вычисляю вид Нормальные поверхностные нормали и значения линейной глубины. Я храню их в текстуре 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 shader использует 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;
Правильно или неправильно?