Тени, отбрасываемые объектами, находящимися очень далеко от источника света

У меня проблема с тенями, отбрасываемыми объектом, находящимся очень далеко от источника света. Я использую подход карты глубины для рендеринга теней в моей симуляции Солнечной системы. Солнце - точечный источник света, и я хотел бы наблюдать тень луны на земле. Но поскольку Луна - действительно крошечный объект по сравнению с расстоянием между ней и Солнцем, и поскольку разрешение карты глубины ограничено, присутствие Луны и Земли игнорируется при рендеринге текстуры карты куба глубины.

Карта глубины Солнечной системы:

введите описание изображения здесь

Вы можете видеть, что даже с преувеличенными размерами Луны, она оставляет лишь небольшой след на карте куба глубины. С такой большой луной затмения работают, но как только я уменьшаю луну до ее фактического размера, она больше не отображается на карте глубины и из-за этого больше не принимается во внимание при расчетах теней. Я использую текстуру 4096 X 4096. Есть ли способ решить эту проблему или мой подход обречен на провал? Любая помощь приветствуется.


person Grupa    schedule 11.03.2019    source источник
comment
Вы уверены, что карты глубины подходят для создания теней в такой сцене? Поскольку у вас небольшое количество крошечных объектов, вам могут лучше подойти теневые объемы.   -  person lisyarus    schedule 11.03.2019
comment
Я не уверен, что это лучший подход. Вот почему я спрашиваю. Shadow Mapping - единственный известный мне подход.   -  person Grupa    schedule 11.03.2019


Ответы (1)


Следует сделать важное наблюдение: когда вы смотрите на Землю вблизи, вас, вероятно, не волнуют тени на Марсе. Поэтому вместо использования кубической карты для отображения теней всей солнечной системы используйте планарную карту теней, чтобы покрыть только околоземную область.

С картой глубины 4096x4096 и расстоянием до Луны 384000 км вы получите разрешение ~ 100 км на тексель, а на карте теней луна займет диск радиусом ~ 20 текселей.

Однако есть подход получше. Поскольку планеты и луны приблизительно сферические, а их всего несколько, вы можете просто выполнить пересечение лучевой сферы для каждого фрагмента, чтобы вычислить тени. Можно рассчитать угловую область пересечения между луной и солнечными дисками, чтобы получить рендеринг тени / полутени в реальном времени. Вот функция, которая приближает коэффициент тени в шейдере:

float soft_shadow(vec3 light, float light_radius,
    vec3 occluder, float occluder_radius, vec3 fragment)
{
    vec3 v0 = light - fragment;
    vec3 v1 = occluder - fragment;

    float R0 = length(v0);
    float R1 = length(v1);

    float a0 = light_radius/R0;
    float a1 = occluder_radius/R1;

    float a = length(cross(v0, v1))/(R0*R1);
    a = smoothstep(a0 - a1, a0 + a1, a);
    return 1 - (1 - a)*pow(a1/a0, 2);
}

Здесь 0.0 означает полную тень, 1.0 означает отсутствие тени. light, occluder и fragment - это местоположения солнца, луны и фрагмента в непроективном пространстве, тогда как light_radius и occluder_radius - это радиусы солнца и луны.

Для реалистичных размеров этот код дает мне следующие изображения:

Если я уменьшу размер солнца вдвое, я получу следующее:

person Yakov Galka    schedule 11.03.2019
comment
Поскольку мне пришлось на время отложить этот проект, я забыл сказать вам, насколько вы очень помогли. Я новичок и потратил уйму времени, пытаясь найти достаточно точное решение моей проблемы. Я знаю, что, возможно, вы дали мне то, что может показаться тривиальным расчетом, но я просто хотел сообщить вам, что это оказалось для меня наиболее полезным, и я искренне благодарен за ваше время. - person Grupa; 21.03.2019