Каскадные карты теней между разделениями

Поэтому я решил внедрить 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;
        }
    }

0 ответов

Другие вопросы по тегам