Welcome, Guest.
Username: Password: Remember me

TOPIC: Depth buffer modifications

Depth buffer modifications 6 months 3 weeks ago #1

Hi all, I'm trying to render solid shapes to a buffer, either per draw call or per geometry instance/object id or whatever the proper term is. I don't know if that makes sense, so here's some images showing you what I've done strictly in shaders and the shortcomings therein that led me to start working in the source code to try and find a way.





So basically the top image is the unmodified depth buffer, the bottom has some simple stepping applied to it. The third image is a better example of where the stepping really starts to fall apart. I thought that might be enough for what I wanted to accomplish, but it would be much nicer to have basically an object map to define individual meshes in tandem with the two versions of the depth pass. The application for this is for making physical art in real life using my laser cutter with thin wood.

Any ideas?
The administrator has disabled public write access.

Depth buffer modifications 6 months 2 weeks ago #2

This is not trivial to do and requires a lot hacking with ReShade's source code. Best way I can think of is to change the depth stencil state for each draw call of the game so that stencil testing is active and set to replace the value in the stencil buffer when the test passes. Then just change the stencil reference value on each draw call (e.g. just have a counter that increases by one each time and is reset to zero the next frame). Finally make sure the same depth stencil buffer with a format that supports stencil is bound for all those draw calls and you should have a buffer which contains both depth and object IDs (in the stencil portion of the buffer).

In case of D3D11, on each draw call:
1) Call "OMSetDepthStencilState(state, geometry_id++ % 255)" with a state that has the following set in the D3D11_DEPTH_STENCIL_DESC and where "geometry_id" is just a global variable that is set to zero once:
DepthEnable = true;
DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
DepthFunc = Whatever the game uses;
StencilEnable = true;
StencilReadMask = 0xFF;
StencilWriteMask = 0xFF;
FrontFace/BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
FrontFace/BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
FrontFace/BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
FrontFace/BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
2) Make sure the bound depth stencil has a format that supports stencil, otherwise create your own and bind it with "OMSetRenderTargets" (can use "OMGetRenderTargets" to get the render targets of the game first and only replace the depth stencil buffer). And by supporting stencil I mean that the texture which was used to create the depth stencil view is of format DXGI_FORMAT_D24_UNORM_S8_UINT or DXGI_FORMAT_D32_FLOAT_S8X24_UINT (note the S8).
3) After the game finished rendering, read back the data from the stencil portion of the texture as well as the depth portion. ReShade source code shows how to bind a depth texture as a shader resource. It does not bind the stencil part. So you'd have to come up with that.

As you can see this is quite a lot of work and requires decent knowledge of the graphics API the game you wish to do this for was written with. Wish it was easier, but I don't think there is a simpler away to get actual geometry IDs.

There may be ways to try simple object detection using just the depth data in a shader instead (by infering normals and using that to detect hard object edges).
Cheers, crosire =)
The administrator has disabled public write access.
The following user(s) said Thank You: Audio

Depth buffer modifications 6 months 2 weeks ago #3

First off, thank you for taking the time to write such an informative reply! That was far more than I had hoped to receive.

I'll take a look at the points you listed and see what I can do. If you never hear from me again, it's safe to assume I gave up. Otherwise, I will post again once I have results and/or questions.

Either way, thank you for your time and the awesome work done on reshade :)
The administrator has disabled public write access.