medfall

A super great game engine
Log | Files | Refs

commit 1a7f735de69ab7a15c8882be01da6e3fcb257e51
parent 6534f3bef1dbee2a6f00f12cb9783d6ff3dadf8c
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Sat,  4 Nov 2017 14:40:18 +0200

Sobel filter normalmap in pp2

Diffstat:
pp2.cc | 71++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 48 insertions(+), 23 deletions(-)

diff --git a/pp2.cc b/pp2.cc @@ -58,32 +58,57 @@ static void compute_horizons( } } +static v3 simple_normal( const array2d< u16 > heightmap, size_t x, size_t y ) { + size_t x_plus_one = x + 1; + size_t x_minus_one = x - 1; + size_t y_plus_one = y + 1; + size_t y_minus_one = y - 1; + + if( x == 0 ) x_minus_one = x; + if( x == heightmap.w - 1 ) x_plus_one = x; + if( y == 0 ) y_minus_one = y; + if( y == heightmap.h - 1 ) y_plus_one = y; + + v3 tangent( + checked_cast< float >( x_plus_one - x_minus_one ), + 0, + heightmap( x_plus_one, y ) / 256.0f - heightmap( x_minus_one, y ) / 256.0f ); + v3 bitangent( + 0, + checked_cast< float >( y_plus_one - y_minus_one ), + heightmap( x, y_plus_one ) / 256.0f - heightmap( x, y_minus_one ) / 256.0f ); + + return normalize( cross( tangent, bitangent ) ); +} + +static v3 compute_normal( const array2d< u16 > heightmap, size_t x, size_t y ) { + if( x == 0 || x == heightmap.w - 1 || y == 0 || y == heightmap.h - 1 ) { + return simple_normal( heightmap, x, y ); + } + + float mm = heightmap( x - 1, y - 1 ) / 256.0f; + float me = heightmap( x - 1, y + 0 ) / 256.0f; + float mp = heightmap( x - 1, y + 1 ) / 256.0f; + float em = heightmap( x + 0, y - 1 ) / 256.0f; + // float ee = heightmap( x + 0, y + 0 ) / 256.0f; + float ep = heightmap( x + 0, y + 1 ) / 256.0f; + float pm = heightmap( x + 1, y - 1 ) / 256.0f; + float pe = heightmap( x + 1, y + 0 ) / 256.0f; + float pp = heightmap( x + 1, y + 1 ) / 256.0f; + + float grad_y = -( mm + 2.0f * em + pm - ( mp + 2.0f * ep + pp ) ) / 8.0f; + float grad_x = -( mm + 2.0f * me + mp - ( pm + 2.0f * pe + pp ) ) / 8.0f; + + v3 tangent = v3( 1, 0, grad_x ); + v3 bitangent = v3( 0, 1, grad_y ); + + return normalize( cross( tangent, bitangent ) ); +} + static void compute_normals( const array2d< u16 > heightmap, array2d< v3 > normals ) { - // TODO: sobel operator? - // estimate the gradient at each point by doing central differences on - // each axis, then cross the tangent and bitangent to find the normal for( size_t y = 0; y < heightmap.h; y++ ) { for( size_t x = 0; x < heightmap.w; x++ ) { - size_t x_plus_one = x + 1; - size_t x_minus_one = x - 1; - size_t y_plus_one = y + 1; - size_t y_minus_one = y - 1; - - if( x == 0 ) x_minus_one = x; - if( x == heightmap.w - 1 ) x_plus_one = x; - if( y == 0 ) y_minus_one = y; - if( y == heightmap.h - 1 ) y_plus_one = y; - - v3 tangent( - checked_cast< float >( x_plus_one - x_minus_one ), - 0, - heightmap( x_plus_one, y ) / 256.0f - heightmap( x_minus_one, y ) / 256.0f ); - v3 bitangent( - 0, - checked_cast< float >( y_plus_one - y_minus_one ), - heightmap( x, y_plus_one ) / 256.0f - heightmap( x, y_minus_one ) / 256.0f ); - - normals( x, y ) = normalize( cross( tangent, bitangent ) ); + normals( x, y ) = compute_normal( heightmap, x, y ); } } }