Home Unity

Is there a way to fetch PBR attributes and normals in a deferred fragment shader?

polycounter lvl 10
Offline / Send Message
bac9-flcl polycounter lvl 10
The title pretty much covers it.

I want to create an opaque per-pixel fragment shader that:
  • Will be rendered after all normal opaque surfaces but before all transparent surfaces
  • Will have albedo, specular, smoothness, occlusion values and normals fetched from the deferred render targets (for each given pixel)
  • Will output those fetched RT values

Basically, this will make the shader completely invisible, as it will just write back the content of deferred render targets. This is the base I need to create proper UE4-like normal decals and some other stuff, but those are the easy part. What I need to figure out right now is how can I get that content from RTs. I'm unable to find anything about this in the documentation, but this should be possible - after all, Unity already offers a way to fetch values like linear eye depth, so asking to fetch something like smoothness is not exactly an exotic thing.

Can anyone help me out?

Replies

  • echofourpapa
    Offline / Send Message
    echofourpapa polycounter lvl 4
    Yes. Here's the layout:

    sampler2D CameraGBufferTexture0 is diffuse(rgb)
    sampler2D CameraGBufferTexture1 is Specular(rgb) and roughness(a)
    sampler2D CameraGBufferTexture2 is world-space normals(rgb)
    sampler2D CameraGBufferTexture3 is lighting(rgb)

    Use those in any shader.

    Docs here: http://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

    But you might find this more interesting: http://blogs.unity3d.com/2015/02/06/extending-unity-5-rendering-pipeline-command-buffers/
  • bac9-flcl
    Offline / Send Message
    bac9-flcl polycounter lvl 10
    Thanks! Unfortunately, I have a few issues with those textures. Specifically:

    - Those textures do are not sampled properly at all if my shader has no decal:add or decal:blend - I get a completely random surface texture within _CameraGBufferTexture0 and others if I attempt to read it from an ordinary opaque shader.

    - Sometimes those textures jump around wildly or contain pure black, which to me suggests that the decal renders too early - but setting the queue/type to transparent does absolutely nothing to solve the issue. Only decal:add or decal:blend solve it, which makes me wonder what's so special about those attributes. Nothing out of ordinary is documented about them.

    - If I do use decal:blend or decal:add, absolutely nothing I do in finalgbuffer function is seems to affect the surface, so I can not actually put the values I read from the buffers back into them, it seems. I suspect that happens because decal:add and decal:blend force my shader to go into forward mode, which is obviously not desirable at all. Maybe it's completely impossible to read those textures from a deferred shader and I should look for other approach to implementing normal decals.

    As about command buffers, I looked at the example and I have to admit I was not able to understand anything useful out if it. I need a far, far more simple thing - a surface shader for geometry that already has proper placement and UV mapping. The example is filled with code handling projection, boxes, keeps per-decal object references, does strange blit operations in a special component and so on, which makes it really hard to understand how to apply it to a simple surface decal shader. For reference, I'm trying to replicate a shader similar to these from UE4 and CE: http://www.polycount.com/forum/showthread.php?t=155894
Sign In or Register to comment.