Search Unity

_CameraDepthTexture.g to access the stencil values?

Discussion in 'Image Effects' started by Deleted User, Sep 24, 2016.

  1. Deleted User

    Deleted User

    Guest

    I'd like to be able to read the stencil value of a nearby pixel.

    When I frame debug with RenderDoc, it shows that my shader has a texture input in R32G8 format. The R being the depth, and the G8 being the 8 bit stencil. And it shows my values of 128 in the pixels where I expect it to be, so all looks good.

    My shader has no _MainTex or any other texture property, except for sampler2d _CameraDepthTexture;

    Yet, if I try to access _CameraDepthTexture.r in the shader, I get values. But if I try to access _CameraDepthBuffer.g, I get nothing but 0's?
     
  2. Deleted User

    Deleted User

    Guest

    ... I just read somewhere that it's not possible due to the fact that GPU's are massive multithreaded blah blah blah's.

    But that makes no sense in my case, since I'm fully finished rendering before I do it. I'm doing it in a post-processing shader. The picture's already done. I can even read the nearby pixel's colors, simply by sampling them.

    But I know the stencil is saved per-pixel. Why can't I then sample the stencil? It's done being rendered, I see no reason why not?
     
  3. Deleted User

    Deleted User

    Guest

    Plus, I can sample the depth texture easy enougn, it's at _CameraDepthTexture.r. If I can sample nearby pixel's depths, and I can sample nearby pixel's colors, why can't I sample nearby pixel's stencil values?
     
  4. Deleted User

    Deleted User

    Guest

    Plus, RenderDoc is an external program that integrates with Unity, and it can "analyze" a frame and sprews out all the stencil data for every pixel.

    So is someone gonna tell me that RenderDoc gets to read my stencil values from outside Unity (it's a separate program), but from within Unity itself I can't? Seems legit. :p
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    You can request the stencil information from the GPU to read back to the CPU, but it's pretty slow so it's not something you want to do normally, but totally fine for something like RenderDoc that's for debugging.

    You can make a copy of the depth buffer (which includes the stencil) and save it to a texture, which is exactly what Unity already does, but that functionality isn't directly exposed to script and Unity only saves the depth to the texture instead of depth and stencil, mainly because the image formats that store both depth and stencil aren't available to all platforms to be sampled as a texture. They could store two textures, one with the depth and one with the stencil, but it's one of those features that is so rarely required it's probably not worth the time for them to implement and those who might know about and actually want that functionality are likely the larger studios who are paying for source access so they can just add it themselves (though I wouldn't be surprised if literally no one has ever implemented this for Unity, ever).

    It's plausible once Unity releases their planned scriptable render loop that this will become possible, but probably not.
     
    zhuhaiyia1 likes this.
  6. Deleted User

    Deleted User

    Guest

    Thanks for the reply. You are awesome by the way, you've helped me before on this forum :)

    The reason I'm trying to directly access the stencil is because the thing you said about "you can make a copy of the stencil and save it as a texture" isn't... exactly... feasible. At least not with CommandBuffer.Blit().

    I guess you've probably seen me spamming about this issue all over this forum for 6 days now. If it was possible to just casually make a black and white texture based on the stencil, I wouldn't still be here. ;P

    Here's the summary though:

    1) If you blit from the screen to a rendertexture, you can't use a custom shader... or else the resulting render texture is blank. Also, it doesn't copy the stencil to that render texture.

    2) If you blit from a render texture, to another render texture, the stencil can't be access in the shader. It just can't. Tried, tried, and tried again. Probably because as I said in #1, stencils aren't copied to render textures. So since neither of the textures have the stencil... well... then no stencil for the shader to use.

    3) If you blit from a render texture to the screen, everything works (weee!!), but now you just over-written the picture on the screen. You'd then have to fix that, I suppose with another blit to put the original picture back again.

    In the end yeah it's possible but it requires too many blits.

    -> first blit is from screen to render texture, with no shader, since as I said in #1 above, you can't blit from screen to rendertexture wtih a custom shader or else it's blank.
    -> second blit is from that render texture to screen, to make the stencil image, since as I said in #2, you can't blit from a RT to another RT, or else there is no stencil... but anyway now you just put the black and white picture on your screen so screen is screwed up.
    -> third blit is from screen to render texture, again with no shader allowed (see #1 above), just to "save" the stencil image you made. Or else, if you skip this step, how are you gonna use it later?
    -> fourth blit is from the original render texture, back to the screen again, with a shader to do some post processing effect. You'd have to set the stencil image to a global property, so that this shader would have it also to work with.

    That's a minimum of 4 blits just to make and use this stencil texture. Now you see why I'm fussing with this for so long. Sure, it can be done, but this is 4 blits. I'd happily do it if it could be done with just one blit from screen to screen, using a custom shader, but oh yeah I forgot to mention:

    4) You can't blit from screen to screen. :(
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Sorry, that phrasing might of been too nebulous. The "you" in "you can" is referring to "you" in the general sense of its possible for someone else to ... if that person is writing their own engine from scratch or has source code level access to the engine, which you specifically are not doing since you're using Unity and do not have if you're using Unity and not paying several hundred thousand dollars.

    You cannot get access to the stencil buffer as a texture unless Unity adds features to the engine that it current does not expose, apart from the exceptional circuitous route you've already come up with.
     
  8. Deleted User

    Deleted User

    Guest

    Well, what got me started trying to do this is @Tim-C said it was possible to do it, in this post: http://forum.unity3d.com/threads/on...buffers-of-source-active.428738/#post-2775081

    And in his post, he seemed to indicate that he had tested it, and that it worked. But his method simply does a blit from the screen, to a render texture, with a shader. And as I said in point #1 above, that doesn't work. I spent the last 6 days trying to figure out why not, because if that did work, it would cut down on the number of blits.

    I'm guessing it used to work, but broke in the latest version of unity. My theory is that not very many people use CommandBuffer right now, so they let several breaks such as these slip through in the 5.4.1 update, and nobody complained because nobody is using CommandBuffer. Stinks for me. Also @Tim-C hasn't responded, I've been tagging him in my posts for days lol.

    Anyway thanks for the help. I'm considering to just go back to using Graphics.Blit, since incidentally, I already know Graphics.Blit can do all of this without most of these issues. I guess I just really wanted to use CommandBuffer.Blit so that I'd be more cutting edge and have more options, but I need to bite the bullet and accept that I lost this battle.
     
  9. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Hey :) I'm back now. I've been in a deep refactoring hole (actually trying to clear up some of the back end around this that is causing issues). I'll write a response tomorrow :)
     
  10. Deleted User

    Deleted User

    Guest