Search Unity

  1. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Let us know a bit about your interests, and if you'd like to become more directly involved. Take our survey!
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    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



    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:
    203
    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 :)