GLSL gl_FragCoord.z Расчет и настройка gl_FragDepth
Итак, у меня есть самозванец (настоящая геометрия - это куб, возможно, обрезанный, а геометрия самозванца - губка Менгера), и мне нужно рассчитать его глубину.
Я могу довольно легко рассчитать сумму, чтобы сместить в мировом пространстве. К сожалению, я потратил часы, не беспокоясь о глубине.
Единственные правильные результаты, которые я могу получить, это когда я иду:
gl_FragDepth = gl_FragCoord.z
По сути, мне нужно знать, как рассчитывается gl_FragCoord.z, чтобы я мог:
- Возьмите обратное преобразование из gl_FragCoord.z в пространство глаз
- Добавьте возмущение глубины
- Преобразуйте эту возмущенную глубину обратно в то же пространство, что и оригинальный файл gl_FragCoord.z.
Я прошу прощения, если это кажется дублирующим вопросом; здесь есть ряд других постов, посвященных подобным вещам. Однако после их реализации ни один из них не работает правильно. Вместо того, чтобы пытаться выбрать один, чтобы получить помощь, на данный момент, я прошу полный код, который делает это. Это должно быть просто несколько строк.
2 ответа
Для дальнейшего использования, код ключа:
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;
Для дальнейшего использования, это та же формула, что и для 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.