MRT's and surface shaders

Discussion in 'Developer Preview Archive' started by Chickenlord, Jan 22, 2012.

  1. Chickenlord

    Chickenlord

    Member

    Joined:
    May 13, 2011
    Messages:
    381
    Hi,

    i've got a simple and quick question. As 3.5 comes with MRT support, how can one write to the other render targets in surface shaders? Is it possible at all?

    Thanks,
    Lennard
     
  2. Chickenlord

    Chickenlord

    Member

    Joined:
    May 13, 2011
    Messages:
    381
  3. jemast

    jemast

    Member

    Joined:
    Dec 7, 2011
    Messages:
    136
    Theoretically, I think you cannot switch or pick render targets from shaders (I'm no expert on the subject at all so take that with a grain of salt).

    Though you can do this from script with methods such as:

    Code (csharp):
    and

    Calling these methods before rendering passes that require separate/additional render targets should do the trick (for cameras, I'd try calling this in OnPreRender and OnPostRender methods but that's just a shot in the dark, haven't tried at all).

    By the way, they're both documented in the offline beta scripting reference (you can access it from Unity's Help menu).

    Edit: Actually, the Graphics.SetRenderTarget allows settings multiple render targets in one pass and the docs mention that "The function call with colorBuffers array enables techniques that use Multiple Render Targets (MRT), where fragment shader can output more than one final color.". If you cannot get these multiple outputs from surface shader, a last resort method may be to use "open compiled shader" method from one of your surface shaders where you want to use MRT and start from there.

    Edit2: Okay, after educating myself on the subject, it seems there are no documented feature for what you're looking for in surface shaders. Looks like you could file a feature request.
     
    Last edited: Jan 28, 2012
  4. Cameron.

    Cameron.

    Member

    Joined:
    Jun 1, 2009
    Messages:
    726
    Having MRT output for surface shaders would be nice, coupled with the newly included GL MIN/MAX blend modes would allow for some really nice methods of building info about the scene for much more complex post effects.
     
  5. brianasu

    brianasu

    Member

    Joined:
    Mar 9, 2010
    Messages:
    281
    Probably use Graphics.SetRenderTarget(RenderBuffer[] ...
    Then in your shader besides outputting a single Color you would output a custom struct
    struct COL_OUTPUT
    {
    float4 Col0 : COLOR0;
    float4 Col1 : COLOR1;
    float4 Cor2 : COLOR2;
    };

    and in your shader

    COL_OUTPUT frag(v2f i)
    {
    COL_OUTPUT o;
    ... shader stuff
    o.col1 = something;
    o.col2 = something;
    o.col3 = something;
    return o;
    }
     
  6. Chickenlord

    Chickenlord

    Member

    Joined:
    May 13, 2011
    Messages:
    381
    Well, if i haven't missed anything this is not possible to achieve with surface shaders. Of course it's possible to return multiple results in standard cg vert/frag shaders, but i don't think anybody wants to convert all the surface shaders to standard ones using debug and in addition this would kill all the nice things surface shaders have to offer...
     
  7. ole

    ole

    Unity programmer

    Joined:
    Sep 30, 2010
    Messages:
    56
    as far as i know there is no easy way to make it work with surface shaders atm. but there is a way: uncollapse them via #pragma debug and then write for the various passes to the different buffers, just as brianasu suggested.

    EDIT: saw your post too late, but yes, for the time being MRT support mostly addresses possible post and custom FX speed-ups.
     
  8. romeo_ftv

    romeo_ftv

    Member

    Joined:
    Oct 20, 2009
    Messages:
    32
    ole,
    you plan to implement the builtin imagespace motion blur effect?