Показать сообщение отдельно
Старый 16.05.2014, 01:15   #216
Mr_F_
Терабайт исходников
 
Аватар для Mr_F_
 
Регистрация: 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 нулю, получается только этот столб осветится, а не целый шар на экране.
__________________
бложик | geom.io | твиттер | faded | демо 1 2 | роботы | лайтмаппер
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо Mr_F_ за это полезное сообщение:
HolyDel (16.05.2014), mr.DIMAS (16.05.2014), Randomize (16.05.2014)