Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по теням (из Example DirectX8/StencilBuffer/ShadowVolume) [Delphi, DirectX 9]


Страницы:   1 2 3

ElectriC ©   (2007-05-11 17:35:00) 

Как сделать, чтобы тени не рисовались на камере?


Sapersky   (2007-06-11 10:34:00) [21]

Похоже, что не всё так просто и методы эти не вполне эквивалентны.
Если рисовать по z-fail, рисуются части теневых объёмов ЗА отбрасывающим тень объектом (что логично, z-fail фактически означает "рисовать невидимое"). При отрисовке тени они вылезают наверх, и появляются лишние тени на объекте. То ли метод Кармака рассчитан на то, чтобы рисовать объект после теневых объёмов (но тогда никакого самозатенения), то ли я чего-то недопонял.
В общем, надо копать глубже, смотреть [Everitt and Kilgard 2002], или some good code and comprehensible presentations from http://developer.nvidia.com


ElectriC   (2007-06-10 17:25:00) [22]

function CMyD3DApplication.RenderShadow: HResult;
begin
 // Disable z-buffer writes (note: z-testing still occurs), and enable the
 // stencil-buffer
 m_pd3dDevice.SetRenderState(D3DRS_ZWRITEENABLE,  iFALSE);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILENABLE, iTRUE);

 // Dont bother with interpolating color
 m_pd3dDevice.SetRenderState(D3DRS_SHADEMODE,     D3DSHADE_FLAT);

 // Set up stencil compare fuction, reference value, and masks.
 // Stencil test passes if ((ref  and mask) cmpfn (stencil  and mask)) is true.
 // Note: since we set up the stencil-test to always pass, the STENCILFAIL
 // renderstate is really not needed.
 m_pd3dDevice.SetRenderState(D3DRS_STENCILFUNC,  D3DCMP_ALWAYS);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILFAIL,  D3DSTENCILOP_KEEP);

 // If ztest passes, inc/decrement stencil buffer value
 m_pd3dDevice.SetRenderState(D3DRS_STENCILREF,       $1);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILMASK,      $ffffffff);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILWRITEMASK, $ffffffff);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILPASS,      D3DSTENCILOP_INCR);

 // Make sure that no pixels get drawn to the frame buffer
 m_pd3dDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, iTRUE);
 m_pd3dDevice.SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ZERO);
 m_pd3dDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

 // Draw front-side of shadow volume in stencil/z only
 m_pd3dDevice.SetTransform(D3DTS_WORLD, m_matObjectMatrix);
 m_pShadowVolume.Render(m_pd3dDevice);

 // Now reverse cull order so back sides of shadow volume are written.
 m_pd3dDevice.SetRenderState(D3DRS_CULLMODE,   D3DCULL_CW);

 // Decrement stencil buffer value
 m_pd3dDevice.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);

 // Draw back-side of shadow volume in stencil/z only
 m_pd3dDevice.SetTransform(D3DTS_WORLD, m_matObjectMatrix);
 m_pShadowVolume.Render(m_pd3dDevice);

 // Restore render states
 m_pd3dDevice.SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
 m_pd3dDevice.SetRenderState(D3DRS_CULLMODE,  D3DCULL_CCW);
 m_pd3dDevice.SetRenderState(D3DRS_ZWRITEENABLE,     iTRUE);
 m_pd3dDevice.SetRenderState(D3DRS_STENCILENABLE,    iFALSE);
 m_pd3dDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, iFALSE);

 Result := S_OK;
end;

Можешь подсказать, что, примерно, нужно изменять в этой функции?


ElectriC   (2007-06-10 16:35:00) [23]


> Sapersky

Лана, попробую!


Sapersky   (2007-06-09 17:52:00) [24]

В примере из SDK8 (CMyD3DApplication.RenderShadow) реализован метод Z-pass:

for all front facing shadow quads from viewpoint do
   if Z-buffer test passes then
       increment stencil buffer value
   end if
end for

for all back facing shadow quads from viewpoint do
   if Z-buffer test passes then
       decrement stencil buffer value
   end if
end for

Нужно переделать его на Z-fail (см. ранее). Буквально несколько констант поменять. Может, сам сообразишь, какие? А то я всё равно проверить не смогу, нельзя в этом примере влезть внутрь тени.


ElectriC   (2007-06-09 16:47:00) [25]


> Я так и не въехал что за тень на камере??

Поставь камеру именно (внутрь) в тень!!!


ElectriC   (2007-06-09 16:46:00) [26]

Так я не понимаю, как реализовать это на дельфи?


Sapersky   (2007-06-09 13:22:00) [27]

Скриншот, ИМХО, здесь вообще не в тему. Телепатор подсказывает, что имеется в виду эта проблема (из 2-й ссылки в [14]):

I first implemented stencil shadow volumes over two years ago in the
post-Q2 research period. They looked great until you flew the viewpoint
into one of the volumes, and depending on the exact test you used, either
most of the screen went into negative shadow, or most of the shadows
disappeared.

