GLSL gl_FragCoord.z Расчет и настройка gl_FragDepth
Итак, у меня есть самозванец (реальная геометрия - это куб, возможно, обрезанный, а геометрия импостера - губка Менгера), и мне нужно рассчитать его глубину.
Я могу легко вычислить сумму, которую нужно компенсировать в мировом пространстве. К сожалению, я потратил несколько часов, чтобы не беспокоить его глубину.
Единственные правильные результаты, которые я могу получить, - это когда я иду:
gl_FragDepth = gl_FragCoord.z
В принципе, мне нужно знать, как вычисляется gl_FragCoord.z, чтобы я мог:
- Возьмите обратное преобразование из gl_FragCoord.z в пространство глаз
- Добавить возмущение глубины
- Преобразуйте эту возмущенную глубину обратно в то же пространство, что и исходный gl_FragCoord.z.
Извиняюсь, если это похоже на дублирующий вопрос; там есть несколько других сообщений, которые обращаются к подобным вещам. Однако после реализации всех из них никто не работает правильно. Вместо того, чтобы пытаться выбрать один, чтобы получить помощь, на данный момент я прошу полный код, который это делает. Это должно быть всего несколько строк.
Ответы
Ответ 1
Для справки в будущем key code:
float far=gl_DepthRange.far; float near=gl_DepthRange.near;
vec4 eye_space_pos = gl_ModelViewMatrix * /*something*/
vec4 clip_space_pos = gl_ProjectionMatrix * eye_space_pos;
float ndc_depth = clip_space_pos.z / clip_space_pos.w;
float depth = (((far-near) * ndc_depth) + near + far) / 2.0;
gl_FragDepth = depth;
Ответ 2
Для другой будущей ссылки это та же самая формула, которую дал imallett, который работал у меня в приложении OpenGL 4.0:
vec4 v_clip_coord = modelview_projection * vec4(v_position, 1.0);
float f_ndc_depth = v_clip_coord.z / v_clip_coord.w;
gl_FragDepth = (1.0 - 0.0) * 0.5 * f_ndc_depth + (1.0 + 0.0) * 0.5;
Здесь modelview_projection
- матрица прогноза модели 4x4, а v_position
- позиция объекта-пространства пикселя (в моем случае вычисляется raymarcher).
Уравнение происходит из координаты окна в разделе данное руководство. Обратите внимание, что в моем коде около 0.0
и далеко 1.0
, которые являются значениями по умолчанию gl_DepthRange
. Обратите внимание, что gl_DepthRange
не то же самое, что ближнее/дальнее расстояние в формуле для матрицы перспективных прогнозов! Единственный трюк - использовать 0.0
и 1.0
(или gl_DepthRange
в случае, если вам действительно нужно его изменить), я боролся в течение часа с другим диапазоном глубины - но это уже "испечено" в моя (перспективная) матрица проекции.
Обратите внимание, что таким образом уравнение действительно содержит только одно умножение на константу ((far - near) / 2
) и одно добавление другой константы ((far + near) / 2
). Сравните это, чтобы умножить, добавить и разделить (возможно, преобразовать в умножение с помощью оптимизационного компилятора), который требуется в коде imallett.