Я пытался внедрить окклюзию окружающего пространства экрана, как описано в уроке this. Я решал проблемы с моей реализацией, поскольку я сталкивался с ними, но на этот раз я был в тупике.OpenGL: Проецирование координаты пространства обзора в НДЦ, результаты, казалось бы, вне диапазона [-1,1]
Мое понимание метода заключается в следующем. Фактор внешней окклюзии определяется образцами, взятыми изнутри полушария, выровненными с нормалью данного фрагмента. Чтобы определить, способствует ли образец влиянию на коэффициент внешней окклюзии, я должен проверить глубину изображения в пространстве просмотра относительно текстуры глубины пространства обзора (включенной в нижний левый угол изображения этого сообщения). Поэтому я знаю, какие координаты для извлечения из текстуры глубины, я должен преобразовать координаты образца из пространства вида в нормализованные координаты устройства (в диапазоне [-1,1]), а затем в диапазон [0 , 1], поэтому текстура глубины эффективно «отображает» в окне просмотра.
Следующий образ моей окклюзии окружающего мира, лежащей над моей сценой. Я знаю, что у меня есть довольно очевидная проблема с окружающей окклюзией (я полагаю, что полушария ориентированы неправильно), с которыми я буду иметь дело вовремя, но то, что раздражает мое любопытство, в настоящее время - это появление окклюзии, которая «уменьшилась» ', предполагая, что моя операция по перемещению из координат образца пространства зрения в координаты текстуры неверна.
Как я не хватаю стабильные шейдеров отладчика, отладка я могу сделать, это ограничивается тем, что я могу вынести на экран. Следующее изображение создаются с помощью следующего кода, с НСДОМ быть нормированным-устройство координаты для данного образца .:
if (ndcs.x > 1.0f || ndcs.y > 1.0f || ndcs.x < -1.0f || ndcs.y < -1.0f)
{
gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
else
{
gl_FragColor = vec4(vec3(1.0f), 1.0f);
}
Я бы ожидать изображение, чтобы быть полностью белым (или, скорее, биты, которые я использую для этого шейдера), однако, похоже, что NDC, которые я создаю, находятся за пределами диапазона [-1,1], который, я считаю, должен быть неправильным. Это не соответствует области экрана или, как вы можете видеть на следующем рисунке, где камера находится очень близко к поверхности: не
Я не использовал эту процедуру, прежде чем получить НЦД, так что я Я уверен, что моя логика должна быть где-то неправильной. Я загрузил демо-код, поставляемый с учебником, и я не вижу, где мой код отличается. Я также искал онлайн (в том числе и на этом сайте), и я, похоже, не могу найти никого с такими же симптомами, как я.
Вот соответствующий код из моих шейдеров:
Vert Shader:
v_eye_space_position = u_mvpMatrix * a_position;
v_world_space_normal = normalize(u_rotationMatrix * a_normal);
v_eye_space_normal = normalize(u_mvpMatrix * a_normal);
gl_Position = v_eye_space_position;
Frag Shader:
// --- SSAO Testing ---
// Convert from the noise texture back to [-1,1] range
// We want the noise texture to tile across the screen.
vec3 kernel_rotation = (texture2D(s_noise, gl_FragCoord.xy * u_noise_scale) * 2.0f - 1.0f).xyz;
vec3 eye_space_tangent = normalize(kernel_rotation - v_eye_space_normal.xyz * dot(kernel_rotation, v_eye_space_normal.xyz));
vec3 eye_space_bitangent = cross(v_eye_space_normal.xyz, eye_space_tangent);
mat3 tbn = mat3(eye_space_tangent, eye_space_bitangent, v_eye_space_normal);
float ambient_occlusion = 0.0f;
const float hemisphere_radius = 0.05f;
for (int i=0; i<16; i++)
{
vec3 kernel_sample = tbn * u_ssao_kernel[i];
kernel_sample = kernel_sample * hemisphere_radius + v_eye_space_position.xyz;
// Project the sample position into screen space.
vec4 offset = vec4(kernel_sample, 1.0f);
offset = u_projection_matrix * offset;
offset.xy /= offset.w;
vec4 ndcs = offset;
offset.xy = 1.0f - (offset.xy * 0.5f + 0.5f);
// Find the depth at this sample point.
float sample_depth = texture2D(s_camera_depth, offset.xy).z;
// Check if the sample point is occluded.
float range_check = 0.0f;
float linear_eye_space_position = (v_eye_space_position.z - u_near_plane)/(u_far_plane - u_near_plane);
// Range check.
if (abs(linear_eye_space_position - sample_depth) < hemisphere_radius)
{
range_check = 1.0f;
}
float linear_kernel_sample_depth = (kernel_sample.z - u_near_plane)/(u_far_plane - u_near_plane);
if (sample_depth <= linear_kernel_sample_depth)
{
ambient_occlusion += 1.0f * range_check;
}
}
// Average and invert the ambient occlusion.
ambient_occlusion = 1.0f - (ambient_occlusion/16.0f);
Я посмотрел на каждый элемент в отдельности, и я не могу см. проблему с ними.
- Я susbstituted собственной позиции вида пространственно-фрагмента в проекции (вместо показов пространственного положения образца), и я получаю одни и те же результатов.
- Матрица проекции является перспективной матрицей I использовать для преобразования вершин в модели (я построил матрицу MVP в моих вершинных шейдерах, чтобы обеспечить матрицу проекции достигает шейдерную программу в такте и это).
- Операция проектирования сама по себе - это не то, что я делал раньше, но я читал статьи и вопросы от людей с проекционными проблемами , и я не вижу, что я делаю неправильно.
Как таковой, я могу только сделать вывод, что должно быть что-то принципиальное в моем понимании перспективной проекции, которая является ошибочной, но я просто не могу понять, что. Если бы кто-нибудь из вас, ребята, мог пролить свет на проблему или дальнейшие пути для проверки, я был бы очень благодарен. Если есть какая-либо полезная информация, которую я опустил, или что-либо, что я могу прояснить, просто дайте мне знать.
Благодарим вас за помощь в этом. После реализации ваших предложений результаты я ожидал. Забавно, как я ослепил себя такой простой ошибкой. Извлеченный урок: всегда проверяйте «простые» вещи (в частности, координатные пространства). Большое спасибо еще раз - вы избавили меня от огромного стресса. Хорошего дня! :) –