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的设置一致的

posted on 2021-04-08 18:21  minggoddess  阅读(294)  评论(0编辑  收藏  举报