Привет всем.
Как-то уже обсуждал эту тему на gamedev, но толком ни чего не разобрал. Вот сейчас эта проблема затенения сцены и стала передо мной.
Далее будет много букф, надеюсь, осилите : D
Проблема рас:
Итак, у меня в движке реализовано только динамическое затенение а именно ShadowMaps, VarianceShadowMaps (ага, не густо).
Но насчёт "реализован" я наверно преувеличил. У меня сценеграф перед рендером сцены находит все источники света, которые воздействуют на видимую часть сцены. Для каждого источника света делается DepthPass тоесть в текстуру глубины каждого источника записывается сцена. Далее сделано очень тупо - первые 4 источника света (их карты глубины) передаются в фрагментный шейдер и собсно сцена затеняется (как именно - думаю вам известно).
Что мне тут не нравится:
1. (Я этот вопрос, как говорил выше, поднимал но не нашёл ответа)
Представим такую ситуацию: игрок стоит перед стеной (метрах в 20), на стене висит прожектор и светит на игрока, на бочку и ящик, которые стоят между игроком и стеной. Вдруг (не важно, что это именно) возле ног игрока на полу загораются 5 лампочек - они намного слабже прожектора со стены но всёже прилично так светят. И что тут получается - если 5 лампочек должны отбрасывать тень (а у меня максимум 4 источника света, которые могут отбрасывать тень) то, получается, тень от прожектора исчезнет? Это будет очень заметно, особенно когда исчезнит тень от ящика и бочки.
Вторая ситуация:
Пол, на полу стоят 2 ящика на расстоянии 5 метров друг от друга. На стене возле одного ящика 4 лампочки с динамическими тенями, но они светят слабо, а на противоположной стене 1 лампочка но светит довольно ярко! Получается, возможен вариант, когда тени от 4 слабых лампочек будут просчитываться а от яркой исчезнит.
Как поступать в такой ситуации? Я думаю о 2 вариантах:
а. делать уровень так, что на любой объект в игровом мире будет действовать
максимум 4 источника света с тенями.
б. както просчитывать, какой из источников света приоритетнее.
Вопрос номер 2:
СтОит ли мне сейчас делать какое-либо статичное освещение? например LightMap
Я не говорю о техниках типа PRT, RNM, LightMass - это я сделаю.
1) Можно попробовать подход похожий чем-то на lighcut, только упрощенный.
Идея в том, чтобы построить дерево, в котором каждый узел - источник света, пытающийся апроксимировать свои листья.
Ну и считать свет от четырех точечных источников, которые находятся на 3 уровне глубины дерева.
То есть освещать сцену не настоящими источниками а приближенными. Но тут все зависит оттого как будет построено lightcut tree.
Соответственно, так можно любое число источников света обработать. Все сам хочу сделать нормальный lightcut, руки не доходят(
2) А почему нет? Если не лень, то халявное освещение никому еще не вредило.
Вот дохлая видюха не потянет твои 4 шадоумапа, а лайтмап как был так и останется и будет достаточно красиво.
FROL
> 1) Можно попробовать подход похожий чем-то на lighcut, только упрощенный.
оуу блин. у мну какраз сейча инета нету даже 4.5 мб скачать : ( такчто глянуть пока не могу. Есть какие идеи по реализации без такой техники?? Блин, есть же тут люди (даже знаю кто), кто сделал у себя множественные ситочники света с тенями!! Так влом поделиться знаниями?
FROL
> Если не лень, то халявное освещение никому еще не вредило.
нет, не лень : )
FROL
> Вот дохлая видюха не потянет твои 4 шадоумапа
у меня минимальные спеки это sm_3_0
я бы так сказал, что во всём этом меня волнуют такого рода ситуации:
Например PointLight освещает Indoor сцену слабо!(он ещё кастит тени) - тёмная комната есссно вся в тенях и тут несколько людей вбегают с яркими фонарями!! и все тени в комнате, кроме как от фонаерй, исчезают нафиг!! Вот я всё это спрашиваю, т.к. такие ситуациименя реально смущают. Я вот думаю, может сделать "метки" источникам света типа "обязательно включать в список кастующих тени лайтов" ?? -> что-то вроде: в редакторе карт ставим лайт в комнате и ставим ему ForceShadows галку! и тогда от него тени будут полюбому! Помоему это один из выходов но довольно геморный для дизайнеров!
L
> ForceShadows галку!
по-моему правильное решение.
>геморный для дизайнеров
нисколько.
L
а как насчет того, чтобы не ограничивать количество источников света?
рендерить по 4 за проход, с аддитивным блендингом.
Kloun
> рендерить по 4 за проход, с аддитивным блендингом.
обоже!! если так сделать то начну "жыреть" и ставить по 15 лайтов на объект ! : D а это4 рендера сцены заново!!! (не считая рендеров в текстуру глубины и ещё блендинга этих всех результатов)
да и вообще больше 4 шадоумапов на кадр - это ж одуреть можно!! особенно если лайты PointLight с кубической картой глубины!!!
IronNick
> > ForceShadows галку!
> по-моему правильное решение
оу. А у тебя как? Также или всёже как-то по-другому?
я вот ещё думаю.. есть 3 типа источника света PointLight, SpotLight. DirectionalLight.
Тени для point нуна рендерить в кубтекстуру а для spot, directional нужно 2D текстура!
Как лучше (как вообще у вас сделано?) - объявить в шейдере 2 сэмплера для 2 текстур sampler2D, samplerCUBE или же 2D текстуры рендерить также в кубическую карту??. тоесть в кубтекстуре FP32 формата есть 4 канала. в каких-то куб текстура запечена а в каких-то в нулевой грани лежат 2D текстуры )а потом просто переводить 2D текстурные координаты в 3D и читать)
L
> point нуна рендерить в кубтекстуру
лучше в дуал-параболоид
Gurich
> лучше в дуал-параболоид
а качество у теней не сильно ухудшится? какбэ поидее в over3 раза хуже должно быть о_О
вообщем, решил покурить dual paraboloid maps.
Всё вроде как просто но какаято фигня на экране получается! совсем не полусфера : D
по этому туториалу http://www.gamedev.net/reference/articles/article2308.asp замутил вершинный шейдер:
float4x4 mWorld; float4x4 mView; float4x4 mProj; struct VS_INPUT { float4 Position : POSITION0; float2 Texcoord : TEXCOORD0; float3 Normal : NORMAL0; float3 Tangent : TANGENT0; float3 Binormal : BINORMAL0; }; struct VS_OUTPUT { float4 Position : POSITION0; float2 Texcoord : TEXCOORD0; float3 Normal : TEXCOORD1; float3 Tangent : TEXCOORD2; float3 Binormal : TEXCOORD3; float4 Pos : TEXCOORD4; }; VS_OUTPUT main_VS(VS_INPUT Input ) { VS_OUTPUT Output; float4x4 mVP = mul( mView, mProj); float4x4 mWVP = mul( mWorld, mVP); Output.Position = mul( Input.Position, mWVP); Output.Position = Output.Position / Output.Position.w; float L = length( Output.Position.xyz); Output.Position = Output.Position / L; Output.Position.z = Output.Position.z + 1.0f; Output.Position.x = Output.Position.x / Output.Position.z; Output.Position.y = Output.Position.y / Output.Position.z; Output.Position.z = ( L - 0.1f)/( 30.0f-0.1f); Output.Position.w = 1.0f; Output.Texcoord = Input.Texcoord; Output.Normal = mul( Input.Normal, ( float3x3)mWorld); Output.Tangent = mul( Input.Tangent, ( float3x3)mWorld); Output.Binormal = mul( Input.Binormal, ( float3x3)mWorld); Output.Pos = mul( Input.Position, mWorld); Output.Pos.w = Output.Position.z; return( Output ); }
это я из тестового шейдера нормалмапа сделал новый тестовый шейдер для рендеринга в paraboloid карту. но что-то не рисует. иногда на экране появляются ортогональные части комнаты и всё.
проекционная матрица == Identity матрица
видовая: vEye = lightPosition, vAt = lightPosition + Vector3D(1,0,0); vUp = Vector3D(0,1,0);
L
> б. както просчитывать, какой из источников света приоритетнее.
Думаю, у кого радиус( зона) покрытия больше, тот и считаем первым, потом по уменьшению радиуса.
на счет ForceShadows - думаю это не лучший вариант.
----
Оптимизировать:
к примеру, из известного, это рендерить несколько ShadowMap в одну текстуру( в Крайзисе 4 мапы в одной текстуре (R,G,B,A -по каналам))
+ юзать Shadow Occluder
+ если у тебя несколько источников на близком расстояние друг от друга( const ), то делаем вместо них новый, который помещаем в среднее положение между всем, и считаем для него ShadowMap. У меня если лайты по суммарному расстоянию не дальше чем 1 метр друг от друга, то создается "виртуальный" источник.
Я лично, рендерю 8 мап одновременно, с упрощениями, соответсвенно
Aldaron
> + если у тебя несколько источников на близком расстояние друг от друга( const
> ), то делаем вместо них новый, который помещаем в среднее положение между всем,
> и считаем для него ShadowMap.
Во, во, это lightcut и есть
FROL
я не силен в названиях, обычно сижу с тетрадкой и пытаюсь что-нить придумать)
Aldaron
> У меня если лайты по суммарному расстоянию не дальше чем 1 метр друг от друга,
> то создается "виртуальный" источник.
проверку на препятствия между ними делаешь?
если разные радиусы?
цвет(в том числе и тени)?
качество теней?
статик/динамик лайт?
проверка на этапе старта или риалтайм?
наверное, не все так просто...
Тема в архиве.