Итак, я решил внедрить CSM для улучшения разрешения теней в моих сценах. Это работает довольно хорошо, как можно увидеть здесь: Прямо сейчас я передаю количество разделений в качестве аргумента, но отношение каждого разделения довольно жестко закодировано. Мне интересно, есть ли хорошее обобщенное c решение для вычисления расщепления для лучших теней на основе чего-либо, или это больше искусство, чем что-либо еще, и мне просто нужно поиграть со значениями?
Также я получаю швы теней на границы каждой карты теней, потому что разрешение карты теней, очевидно, изменяется из-за того, что световой усеченный размер увеличивается после каждого каскада, уменьшая разрешение go:
Теперь я не мог не понимаю, что я могу с этим поделать. Я читал в Интернете, что я должен сэмплировать карты расщепления теней и линейную интерполяцию их ... но я даже не уверен, как?
Способ, которым я сейчас делю каскады, - это жестко заданное фиксированное отношение. первый сплит 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.
Помощь по этому вопросу была бы признательна!
EDIT1:
Пытался смешаться следующим образом, но получил тот же результат:
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;
}
}