![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по теням (из Example DirectX8/StencilBuffer/ShadowVolume) [Delphi, DirectX 9]
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]Так тени рисуются правильно, просто нужно убрать этот глюк!
А как, я не знаю((