Каскадные карты теней между разделениями
Поэтому я решил внедрить CSM, чтобы улучшить разрешение теней в моих сценах. Это работает очень хорошо, как можно увидеть здесь: сейчас я передаю количество разделений в качестве аргумента, но соотношение каждого разделения жестко запрограммировано. Мне интересно, есть ли хорошее универсальное решение для расчета разделений для лучших теней на основе чего-то, или это больше искусство, чем что-либо, и я должен просто поиграть со значениями?
Также я получаю швы теней на границе каждой карты теней, потому что разрешение карты теней, очевидно, меняется из-за того, как усеченная пирамида света становится больше после каждого уменьшения разрешения каскада:
Теперь я не мог понять, что я могу с этим поделать. Я читал в Интернете, что я должен пробовать как разделенные карты теней, так и линейную интерполировать их... но я даже не уверен, как?
Я разделяю каскады прямо сейчас - это жестко запрограммированное фиксированное соотношение.
первый раскол0.0366... * far
.
второй раскол0.5 * far
.
второй раскол1.0 * far
.
Эти значения предназначались только для тестирования и демонстрации стыков между первым и вторым разделением.
Я выбираю правильную карту теней, вычисляя положение фрагмента по оси z в пространстве клипа и передавая его в шейдер фрагмента:
vs_out.v_FragPosClipSpaceZ = (u_Projection * u_View * u_Model * vec4(position, 1.0).z;
Я прохожу униформу uniform float u_CascadeEndClipSpace[NR_LIGHT_SPACE];
к фрагментному шейдеру, который представляет собой все дальние плоскости каждой пирамиды вида, который CSM разделяет в пространстве клипа камеры.
Затем я проверяю, еслиv_FragPosClipSpaceZ
ниже чем u_CascadeEndClipSpace[i]
и если так образец uniform sampler2D u_ShadowMap[NR_LIGHT_SPACE];
согласно с i
во фрагментном шейдере:
float shadow = 0.0f;
for (int i = 0; i < NR_LIGHT_SPACE; i++) {
if (fs_in.v_FragPosClipSpaceZ <= u_CascadeEndClipSpace[i]) {
shadow = isInShadow(fs_in.v_FragPosLightSpace[i], normal, lightDirection, i);
break;
}
}
Все разделения имеют одно и то же разрешение карты прямо сейчас - 8192.
Помощь в этом будет оценена!
РЕДАКТИРОВАТЬ1:
Пытался смешать следующим образом, но результат тот же:
float shadow = 0.0
for (int i = 0; i < NR_LIGHT_SPACE; i++) {
if (fs_in.v_FragPosClipSpaceZ <= u_CascadeEndClipSpace[i]) {
shadow = isInShadow(fs_in.v_FragPosLightSpace[i], normal, lightDirection, i);
float diff = u_CascadeEndClipSpace[i] - fs_in.v_FragPosClipSpaceZ;
float frustumLength = u_CascadeEndClipSpace[i] - (i > 0 ? u_CascadeEndClipSpace[i - 1] : 0.0);
float diffRatio = clamp(diff / frustumLength, 0.0, 1.0) * 0.1;
if (i < NR_LIGHT_SPACE - 1 && diffRatio < 1.0) {
float nextShadow = isInShadow(fs_in.v_FragPosLightSpace[i + 1], normal, lightDirection, i + 1);
shadow = mix(shadow, nextShadow, diffRatio);
}
break;
}
}