commit 9ca5e450d66a8c3e22bbf6a3c5084bbeea9682fe parent 8ddb8f37ce2c412212502031a87497ad9dd306d4 Author: Michael Savage <mikejsavage@gmail.com> Date: Wed Oct 26 19:59:56 +0300 Simpler normalmap generation Diffstat:
pp.cc | | | 89 | +++++++++++++------------------------------------------------------------------ |
diff --git a/pp.cc b/pp.cc @@ -63,84 +63,23 @@ static void compute_horizons( } } -// CCW winding points towards the camera -static v3 triangle_normal_ccw( v3 a, v3 b, v3 c ) { - return normalize( cross( b - a, c - a ) ); -} - -static v3 normal_at_point( const array2d< u8 > heightmap, size_t x, size_t y ) { - v3 bent_normal = v3( 0 ); - - /* - * A vertex looks like this: - * - * +y - * \ 6 | - * \ | - * 5 \ | 1 - * \| - * ------X------ +x - * |\ - * 2 | \ 4 - * | \ - * | 3 \ - * - * We consider up to six triangles for the bent normal - */ - -#define P( x, y ) v3( x, y, heightmap( x, y ) ) - if( x > 0 ) { - if( y > 0 ) { // bottom left - v3 tri2a = P( x, y ); - v3 tri2b = P( x - 1, y ); - v3 tri2c = P( x, y - 1 ); - - bent_normal += triangle_normal_ccw( tri2a, tri2b, tri2c ); - } - if( y < heightmap.h - 1 ) { // top left - v3 tri5a = P( x, y ); - v3 tri5b = P( x - 1, y + 1 ); - v3 tri5c = P( x - 1, y ); - - v3 tri6a = P( x, y ); - v3 tri6b = P( x, y + 1 ); - v3 tri6c = P( x - 1, y + 1 ); - - bent_normal += triangle_normal_ccw( tri5a, tri5b, tri5c ); - bent_normal += triangle_normal_ccw( tri6a, tri6b, tri6c ); - } - } - - if( x < heightmap.w - 1 ) { - if( y > 0 ) { // bottom right - v3 tri3a = P( x, y ); - v3 tri3b = P( x, y - 1 ); - v3 tri3c = P( x + 1, y - 1 ); - - v3 tri4a = P( x, y ); - v3 tri4b = P( x + 1, y - 1 ); - v3 tri4c = P( x + 1, y ); - - bent_normal += triangle_normal_ccw( tri3a, tri3b, tri3c ); - bent_normal += triangle_normal_ccw( tri4a, tri4b, tri4c ); - } - if( y < heightmap.h - 1 ) { // top right - v3 tri1a = P( x, y ); - v3 tri1b = P( x + 1, y ); - v3 tri1c = P( x, y + 1 ); - - bent_normal += triangle_normal_ccw( tri1a, tri1b, tri1c ); - } - } -#undef P - - return normalize( bent_normal ); -} - static void compute_normals( const array2d< u8 > heightmap, array2d< v3 > normals ) { for( size_t y = 0; y < heightmap.h; y++ ) { for( size_t x = 0; x < heightmap.w; x++ ) { - normals( x, y ) = normal_at_point( heightmap, x, y ); + float x_plus_one = x + 1; + float x_minus_one = x - 1; + float y_plus_one = y + 1; + float 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( x_plus_one - x_minus_one, 0, heightmap( x_plus_one, y ) - heightmap( x_minus_one, y ) ); + v3 bitangent( 0, y_plus_one - y_minus_one, heightmap( x, y_plus_one ) - heightmap( x, y_minus_one ) ); + + normals( x, y ) = normalize( cross( tangent, bitangent ) ); } } }