Разглагольствования Кармака - это, конечно, интересно, но по 1-й ссылке решение проблемы описано более коротко и внятно:

First off, the algorithm only works if the viewpoint is outside of shadow, otherwise the stencil counting is inverted. This can be remedied by testing this special case, inverting the shadow test, and also initializing the stencil buffer to 2N−1 (where N is the stencil buffer precision), as the stencil buffer holds only unsigned values and decrementing from a zero value would again result in incorrect shadows. A more elegant solution is proposed in [Everitt and Kilgard 2002] , which was partially inspired by an insight of John Carmack, lead programmer of id software [Carmack 2000]. First off, instead of computing the stencil values by incrementing front facing shadow quads and decrementing back facing shadow quads on Z-buffer pass, the entire process is modified to count from infinity instead of from the viewpoint, the so called Z-fail version:

procedure COMPUTEFRAGMENTSINSHADOW(Z-fail)
for all shadow casting objects do
   compute potential silhouette edges (PSE) of the polygonal model
   compute the shadow volume polygons (shadow quads) from the light source(s) and the PSE
end for

for all front facing shadow quads from viewpoint do
   if Z-buffer test fails then
       decrement stencil buffer value
   end if
end for

for all back facing shadow quads from viewpoint do
   if Z-buffer test fails then
       increment stencil buffer value
   end if
end for

The two representations (Z-pass and Z-fail) are completely equivalent and compute the same value, yet they do not suffer from the problems mentioned above: the viewer being in shadow is no longer a special case.


@!!ex_   (2007-06-09 08:07:00) [28]

Я так и не въехал что за тень на камере??
На скрин щоте только тенб на кубе, но исправляется соответственно просто... Либо отбрасыванием тени кубом, либо отрисовку куба после отрисовки SV.


ElectriC   (2007-06-09 00:09:00) [29]

Блин, лаг что-ли с нетом;))


ElectriC   (2007-06-09 00:08:00) [30]

Может кто-нить помочь с написание кода на Delphi, который предотвращает рисование теней на камере?
P.S. Сам читал Help [14], но толком не понял, как это сделать?


ElectriC   (2007-06-09 00:08:00) [31]

Может кто-нить помочь с написание кода на Delphi, который предотвращает рисование теней на камере?
P.S. Сам читал Help [14], но толком не понял, как это сделать?


ElectriC   (2007-05-20 15:43:00) [32]

Можно как-нить оптимизировать теневые объёмы (двухсторонние трафареты, не предлагать - уже реализованы), а то при отбрасывании теней от сложных объектов + перемещение источника света -> наблюдается слишком большое падение кадров, при отрисовке теней. Если да, то как?
P.S. Если не трудно, ввиде исходного текста.


ElectriC   (2007-05-14 19:16:00) [33]

Спасибо.


Sapersky   (2007-05-14 18:29:00) [34]

Можно, и здесь даже написано, как:
http://www.devmaster.net/articles/shadow_techniques/
http://www.rasterise.com/CarmackOnShadowVolumes.txt
Но готового кода на Delphi, разумеется, нет.


ElectriC   (2007-05-14 17:20:00) [35]

А можно, как-нить, убрать рисование тени на камере?
P.S. Из-за этого появляются некоторые 'побочные эффекты' - экран перекрашивается в цвет тени, а тени - в белый цвет! Очень раздражает!


ElectriC   (2007-05-14 16:28:00) [36]

Спасибо за информацию.


Sapersky   (2007-05-14 14:06:00) [37]

Для начала рекомендую ещё раз перечитать
http://en.wikipedia.org/wiki/Source_engine#Future_technologies
(то, что слева)
и осознать ограничения, которые даёт данный метод.

Реализуется, думаю, примерно так же, как и статичное освещение лайтмэпами (lightmap). Т.е. на этапе создания уровня для каждого сектора  определяется источник света, от которого будут отбрасываться тени, зачем проходим по всем полигонам с определённым шагом и генерируем для них набор текстур, где точка, на которую может падать тень - белая, на которую не может (полигон развёрнут к источнику света задней стороной или точку заслоняют другие полигоны) - чёрная. Или, возможно, удобнее будет наоборот, поскольку тени чёрного цвета. При наложении тени комбинировать её с текстурой маски (умножать или ещё как-нибудь).
Примеры с лайтмэпами должны быть здесь:
http://dxlab.host.sk/index_en.html


ElectriC   (2007-05-13 16:44:00) [38]


> Sapersky

Та вы писали что-то про маску.

> Напрашивается некая заранее просчитанная "маска", что ли, которая
> будет отсекать задние грани и перекрытые другими поверхности.

Как её реализовать?


Sapersky   (2007-05-13 12:21:00) [39]

Что-то знакомое... а, вот:
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1165158185&n=9


ElectriC   (2007-05-12 17:54:00) [40]

Так тени рисуются правильно, просто нужно убрать этот глюк!
А как, я не знаю((


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо