|
14.05.2014, 22:44
|
#211
|
Быдлокодер
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 5,021
Написано 2,312 полезных сообщений (для 5,349 пользователей)
|
Ответ: [TrueHorror] - разработка
Сообщение от tirarex
А хрен его знает как правильно , я поглядел разные игры и можно увидеть что в кадре динамического света очень мало (1-10) редко где больше 10 светильников было .
|
Даже меньше чем 10 и в зависимости от антуража.
Например на дневной локации будет только один источник света - солнце.
Те же пещеры (то что я замечал), делают с учётом того что бы в одной части не больше 2-3 источников, остальное скрыто. То бишь из просторной пещеры вошёл в "кишку", дальше опять большое пространство. В каждой такой части и будет не больше 2-3 источников. Свет активен только в той части где игрок, + совмещают с картами освещённости. И ещё дизайн локации, то есть две части пещеры не на одной линии, что бы из одной части нельзя было видеть что в следующей.
По большей части это мои предположения.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Arton за это полезное сообщение:
|
|
15.05.2014, 12:20
|
#212
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
Народ ну чё за ботва. Подкиньте идеек по оптимизации.
__________________
|
(Offline)
|
|
15.05.2014, 12:54
|
#213
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: [TrueHorror] - разработка
Нужно сцену смотреть.
Куча лайтов с пересекающейся зоной влияния - много овердро.
Куча отдельных маленьких - должно норм пахать.
А, Ну дак у тебя на каждый лайт фулскрин квад рисуется!
Надо кваду ограничивать зону влияния, иначе тут в любом случае жутчайший овердро.
Известные способы (не мешающие друг другу):
1. Рисовать не фулскрин квад, а квад поменьше, в который вписывается зона влияния лайта. Часто лайты не влияют на весь экран.
2. Рисовать грубый меш по форме зоны влияния лайта (лоуполи сферу для поинта, конус для спота). Рисовать его только в стенсил (не в глубину, не в цвет). Юзать настройки стенсила, как со стенсильными тенями в Depth Fail методе (2 раза не надо только волум рисовать, есть хардварный two-sided stencil):
http://en.wikipedia.org/wiki/Shadow_volume
Это даст тебе помеченные в стенсиле пиксели, куда влияет лайт (где он пересекается со сценой). Дальше рисуешь экранный квад, но настраиваешь стенсил так, чтобы он проявлялся только в помеченых волумом местах. Стенсил тест идёт до выполнения шейдеров.
Это точнее, чем вариант 1, который не учитывает пересечение с збуфером, но вариант 1 тоже не помешает, чтобы сократить число пикселей квада, тестящих стенсил.
---
По мелочам из кода:
vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1View, &view );
vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1Proj, &proj );
vertexShaderPassOne->GetConstantTable()->SetMatrix( g_device, v1World, &world );
|
pixelShaderPassTwo->GetConstantTable()->SetFloatArray( g_device, p2LightPos, temp, 3 );
pixelShaderPassTwo->GetConstantTable()->SetFloat( g_device, p2LightRange, light->radius );
|
- многовато лишних действий. много за 1 вызов заливать все матрицы и за 1 все параметры лайта:
SetVertexShaderConstantF
SetPixelShaderConstantF
необязательно по имени брать константы из шейдера, можно замаппить их напрямую в нужные регистры типа
const float4x4 MatWorldViewProj : register(c0);
const float4x4 MatWorld : register(c4);
с# - номера констант, они измеряются в float4, это нативный формат видюшной константы (на самом деле флоаты и флоаты2/3, это все равно неполные флоаты4 или их части).
Но если у тебя там не тысячи объектов, это всё мелочи - просто так удобнее, быстрее, контроллируемее, имхо.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Mr_F_ за это полезное сообщение:
|
|
15.05.2014, 16:19
|
#214
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
Спасибо ОГРОМНОЕ! Как сделаю, так сразу отпишусь о результате.
__________________
|
(Offline)
|
|
16.05.2014, 00:36
|
#215
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
Раньше никогда не работал с буфером трафарета и вот наткнулся на грабли. Вроде все работает как надо - да вот только когда попадаешь в несколько ограничивающих сфер сразу( у меня точечные источники света ) - фпс падает в 2 раза. Причем если источники стоят не пересекаясь между собой - то все норм - фпс 60 ( при разрешении 2560х1440 ). Все норм и при взгляде на всю сцену.
Гляньте код( особенно где трафарет настраивается ) - Mr_F_ я взываю к тебе
http://pastebin.com/FxUaau8D
Демка в аттаче - 60 источников света.
Комменты к скринам: 1 - камера в нескольких ограничивающих сферах одновременно. 2 - там же, взгляд в пол. 3 - вся сцена из далека. 4 - в сцене между источниками света( не попадаю ни в одну ограничивающую сферу )
__________________
|
(Offline)
|
|
16.05.2014, 01:15
|
#216
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: [TrueHorror] - разработка
Гляньте код( особенно где трафарет настраивается ) - Mr_F_ я взываю к тебе
|
g_device->Clear( 0, 0, D3DCLEAR_STENCIL, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0, 0 );
|
Clear на каждый лайт не надо делать - это считай тот же фулскрин квад рисовать по филлрейту, медленно.
Вместо этого, когда рисуешь обрезаемый стенсилом квад с шейдингом лайта, ставь ему STENCILPASS = D3DSTENCILOP_ZERO, он тогда автоматически собой затрёт только в нужном месте.
g_device->SetRenderState( D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
g_device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP );
g_device->SetRenderState( D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP );
g_device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE );
// draw a sphere bounds light into stencil buffer
g_device->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, icosphereVertexCount, 0, icosphereFaceCount );
// now stecil buffer contains bounding sphere of the light
g_device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
g_device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
|
Не то делаешь. Ты, похоже, рисуешь в стенсил шарик и маркируешь его единицей. Естественно, когда ты внутри шарика, он занимает весь экран.
Так ты мог и без стенсила обойтись, а сразу рисовать шарик с шейдером лайта.
А идея со стенсилом в том, чтобы пометить только пиксели, с которыми соприкасается (!) шарик. В которые он въехал. Где intersection с z-буфером. Тогда неважно, если ты внутри шарика. По сути задача получить реальную 1-битную маску конкретно освещения от лайта.
Могу перепутать что-то местами (incr/decr), но вроде суть такова (псевдокод):
TwoSidedStencilMode = TRUE
CullMode = None
StencilFunc = Always
StencilZFail = D3DSTENCILOP_DECR
CCW_StencilFunc = Always
CCW_StencilZFail = D3DSTENCILOP_INCR
Представь, что рисуешь шарик, нанизанный на столб. Где внутри шарика не виден столб - там за фронтфейсами всегда видны бекфейсы.
Где фронтфейсы и бекфейсы не пересекаются с тем, что в збуфере - ничего не меняется (ZFail не вызывается).
Где и те и другие где-то под землёй/в стене - одни делают +1, другие -1, ничего не меняется.
А вот там, где у тебя в шарике столб, только бекфейсы вызовут ZFail, в результате столб внутри шара пометится чем-то отличным от 0.
Дальше рисуешь квад с шейдингом лайта с StencilFunc = NotEqual нулю, получается только этот столб осветится, а не целый шар на экране.
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо Mr_F_ за это полезное сообщение:
|
|
16.05.2014, 01:25
|
#217
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
Тоесть Z-буфер не очищать после первого прохода, только запрещать в него запись. Затем для каждого источника света рисовать шарик и проверять, где он не прошел тест глубины, тогда получим силуэт реально освещенной части объекта, находящийся в буфере трафарета. А затем уже рисуем экранный квад с отсечением по трафарету. Так?
__________________
|
(Offline)
|
|
16.05.2014, 01:39
|
#218
|
Быдлокодер
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 5,021
Написано 2,312 полезных сообщений (для 5,349 пользователей)
|
Ответ: [TrueHorror] - разработка
Сообщение от Arton
Даже меньше чем 10 и в зависимости от антуража.
Например на дневной локации будет только один источник света - солнце.
Те же пещеры (то что я замечал), делают с учётом того что бы в одной части не больше 2-3 источников, остальное скрыто. То бишь из просторной пещеры вошёл в "кишку", дальше опять большое пространство. В каждой такой части и будет не больше 2-3 источников. Свет активен только в той части где игрок, + совмещают с картами освещённости. И ещё дизайн локации, то есть две части пещеры не на одной линии, что бы из одной части нельзя было видеть что в следующей.
По большей части это мои предположения.
|
Добавлю. Пример из Dark Souls 2. На первом скриншоте, несмотря на источник света в тёмном помещение, по логике от предметов должны быть тени, но их нет:
Но стоило зажечь факел, как главным источником света стал он и чудесным образом появились тени:
Да, не самый лучший пример, DS это всё таки изначально консольный проект, а значит в первую очередь оптимизировали под них.
P. S. Судя по всему этот "закон" актуален для всех локаций. В DS нету смены дня и ночи, каждая локация статична, и как правило тёмная, или хотя бы закат
P. P. S. На одно локации, в маленькой пещере костёр, он главный источник света и теней, зажёг факел, стало два источника, но тени только от факела в руке персонажа.
|
(Offline)
|
|
16.05.2014, 01:39
|
#219
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
Тоесть Z-буфер не очищать после первого прохода, только запрещать в него запись. Затем для каждого источника света рисовать шарик и проверять, где он не прошел тест глубины, тогда получим силуэт реально освещенной части объекта, находящийся в буфере трафарета. А затем уже рисуем экранный квад с отсечением по трафарету. Так?
|
Походу реально так.
Вот код
http://pastebin.com/3x732dwj
Работает все очень шустро - в любом месте 60 фпс.
Демка в аттаче ( 60 источников света )
2Mr_F_ Просто огромное спасибо за разъяснения. То чувство, когда пришло прозрение.
__________________
|
(Offline)
|
|
16.05.2014, 01:51
|
#220
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: [TrueHorror] - разработка
Тоесть Z-буфер не очищать после первого прохода, только запрещать в него запись. Затем для каждого источника света рисовать шарик и проверять, где он не прошел тест глубины, тогда получим силуэт реально освещенной части объекта, находящийся в буфере трафарета. А затем уже рисуем экранный квад с отсечением по трафарету. Так?
|
типа того, только не просто где шарик не прошёл тест глубины, а именно где только одной стороной повернутые фейсы прошли, а другой не прошли - это будет часть именно внутри шарика.
Работает все очень шустро - в любом месте 60 фпс.
|
ура!
для дебага можно тупо один цвет вывести в шейдере лайта - сразу будет видно на каких пикселях считается лайт, убедиться что всё как надо.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
16.05.2014, 01:57
|
#221
|
Дэвелопер
Регистрация: 26.12.2006
Адрес: Санкт-Петербург
Сообщений: 1,572
Написано 547 полезных сообщений (для 1,540 пользователей)
|
Ответ: [TrueHorror] - разработка
для дебага можно тупо один цвет вывести в шейдере лайта - сразу будет видно на каких пикселях считается лайт, убедиться что всё как надо.
|
Вот:
__________________
|
(Offline)
|
|
16.05.2014, 02:31
|
#222
|
Мастер
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений (для 504 пользователей)
|
Ответ: [TrueHorror] - разработка
хочу просто сказать, что после закрытия приложения выходит ошибка:
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
16.05.2014, 14:27
|
#223
|
Бывалый
Регистрация: 23.11.2011
Сообщений: 863
Написано 334 полезных сообщений (для 866 пользователей)
|
Ответ: [TrueHorror] - разработка
Хех , 60фпс , а как такого эффекта добиться ?
С моим деферредом 60 фпс при 10 светильниках
|
(Offline)
|
|
16.05.2014, 14:37
|
#224
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: [TrueHorror] - разработка
на самом деле способ со стенсилом ещё далеко не самый быстрый
на directcompute можно ещё круче наворотить (чем сейчас и занимаюсь)
|
(Offline)
|
|
16.05.2014, 14:58
|
#225
|
Бывалый
Регистрация: 23.11.2011
Сообщений: 863
Написано 334 полезных сообщений (для 866 пользователей)
|
Ответ: [TrueHorror] - разработка
Как я понимаю там сферы рендерятся ?
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 09:21.
|