Search Unity

[SOLVED] Reflection Probe Cubemap From Camera With Post Processing Stack v2

Discussion in 'Shaders' started by GuitarBro, Jun 11, 2019.

  1. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    (Boy, that title is a mouthful... also not sure if this is the best forum category for this since it touches on so many subjects, but whatever.)

    I'm essentially attempting to dynamically capture the sky in a slowly-updating cubemap so that a reflection probe can use it for world reflections. See picture:
    upload_2019-6-10_21-4-26.png

    Why? Because the clouds are rendered as a post process effect using Post Processing Stack v2 and they contribute significantly enough to make a considerable difference in the lighting. Which brings me to the general problem: I can't figure out what steps are necessary in order to ensure camera post effects are applied as expected when rendered to a cubemap instead of a traditional 2D texture. You can see in the screenshot that not all the cubemap faces are correctly using their history buffers in the post effect (the closest one on the left/front is considerably smoother than the top or right faces which are grainy).

    I expect this is an issue with the post processing effect, however I am new to creating custom Stack v2 effects and the documentation is pretty minimal to say the least (not to mention I don't think rendering to cubemaps is a typical use case). I just don't know what I'm doing wrong. I've been looking around for anything that might point me in the right direction, but after exhausting all the Google searches I can think of and not finding what I need, I've given up and resigned myself to posting here. ;)

    For reference, the cloud effect I'm using can be found here: https://github.com/GuitarBro/VolumeCloud/tree/StackV2 (which was my attempt at a Stack v2 port of Yangrc's excellent VolumeCloud effect that can be found here: https://github.com/yangrc1234/VolumeCloud). It works great on my main camera, but clearly not on my cubemap camera.

    As a vague guess, I suspect my issues lie somewhere in VolumeCloudPPS.cs where the different buffers are set up and in CloudShaderPPSv2.shader which manipulates the buffer textures. Unfortunately, my lack of Stack v2 custom effects and the lack of documentation on creating Stack v2 effects (that work with cubemaps) pretty much stops me there. I just don't know what I don't know. :(

    Any help would be appreciated.
     
  2. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    Oh, I should also mention I'm using Camera.RenderToCubemap to actually render the cubemap. Perhaps, that's obvious, but I figured I should mention just in case.
     
  3. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    Any Post Processing Stack v2 wizards out there that wouldn't mind writing up some advanced custom effect docs? Still no luck on this here and it would really just help if I knew more about how it treats things like cubemap cameras. :(
     
  4. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    Ah! I finally figured it out. Persistence paid off for once. ;)

    The main issue was that the shader uses the last frame's worldToCameraMatrix for temporal reprojection, but when rendering a cubemap, the post processing stack Render() is invoked for each face (6 times per RenderToCubemap()). Naturally, the effect object is the same between calls and as such, the variables persist. This leads to the "last frame's matrix" variable being updated to be the "last face's matrix" instead, which is obviously useless in this context.

    Consequently, any frame history values must be stored in an array of length 6 if you want it to work with a cubemap (with additional logic to initialize and cleanup such arrays, obviously). This applies to rendertextures as well: if you have a texture storing the previous frame's output, you now need 6 of them and some incremental counter that resets on 6 to keep track of which face is currently being rendered. A request to the post processing stack guys: please expose a "current cubemap face" variable in the render context so this doesn't have to be tracked manually for each effect.

    In my case, since the worldToCameraMatrix is stationary between frames relative to each cubemap face, I simply opted to add a bool to skip this step if it's being rendered into a cubemap. Less effort and a (very small) bit less rendering work.
     
    hadynlander likes this.
  5. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    As a bonus, enjoy a nice video of the cubemap updating in realtime:
     
  6. ffertigo

    ffertigo

    Joined:
    May 31, 2015
    Posts:
    12
    beautiful! what sky system are you using?
     
  7. GuitarBro

    GuitarBro

    Joined:
    Oct 9, 2014
    Posts:
    80
    ffertigo likes this.
unityunity