diff options
Diffstat (limited to 'core/image.cpp')
-rw-r--r-- | core/image.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/core/image.cpp b/core/image.cpp index 07e705265d..c6d1c07332 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -2271,6 +2271,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha); ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear); ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy); + ClassDB::bind_method(D_METHOD("bumpmap_to_normalmap","bump_scale"), &Image::bumpmap_to_normalmap, DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("blit_rect", "src", "src_rect", "dst"), &Image::blit_rect); ClassDB::bind_method(D_METHOD("blit_rect_mask", "src", "mask", "src_rect", "dst"), &Image::blit_rect_mask); @@ -2379,6 +2380,47 @@ void Image::normalmap_to_xy() { convert(Image::FORMAT_LA8); } +void Image::bumpmap_to_normalmap(float bump_scale) { + ERR_FAIL_COND(!_can_modify(format)); + convert(Image::FORMAT_RF); + + PoolVector<uint8_t> result_image; //rgba output + result_image.resize(width * height* 4); + + { + PoolVector<uint8_t>::Read rp = data.read(); + PoolVector<uint8_t>::Write wp = result_image.write(); + + unsigned char *write_ptr = wp.ptr(); + float *read_ptr = (float*) rp.ptr(); + + for (int ty = 0; ty < height; ty++) { + int py = ty+1; + if (py >= height) py-=height; + + for (int tx = 0; tx < width; tx++) { + int px=tx+1; + if (px >= width) px-=width; + float here = read_ptr[ty*width + tx]; + float to_right= read_ptr[ty*width + px]; + float above= read_ptr[py*width + tx]; + Vector3 up = Vector3(0,1,(here-above)*bump_scale); + Vector3 across = Vector3(1,0,(to_right-here)*bump_scale); + + Vector3 normal = across.cross(up); + normal.normalize(); + + write_ptr[ ((ty*width + tx) <<2) +0 ]= (128.0 + normal.x * 127.0); + write_ptr[ ((ty*width + tx) <<2) +1 ]= (128.0 + normal.y * 127.0); + write_ptr[ ((ty*width + tx) <<2) +2 ]= (128.0 + normal.z * 127.0); + write_ptr[ ((ty*width + tx) <<2) +3 ]= 255; + } + } + } + format=FORMAT_RGBA8; + data=result_image; +} + void Image::srgb_to_linear() { if (data.size() == 0) |