@!!ex
> Т.к. для направленного источника тень имеет тотже размер, что и сам объект
> От направленного источника света тень всегда будет одного размера, на любом расстоянии.
Чушь какая-то...
Elec3C
> Чушь какая-то...
Почему чушь?
Если тень без разноса по дальности, то всё верно.
@!!ex
Вообще, я понял так (правда я не понял, как строить бокс):
Скрин: Бокс (OBB) тени строить так?

Скрин: Или так?

Или вообще как-то по-другому строить? OBB или AABB бокс? Привёл бы чтоли картинки, как строить и что?
SNVampyre
См. скрины этого поста
ну тебе уже сказали 5 раз - строишь фрустум от источника, прицеливаясь на ресиверов в кадре. выбираешь им кастеров из сг и их рисуеж
З.Ы. для общего развития можно было бы хотябы одну бумагу про тени прочитать ну или дему пасмареть
kas
... или даже обратить внимание на скриншот...
Z
это слишком сложно!
kas
Ты читать умеешь или нет? Я у @!!ex спрашиваю, что он предлагал боксы строить, а не фрустумы, разъяснения его предложения насчёт боксов.
Elec3C
извини, я думал ты спрашываешь про то как делать правильно. нет так нет
Кстати, реально, достаточно построить несколько плоскостей на основе фрустума и его граней в сторону источника света.
Если объект будет лежать внутри всех этих плоскостей (а их может быть 4 или 5), то он отбрасывает тень во фрустум.
А как вычислять длину тени, чтобы правильно построить бокс/фрустум?
Скрин (в данном случае - бокс):

Раз не надо как павильно, а просто для фана посчитать какие-то страннъе боксъ - можно заюзать marching cubes, оценивая тень в углах куба и разбивая его, если разнъе углъ не одинакого в/вне тени. Получится даже точнее бокса - сурфейс тени!
Накидал примерный код.
class vec3 // класс вектора { public: float x, y, z; inline vec3 (float X, float Y, float Z) { x = X, y = Y, z = Z; } inline vec3 Sub ( vec3 &v) { return vec3 ( x - v.x, y - v.y, z - v.z); } // скалярное произведение inline float Dot ( vec3 &v) { return x*x + y*y + z*z; } // векторное произведение inline float Cross ( vec3 &v) { return vec3 ( v.z*y - v.y*z, v.x*z - v.z*x, v.y*x - v.x*y); } }; class plane // класс плоскости { public: float x, y, z, d; // проверка, лежит ли точка внутри плоскости bool Slice ( vec3 &p) { return x*p.x + y*p.y + z*p.z > d; } // установка плоскости по нормали и одной из точек в этой плоскости void Set ( vec3 &nrm, vec3 &pos) { x = nrm.x, y = nrm.y, z = nrm.z, d = pos.Dot ( nrm); } }; class frustum // класс фрустума { public: plane clips[4]; // плоскости фрустума vec3 look[4]; // направления по углам фрустума vec3 center; // вершина фрустума }; class lightClips { public: plane clips[6]; // плоскости отсечения int count; // количество плоскостей отсечения vec3 lPos; // позиция источника света // построение плоскостей отсечения, определяющих видимость теней от объектов void Compute ( frustum &fr) { count = 0; int first = 4, last = 0; // с начала добавим плоскости фрустума, внутри которых лежит источник света for( int i = 0; i < 4; i++) if( !fr.clips[i].Slice ( lPos)) first = min ( first, i), last = max ( last, i), clips[count++] = fr.clips[i]; // теперь достроим наш набор плоскостей на основе оставшихся граней if( ( count < 4)&&( count > 0)) { if( ( last == 3)&&( first == 0)) first = 3, last = 0; vec3 lVec = lPos.Sub ( fr.center); vec3 cr1 = lVec.Cross ( fr.look[first]); vec3 cr2 = fr.look[( last + 1)%4].Cross ( lVec); // cr1 и cr2 можно нормализовать, но не обязательно clips[count++].Set ( cr1, fr.center); clips[count++].Set ( cr2, fr.center); } // если источник света стоит за камерой if( count == 0) { // строим фрустум по источнику света и точкам полученным от // center + look*бесконечность // в лом расписывать } } // теперь в clips записаны необходимые нам плоскости };
Могут быть ошибки, но идея должна быть правильной :-)
Суть такова, что лежащее внутри полученных плоскостей будет отбрасывать тень во фрустум, а то что лежит вне - не даёт никак.
Правка:
Обнаружил пару ошибок.
Z
Если честно, я не совсем понял твой метод (да и скрин слишком нагружен для понимания) :)
SNVampyre
Надо попробовать реализовать :)
Elec3C
В ближайшем будущем тоже попробую :-)
А главное преимущество в том, что для теста не надо строить шапку от каждого объекта.
Строим плоскости только для источника, в дальнейшем тест ничем не отличается от простого фрустум-куллинга.
То есть можно использовать всю иерархию объектов на сцене, которая используется для других тестов.
Лучше всего конечно же брать сферы, они по плоскостям рубятся самым лучшим образом.
Там кстати "vec3 Cross" должно быть.
И плоскости лучше всё же нормализовать.
Elec3C
У направленного источника света все лучи параллельные.
Значит размер тени будет такой же как и сам объект, на любом расстоянии, т.к. в любой точке между параллельными линиями одно и тоже расстояние.
Именно поэтому от направленного источника света нужно строить бокс, а не пирамиду.
Тема в архиве.