Search Unity

Heat Distortion

Discussion in 'Shaders' started by meh11, May 28, 2010.

  1. meh11

    meh11

    Joined:
    Dec 1, 2009
    Posts:
    15
    .
     

    Attached Files:

    Last edited: Oct 24, 2014
  2. gonza

    gonza

    Joined:
    May 9, 2010
    Posts:
    9
    Cool! Thanks for sharing
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Looks nice :)

    Kind of like the heat refraction shader basing on NM particles from Unite 2008 ... cool :)
     
  4. slgooding

    slgooding

    Joined:
    Jan 12, 2009
    Posts:
    112
    Thanks for sharing! This is great for underwater distortion. Just drop it on a plane in front of the camera and bam! I changed the range to a float for more precision with the strength.
     
  5. ivanmoen

    ivanmoen

    Joined:
    Dec 26, 2008
    Posts:
    102
    Hmm... if I turn of AA the texture gets inverted? Is this a DirectX issue?
     
  6. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Yes, I am that person. The attached image shows what your sample package looks like on my mac with Unity 2.6.1f3 Pro.

    I have no clue what is wrong there, as I explained in the other thread, other GrabPass shaders seem to work fine.
     

    Attached Files:

  7. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Your shader already explicitly defines the queue as transparent+10. However, just to test, I tried a few other values. Interestingly, as soon as I drop into the geometry queue (Geometry,Geometry+1, ..., Geometry+999), the shader starts to partially work. That is, it correctly shows distorted grass in its entire area (with the fire particles rendered (undistorted) on top of it). Other solid geometry, like the walls and the logs are invisible within the spherical area. As soon as the queue hits Geometry+1000 (aka Transparent) it becomes the strange white egg from the picture.

    So I guess the render queue is indeed somehow involved, but I still don't know what is wrong exactly.
     
  8. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    I know, but it happens anyway. Something is quite messed up, but I have no idea what.
     
  9. tonytage

    tonytage

    Joined:
    May 26, 2010
    Posts:
    28
  10. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Yes, refraction / haze are always unity pro only
    You can easily identify this in the initial posting: GrabPass is Pro only
     
  11. Deleted User

    Deleted User

    Guest

    Last edited by a moderator: Aug 7, 2011
  12. fghajhe

    fghajhe

    Joined:
    Jan 6, 2009
    Posts:
    145
    Thanks for sharing meh11.

    I came across this becuase I am looking for some heat distortion for my project.

    For some reason everything is flipped in the distortion except during Deffered render mode. Would you know this could be fixed?

    Thanks for any help!
     
  13. fghajhe

    fghajhe

    Joined:
    Jan 6, 2009
    Posts:
    145
    Thanks for the reply.

    That didn't fix it but no problem.
     
  14. ole

    ole

    Unity programmer

    Joined:
    Sep 30, 2010
    Posts:
    56
    FYI, unity 3.3+ has now a proper builtin function for calculating GrabPass coordinates (handles flipping for windows et al):

    Code (csharp):
    1.  float4 grabPassCoords = ComputeGrabScreenPos(o.pos) // o.pos is projected vertex
     
  15. BIG-BUG

    BIG-BUG

    Joined:
    Mar 29, 2009
    Posts:
    457
    Hi ole!

    Could you show us please, how to use the grabbed texture in screen space on the original position? (like the "render nothing" example)

    I' ve tried the following in a Surface Shader:
    Code (csharp):
    1.  
    2.     float4 sPos = ComputeGrabScreenPos(IN.screenPos); // o.pos is projected vertex
    3.     float2 uv = sPos.xy / sPos.w;
    4.     o.Albedo = tex2D (_GrabTexture, uv).rgb;
    5.  
    In forward rendering the texture is not flipped anymore, however it is not placed correctly either.
    In deferred rendering it is now flipped(and placed elsewhere) where it worked before:
    Code (csharp):
    1.  
    2.     float2 uv = IN.screenPos.xy / IN.screenPos.w;
    3.     o.Albedo = tex2D (_GrabTexture, uv).rgb;
    4.  
    Maybe I'm doing something wrong?

    Thanks!
     
    Last edited: Sep 18, 2011
  16. ole

    ole

    Unity programmer

    Joined:
    Sep 30, 2010
    Posts:
    56
    hello,

    pasting a simplified code derived from our glass shader here that should work in all cases (if not it's a bug) ...

    Code (csharp):
    1.  
    2. struct appdata_t {
    3.     float4 vertex : POSITION;
    4.     float2 texcoord: TEXCOORD0;
    5. };
    6.  
    7. struct v2f {
    8.     float4 vertex : POSITION;
    9.     float4 uvgrab : TEXCOORD0;
    10.     float2 uvbump : TEXCOORD1;
    11. };
    12.  
    13. float4 _BumpMap_ST;
    14.  
    15. v2f vert (appdata_t v)
    16. {
    17.     v2f o;
    18.     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    19.     #if UNITY_UV_STARTS_AT_TOP
    20.     float scale = -1.0;
    21.     #else
    22.     float scale = 1.0;
    23.     #endif
    24.     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    25.     o.uvgrab.zw = o.vertex.zw;
    26.     o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
    27.     return o;
    28. }
    29.  
    30. sampler2D _GrabTexture;
    31. float4 _GrabTexture_TexelSize;
    32. sampler2D _BumpMap;
    33.  
    34. half4 frag( v2f i ) : COLOR
    35. {
    36.     half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg;
    37.     float2 offset = bump * 0.1 * _GrabTexture_TexelSize.xy;
    38.     i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    39.     half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    40.     return col;
    41. }
    42.  
    remember to use GrabPass {} in a pass before this one and then all you'd need to do is add some animation to the bump lookup (and maybe fade out edges etc.) to get heat haze / distortion.
     
  17. ChiuanWei

    ChiuanWei

    Joined:
    Jan 29, 2012
    Posts:
    131
    why i use as your setp...but looks like this ...everything .. reverse....
     
  18. girishgap

    girishgap

    Joined:
    Oct 17, 2011
    Posts:
    10
    But it reduce the frame rate and don't know the exact reason...
     
  19. girishgap

    girishgap

    Joined:
    Oct 17, 2011
    Posts:
    10
    It reduce the frame rate and don't know the exact reason.
     
  20. TwisterK

    TwisterK

    Joined:
    Oct 26, 2010
    Posts:
    110
    Code (csharp):
    1.  
    2.   // check if anti aliasing is used
    3.  
    4.     //if (_ProjectionParams.x < 0)
    5.  
    6.        screenPos.y = 1 - screenPos.y;
    7.  
    Just comment out the checking anti-aliasing part, then it will render correctly, but I not sure what kind impact will this bring if we turn on the AA.

    --TwisterK
     
  21. Denifia

    Denifia

    Joined:
    Nov 16, 2011
    Posts:
    32
    Hi All,

    This looks perfect for a project I am working on but does anyone have a package with the latest version of code? I don't mind piecing it all together from these posts but if someone has a current working version, I'd love to get my hands on it.

    Thanks.
     
  22. Bernardjames

    Bernardjames

    Joined:
    Apr 20, 2012
    Posts:
    2
    What is the range of Heat Distortion temperature of Polysulfone and Polyetherether Ketones(PEEK) ?
     
  23. Apprentice

    Apprentice

    Joined:
    Feb 9, 2012
    Posts:
    74
    The shader doesnt work for, its saying that i cant run subshaders on my graphics card. Im using Unity 3.5 without emulation mode and an nvidia GTX 570
     
  24. Brenden-Frank

    Brenden-Frank

    Joined:
    Aug 5, 2012
    Posts:
    110
    Hey guys, I noticed a small problem when integrating this shader. It will render fog twice causing the distortion object to very obviously stand out.

    This can be fixed by adding:

    Code (csharp):
    1. Fog { Color (0,0,0,0) }
    Here's the full shader:

    Code (csharp):
    1.  
    2. // Upgrade NOTE: replaced 'glstate.matrix.modelview[0]' with 'UNITY_MATRIX_MV'
    3. // Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP'
    4.  
    5. Shader "HeatDistortion" {
    6.  
    7. Properties {
    8.  
    9.     _NoiseTex ("Noise Texture (RG)", 2D) = "white" {}
    10.  
    11.     strength("strength", Range(0.1, 0.3)) = 0.2
    12.  
    13.     transparency("transparency", Range(0.01, 0.1)) = 0.05
    14.  
    15. }
    16.  
    17.  
    18.  
    19. Category {
    20.  
    21.     Tags { "Queue" = "Transparent+10" }
    22.  
    23.     SubShader {
    24.  
    25.         GrabPass {
    26.  
    27.             Name "BASE"
    28.  
    29.             Tags { "LightMode" = "Always" }
    30.  
    31.         }
    32.  
    33.        
    34.  
    35.         Pass {
    36.  
    37.             Name "BASE"
    38.  
    39.             Tags { "LightMode" = "Always" }
    40.            
    41.             Fog { Color (0,0,0,0) }
    42.  
    43.             Lighting Off
    44.  
    45.             Cull Off
    46.  
    47.             ZWrite On
    48.  
    49.             ZTest LEqual
    50.  
    51.             Blend SrcAlpha OneMinusSrcAlpha
    52.  
    53.             AlphaTest Greater 0
    54.          
    55.  
    56. CGPROGRAM
    57. // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members distortion)
    58. #pragma exclude_renderers xbox360
    59.  
    60. #pragma vertex vert
    61.  
    62. #pragma fragment frag
    63.  
    64. #pragma fragmentoption ARB_precision_hint_fastest
    65.  
    66. #pragma fragmentoption ARB_fog_exp2
    67.  
    68. #include "UnityCG.cginc"
    69.  
    70.  
    71.  
    72. sampler2D _GrabTexture : register(s0);
    73.  
    74. float4 _NoiseTex_ST;
    75.  
    76. sampler2D _NoiseTex;
    77.  
    78. float strength;
    79.  
    80. float transparency;
    81.  
    82.  
    83.  
    84. struct data {
    85.  
    86.     float4 vertex : POSITION;
    87.  
    88.     float3 normal : NORMAL;
    89.  
    90.     float4 texcoord : TEXCOORD0;
    91.  
    92. };
    93.  
    94.  
    95.  
    96. struct v2f {
    97.  
    98.     float4 position : POSITION;
    99.  
    100.     float4 screenPos : TEXCOORD0;
    101.  
    102.     float2 uvmain : TEXCOORD2;
    103.  
    104.     float distortion;
    105.  
    106. };
    107.  
    108.  
    109.  
    110. v2f vert(data i){
    111.  
    112.     v2f o;
    113.  
    114.     o.position = mul(UNITY_MATRIX_MVP, i.vertex);      // compute transformed vertex position
    115.  
    116.     o.uvmain = TRANSFORM_TEX(i.texcoord, _NoiseTex);   // compute the texcoords of the noise
    117.  
    118.     float viewAngle = dot(normalize(ObjSpaceViewDir(i.vertex)),
    119.  
    120.                          i.normal);
    121.  
    122.     o.distortion = viewAngle * viewAngle;   // square viewAngle to make the effect fall off stronger
    123.  
    124.     float depth = -mul( UNITY_MATRIX_MV, i.vertex ).z;  // compute vertex depth
    125.  
    126.     o.distortion /= 1+depth;        // scale effect with vertex depth
    127.  
    128.     o.distortion *= strength;   // multiply with user controlled strength
    129.  
    130.     o.screenPos = o.position;   // pass the position to the pixel shader
    131.  
    132.     return o;
    133.  
    134. }
    135.  
    136.  
    137.  
    138. half4 frag( v2f i ) : COLOR
    139.  
    140. {  
    141.  
    142.     // compute the texture coordinates
    143.  
    144.     float2 screenPos = i.screenPos.xy / i.screenPos.w;   // screenpos ranges from -1 to 1
    145.  
    146.     screenPos.x = (screenPos.x + 1) * 0.5;   // I need 0 to 1
    147.  
    148.     screenPos.y = (screenPos.y + 1) * 0.5;   // I need 0 to 1
    149.  
    150.  
    151.  
    152.     // check if anti aliasing is used
    153.  
    154.     if (_ProjectionParams.x < 0)
    155.  
    156.         screenPos.y = 1 - screenPos.y;
    157.  
    158.    
    159.  
    160.     // get two offset values by looking up the noise texture shifted in different directions
    161.  
    162.     half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz);
    163.  
    164.     half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx);
    165.  
    166.    
    167.  
    168.     // use the r values from the noise texture lookups and combine them for x offset
    169.  
    170.     // use the g values from the noise texture lookups and combine them for y offset
    171.  
    172.     // use minus one to shift the texture back to the center
    173.  
    174.     // scale with distortion amount
    175.  
    176.     screenPos.x += ((offsetColor1.r + offsetColor2.r) - 1) * i.distortion;
    177.  
    178.     screenPos.y += ((offsetColor1.g + offsetColor2.g) - 1) * i.distortion;
    179.  
    180.    
    181.  
    182.     half4 col = tex2D( _GrabTexture, screenPos );
    183.  
    184.     col.a = i.distortion/transparency;
    185.  
    186.     return col;
    187.  
    188. }
    189.  
    190.  
    191.  
    192. ENDCG
    193.  
    194.         }
    195.  
    196.     }
    197.  
    198. }
    199.  
    200.  
    201.  
    202. }
     
  25. Lyker

    Lyker

    Joined:
    Feb 27, 2013
    Posts:
    60
    I know this kind off an old post, but is anyone capable of making this into a 4.0 shader?

    I have no experience with shaders and have no idea how to do this myself. I tried renaming and moving some stuff according to the logic in other 4.0 shaders, but without succes.

    The screenshots I saw in this post look promising.

    Any help would be appreciated. :)
     
  26. chenyong

    chenyong

    Joined:
    Apr 4, 2013
    Posts:
    4
    it's great!!!
     
  27. JonnyHilly

    JonnyHilly

    Joined:
    Sep 4, 2009
    Posts:
    749



    I am trying to use this also on 4.0... looks fine on PC and mac, shader compiles ok for OGL2 emulation.
    but runs super slow on iPad3, just rendering 1/8 of screen area, goes from 30fps down to 7fps,
    shame, as it looks great.
     
    Last edited: Aug 20, 2013
  28. neroziros

    neroziros

    Joined:
    Aug 25, 2012
    Posts:
    129
    Hi! Sorry for resurrecting this post but I need to ask: someone knows how to port this code to a compatible DX11 syntax? I'm getting the following errors when compiling in Directx11 rendering mode:

    Material doesn't have a texture property '_NoiseTex'

    Material doesn't have a texture property '_NoiseTex'

    Material doesn't have a float or range property 'strength'

    Material doesn't have a float or range property 'transparency'

    Thanks in advance for your time
     
  29. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Unity has an issue where the Material inspector complains about missing properties in shaders when the underlying issue is a shader compilation failure. I guess shaders that fail to compile are considered to have no properties, so you get a bunch of extra freaking out in the console.

    Save the shader again, and look for the actual compilation errors. If you can fix those, the Material ones should disappear.
     
  30. neroziros

    neroziros

    Joined:
    Aug 25, 2012
    Posts:
    129
    Thanks for your help! The compilation errors are:

    No subshaders can run on this graphics card
    Program 'vert','vert': function return value missing semantics (compiling for d3d11_9x) at line 15

    I'm running a 560GTX Ti so the first error its a little baffling. Additionally, the compiler its adding these lines to the shader code:

    // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members distortion)
    #pragma exclude_renderers d3d11 xbox360

    Struct v2 its (its the same code posted on this thread):

    struct v2f {
    float4 position : POSITION;
    float4 screenPos : TEXCOORD0;
    float2 uvmain : TEXCOORD2;
    float distortion;
    };

    Any idea of how to solve this?
     
  31. tanoshimi

    tanoshimi

    Joined:
    May 21, 2013
    Posts:
    297
    Well, based on the error description, you could try giving distortion a semantic... how about TEXCOORD3?
     
  32. song liu

    song liu

    Joined:
    Oct 3, 2013
    Posts:
    1
    well done!!!
     
  33. ABerlemont

    ABerlemont

    Joined:
    Sep 27, 2012
    Posts:
    67
    This didn't do anything on my project. The image rendered is still upside down.
    Any ideas ?
     
  34. ABerlemont

    ABerlemont

    Joined:
    Sep 27, 2012
    Posts:
    67
    Ok, got it. You need to keep the line but remove the if statement.

    Code (CSharp):
    1.  
    2. // Upgrade NOTE: replaced 'glstate.matrix.modelview[0]' with 'UNITY_MATRIX_MV'
    3. // Upgrade NOTE: replaced 'glstate.matrix.mvp' with 'UNITY_MATRIX_MVP'
    4.  
    5. Shader "HeatDistortion" {
    6.  
    7.   Properties {
    8.     _NoiseTex ("Noise Texture (RG)", 2D) = "white" {}
    9.     strength("strength", Range(0.1, 0.3)) = 0.2
    10.     transparency("transparency", Range(0.01, 0.1)) = 0.05
    11.   }
    12.  
    13.   Category {
    14.     Tags { "Queue" = "Transparent+10" }
    15.     SubShader {
    16.    
    17.       // http://docs.unity3d.com/Manual/SL-GrabPass.html
    18.       // http://docs.unity3d.com/Manual/SL-PassTags.html
    19.       GrabPass {
    20.         Name "BASE"
    21.         Tags { "LightMode" = "Always" } // no lighting
    22.       }
    23.    
    24.       Pass {
    25.         Name "BASE"
    26.         Tags { "LightMode" = "Always" }
    27.         Fog { Color (0,0,0,0) }
    28.         Lighting Off
    29.         Cull Off
    30.         ZWrite On
    31.         ZTest LEqual
    32.         Blend SrcAlpha OneMinusSrcAlpha
    33.         AlphaTest Greater 0
    34.      
    35.         CGPROGRAM
    36.         // Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members distortion)
    37.         #pragma exclude_renderers d3d11 xbox360
    38.         // Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct v2f members distortion)
    39.         #pragma exclude_renderers xbox360
    40.         #pragma vertex vert
    41.         #pragma fragment frag
    42.         #pragma fragmentoption ARB_precision_hint_fastest
    43.         #pragma fragmentoption ARB_fog_exp2
    44.         #include "UnityCG.cginc"
    45.      
    46.         // http://forum.unity3d.com/threads/what-does-register-s0-do.26816/
    47.         sampler2D _GrabTexture : register(s0);
    48.         float4 _NoiseTex_ST;
    49.         sampler2D _NoiseTex;
    50.         float strength;
    51.         float transparency;
    52.      
    53.         struct data {
    54.           float4 vertex : POSITION;
    55.           float3 normal : NORMAL;
    56.           float4 texcoord : TEXCOORD0;
    57.         };
    58.      
    59.         struct v2f {
    60.           float4 position : POSITION;
    61.           float4 screenPos : TEXCOORD0;
    62.           float2 uvmain : TEXCOORD2;
    63.           float distortion;
    64.         };
    65.      
    66.         v2f vert(data i){
    67.           v2f o;
    68.           o.position = mul(UNITY_MATRIX_MVP, i.vertex);      // compute transformed vertex position
    69.           o.uvmain = TRANSFORM_TEX(i.texcoord, _NoiseTex);   // compute the texcoords of the noise
    70.           float viewAngle = dot(normalize(ObjSpaceViewDir(i.vertex)), i.normal);
    71.           o.distortion = viewAngle * viewAngle;   // square viewAngle to make the effect fall off stronger
    72.           float depth = -mul( UNITY_MATRIX_MV, i.vertex ).z;  // compute vertex depth
    73.           o.distortion /= 1+depth;  // scale effect with vertex depth
    74.           o.distortion *= strength; // multiply with user controlled strength
    75.           o.screenPos = o.position; // pass the position to the pixel shader
    76.           return o;
    77.         }
    78.      
    79.         half4 frag( v2f i ) : COLOR
    80.         {
    81.           // compute the texture coordinates
    82.           float2 screenPos = i.screenPos.xy / i.screenPos.w;   // screenpos ranges from -1 to 1
    83.           screenPos.x = (screenPos.x + 1) * 0.5;   // I need 0 to 1
    84.           screenPos.y = (screenPos.y + 1) * 0.5;   // I need 0 to 1
    85.        
    86.           // check if anti aliasing is used
    87.           //if (_ProjectionParams.x < 0) screenPos.y = 1 - screenPos.y;
    88.           screenPos.y = 1 - screenPos.y;
    89.        
    90.           // get two offset values by looking up the noise texture shifted in different directions
    91.           half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz);
    92.           half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx);
    93.        
    94.           // use the r values from the noise texture lookups and combine them for x offset
    95.           // use the g values from the noise texture lookups and combine them for y offset
    96.           // use minus one to shift the texture back to the center
    97.           // scale with distortion amount
    98.           screenPos.x += ((offsetColor1.r + offsetColor2.r) - 1) * i.distortion;
    99.           screenPos.y += ((offsetColor1.g + offsetColor2.g) - 1) * i.distortion;
    100.           half4 col = tex2D( _GrabTexture, screenPos );
    101.           col.a = i.distortion / transparency;
    102.           return col;
    103.         }
    104.      
    105.         ENDCG
    106.       }
    107.     }
    108.   }
    109. }
     
  35. brummer

    brummer

    Joined:
    Jul 3, 2013
    Posts:
    31
    The shader doesn't seem to work since unity5.
     
  36. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
    Problems on Unity5 like this?

     
  37. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
  38. RChrispy

    RChrispy

    Joined:
    Dec 18, 2013
    Posts:
    71
  39. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    Does this work on ios?