Search Unity

post processing thermal vision shader

Discussion in 'Shaders' started by aubergine, Feb 1, 2011.

  1. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    EDIT:
    THIS SHADER WENT COMMERCIAL AND CAN BE DOWNLOADED FROM THE ASSET STORE.

    (If you were lucky enough to grab it previously, you are free to use it anyway you want but i would appreciate your support if you buy it before using in a commercial product.)
     
    Last edited: Jun 23, 2011
  2. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,435
    I'm trying to learn more about image effects so this is perfect timing, thanks for sharing. I noticed that the docs on how to write image effects are pretty sparse, any suggestions on where to look for more info or maybe even a tutorial?
     
  3. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    just look at the source files that are already supplied, finally the thing is same as any ordinary shader except that you work with 1 image file.

    and for the formulas, nvidia shader library and some glsl( strangely they are more common) shaders which can be found around the internet are your friends.
     
  4. Cameron860

    Cameron860

    Joined:
    Jun 1, 2009
    Posts:
    764
    The shader replacement resource also has a lot of simple examples.
     
  5. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    where is this shader replacement resource?
     
  6. Cameron860

    Cameron860

    Joined:
    Jun 1, 2009
    Posts:
    764
  7. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    Would you kindly show how else it could be written without conditionals?
     
  8. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,087
    Code (csharp):
    1.  
    2. float ix = (lum < 0.5) ? 0.0 : 1.0;
    3. float4 res1 =  lerp(colors[0], colors[1], (lum - ix*0.5)/0.5);
    4. float4 res2 = lerp(colors[1], colors[2], (lum - ix*0.5)/0.5);
    5. float4 thermal = lerp(res1, res2, ix );
    6.  
    CONDITIONALS BE GONE!!

    (I didn't closely check syntax or anyhting so there might be an error. Principle remains the same though. Lerps > if's!
     
  9. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    Correct me if im wrong, but isnt the above still a conditional?
     
  10. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,087
    You are correct...

    Code (csharp):
    1.  
    2. float ix = step(lum, 0.5);
    3.  
    That will fix it up for you for OpenGL (ARB) (it will use the SGE instruction). But that doesn't exist on PS2.0 so it will use CMP. Getting the data into the right format to perform the CMP takes a few instructions, but the CMP itself isn't so bad. As a note, the ternary statement seems to be compiled into a CMP on both platforms.
     
    Last edited: Feb 16, 2011
  11. Cameron860

    Cameron860

    Joined:
    Jun 1, 2009
    Posts:
    764
    I've never really been 100% sure why conditionals are so slow though.

    I assume it has something to do with branches in execution throwing a spanner in the works of a GPUs ability to process things in parallel. Like, keeping everything nice and linear with a fixed set of instructions means is can process a whole bunch of fragments at the same time but if the code branches differently for each pixel then it just all gets messed up and slows down. I could be way off there, would welcome any insight anyone else has - I just remember reading that conditionals and shaders are not mixey things.
     
  12. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,087
    PS2.0 does not support support Flow Control / Prediction in the pixel shader (or more specifically is not required too) which is what you are getting at there Cameron (Essentially dynamic branching).

    This is from Real Time Rendering 3'nd Edition (if you are into graphics you should buy this book):

    The reason you want to avoid standard if's ect on PS2.0 is that on some hardware the CMP function has a non optimal performance characteristic. The shader you had provided is not 'bad' at all. All the conditionals were optimized to predicates so there was no dynamic branching. In fact I'm not sure off the top of my head what the minimal shader that would dynamic branch is.

    Here is a good resource on dynamic branching:
    http://developer.amd.com/media/gpu_assets/04 Clever Shader Tricks.pdf
     
  13. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,087
    A further note, because unity compiles Opengl shaders down to ARB shaders and there are no branching instructions for ARB. On OpenGL I believe that you don't get any of the SM3.0 niceties you get with PS3.0. Aras said as much here:

    http://forum.unity3d.com/threads/52704-Compiling-for-shader-model-3.0?p=334362&viewfull=1#post334362

    Edit:

    Just did some playing around with D3D9 profile, this will get you dynamic branching... will only compile on d3d and GLES though:

    Code (csharp):
    1.  
    2.         CGPROGRAM
    3.             #pragma vertex vert_img
    4.             #pragma fragment frag
    5.             #pragma fragmentoption ARB_precision_hint_fastest
    6.             #include "UnityCG.cginc"
    7.             #pragma target 3.0
    8.             #pragma only_renderers d3d9
    9.  
    10.             uniform sampler2D _MainTex;
    11.             float4 thermal;
    12.  
    13.             float4 frag (v2f_img i) : COLOR {
    14.                 float4 pixcol = tex2D(_MainTex, i.uv);
    15.                 float4 colors[3];
    16.                 colors[0] = float4(0.0,0.0,1.0,1.0);
    17.                 colors[1] = float4(1.0,1.0,0.0,1.0);
    18.                 colors[2] = float4(1.0,0.0,0.0,1.0);
    19.                 float lum = (pixcol.r+pixcol.g+pixcol.b)/3.;
    20.                 int ix = (lum < 0.5)? 0:1;
    21.                
    22.                 while( thermal.x < 0.5 )
    23.                 {
    24.                     thermal += lerp(colors[0], colors[1], (lum-float(ix)*0.5)/0.5);
    25.                 }
    26.                 return thermal;
    27.             }
    28.         ENDCG
    29.  
    mmm branching instructions:
    loop aL, i0
    break_ge r0.x, c2.x

    It would be nice if Unity allowed for 3.0 marked shaders to compile into GLSL instead of ARB, then we could do dynamic branching, it does this for GLES. It becomes more of a gamble as to whether the shader will run on the hardware though, you would need to fall back to the fallback shader if the GLSL could not be compiled by the video card driver.
     
    Last edited: Feb 16, 2011
  14. Cameron860

    Cameron860

    Joined:
    Jun 1, 2009
    Posts:
    764
    Thanks for taking the time to post that Stramit, makes a lot more sense now. I might have to grab a copy of that book. :)
     
  15. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,354
    I second the recommendation. It's one of the best textbooks I've come across in any field.
     
  16. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    Soooo, the first posts code is optimal?
     
  17. rahuxx

    rahuxx

    Joined:
    May 8, 2009
    Posts:
    533
    Need to remove this code on code owner's request.


    rahu
     
    Last edited: Jun 27, 2011
  18. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,588
    Unity pro comes with various image effects and there is a script called imageeffectbase.cs in that package. You need that one imported.