ue mobile 延迟光照 点光源 volumtric测试/ue stencil buffer的使用
point light
的volumtric
camera 在volumtric外面
1.第一个drawcall 开深度测试 模板写入
渲染volumetric的frontface(cull back 渲染球靠近camera的一半)
深度测试 留下远的 绿色通过 红色区域depth fail 模版写入1
depth test 结果标识
模板值写入
2.第二个draw 同时开深度 模板测试
渲染volumtric的backface(cull front
深度测试留下近的 绿色区域通过
depth test结果标识
模板测试绿色通过
模板测试
用深度测试和模板测试 把两个球中间的部分留下
用深度测试把 比远处半球近的留下, 用模板测试把这其中比近处半球更近的剔除
留下的这部分 会进行point light shading
无论模板测试通过还是 fail都写入0
模板值写入0 把之前标记清0
中间那个ui红色 还有天空红色是因为它是unlight 这里为什么第二个drawcall 模板测试fail了 接着往下看
D3D11_DEPTH_STENCIL_DESC dsDesc; // Depth test parameters dsDesc.DepthEnable = true; dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDesc.DepthFunc = D3D11_COMPARISON_LESS; // Stencil test parameters dsDesc.StencilEnable = true; dsDesc.StencilReadMask = 0xFF; dsDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create depth stencil state ID3D11DepthStencilState * pDSState; pd3dDevice->CreateDepthStencilState(&dsDesc, &pDSState);
stencil 一共8bits
AAAA AAAA
7654 3210 第几位
xxxx 8421
read mask /write mask 会和 stencilbuffer 和ref val 按位与 得到要操作的那位
比如 01 操作第1位
0f操作前4位
第一个drawcall
第二个drawcall
front cull 看back
write 第一位 全部写0
read 做stencil test 关注前4位
等于02的通过
第7位标记用不用decal
第3位标记aa
第1-3位在mobile上标记shading model
7 <<1 0111左移1位 1110
所以前面stencil 02就是defaultlit
stencil 00是unlit
write mask 0000 0001 & ref 0000 0001
point light volume 的stencil 标记打在第0位 写1
stencil 标记结果 03
第2个drawcall 测试的时候 读取前4位
等于02的通过 之前被标记 deferred default light的
因为第一个pass 不合法的被标记了 01 stencil这里也被剔除了
ui 因为unlit 标记的00被stencil test剔除了
天空因为标记的80 被stencil test剔除了 decal 并且unlit
测试天空default light时 stecil test 没有剔除天空 因为前四位 02 ,但天空是被第二个drawcall的深度测试剔除了的
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState< true, CF_DepthNearOrEqual, true, CF_Always, SO_Keep, SO_Keep, SO_Replace, false, CF_Always, SO_Keep, SO_Keep, SO_Keep, // don't use masking as it has significant performance hit on Mali GPUs (T860MP2) 0x00, 0xff >::GetRHI());
ue设置depth stencil的代码大概是这样 backface 如果是false 它后面4个参数是无效的 renderdoc抓到的 pass op并不是这里设置的keep 而是replace 猜测是和front的设置一致的