Search Unity

  1. Check out our Unite Austin 2017 YouTube playlist to catch up on what you missed. More videos coming soon.
    Dismiss Notice
  2. Unity 2017.2 is now released.
    Dismiss Notice
  3. The Unity Gear Store is here to help you look great at your next meetup, user group or conference. With all new Unity apparel, stickers and more!
    Dismiss Notice
  4. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice
  6. Unity 2017.3 beta is now available for download.
    Dismiss Notice

sobel operator - height to normal map on GPU

Discussion in 'Shaders' started by apple_motion, Oct 30, 2009.

  1. apple_motion

    apple_motion

    Joined:
    Jul 2, 2009
    Posts:
    169
    For some reason (mostly lazy), I don't want to make the normal map on the editor. so that, I made it on runtime :) That is based on the Sobel operator

    [​IMG]

    sobel operation...
    Code (csharp):
    1. float3 height2normal_sobel(float3x3 c)
    2. {      
    3.     float3x3 x = float3x3(   1.0, 0.0, -1.0,
    4.                                     2.0, 0.0, -2.0,
    5.                                     1.0, 0.0, -1.0  );
    6.  
    7.     float3x3 y = float3x3(   1.0,  2.0,  1.0,
    8.                                     0.0,  0.0,  0.0,
    9.                                    -1.0, -2.0, -1.0 );
    10.    
    11.     x = x * c;
    12.     y = y * c;
    13.  
    14.     float cx =  x[0][0] +x[0][2]
    15.                    +x[1][0] +x[1][2]
    16.                    +x[2][0] +x[2][2];
    17.    
    18.     float cy =  y[0][0] +y[0][1] +y[0][2]
    19.                   +y[2][0] +y[2][1] +y[2][2];
    20.                
    21.     float cz =  sqrt(1-(cx*cx+cy*cy));
    22.    
    23.     return float3(cx, cy, cz);
    24. }
    ( Edit: almost forget the float3x3 could do multiply directly :p)

    texture read in...
    Code (csharp):
    1. float3x3 img3x3(sampler2D color_map, float2 tc, float ts, int ch)
    2. {
    3.     float   d = 1.0/ts; // ts, texture sampling size
    4.     float3x3 c;    
    5.     c[0][0] = tex2D(color_map,tc + float2(-d,-d))[ch];
    6.     c[0][1] = tex2D(color_map,tc + float2( 0,-d))[ch];
    7.     c[0][2] = tex2D(color_map,tc + float2( d,-d))[ch]
    8.        
    9.     c[1][0] = tex2D(color_map,tc + float2(-d, 0))[ch];
    10.     c[1][1] = tex2D(color_map,tc                )[ch];
    11.     c[1][2] = tex2D(color_map,tc + float2( d, 0))[ch];
    12.        
    13.     c[2][0] = tex2D(color_map,tc + float2(-d, d))[ch];
    14.     c[2][1] = tex2D(color_map,tc + float2( 0, d))[ch];
    15.     c[2][2] = tex2D(color_map,tc + float2( d, d))[ch];
    16.    
    17.     return c;
    18. }
    19.  
    how to use ...
    Code (csharp):
    1. float3x3 c = img3x3(color_map, IN.texcoord, texture_size, 0 );// red only
    2. float3 normal = height2normal_sobel(c);
    3. normal = normalize(float3(normal.xy, normal.z *bump_level));
    Hope that is useful for someone like me (lazy :p)
     
  2. urgrund

    urgrund

    Joined:
    Jul 14, 2009
    Posts:
    201
    good one - this sort of thing could be very useful for web deployment, if all you wanted was some noisy normalmaps (well, you could make it generate stuff like crazybump does) then this would save having to upload (and having to consider compressing) normalmaps!
    good work :)