1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. We want to know how you learned Unity! Help us by taking this quick survey and have a chance at a $25 gift card
    Dismiss Notice
  5. Unity 5.6 is now released.
    Dismiss Notice
  6. Check out all the fixes for 5.6 on the patch releases 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

    [​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 :)