diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md index 7ae1f754d..001e93401 100644 --- a/Content/Documentation/ScriptingAPI-Documentation.md +++ b/Content/Documentation/ScriptingAPI-Documentation.md @@ -440,6 +440,14 @@ Just holds texture information in VRAM. int perlin_seed = 1234, int perlin_octaves = 8, float perlin_persistence = 0.5) -- creates a gradient texture from parameters +- CreateLensDistortionNormalMap( + int width = 256, + int height = 256, + Vector uv_start = Vecctor(0.5, 0.5), + float radius = 0.5, + float squish = 1, + float blend = 1, + float edge_smoothness = 0.04) -- creates a lens distortion normal map (16-bit precision) - Save(string filename) -- saves texture into a file. Provide the extension in the filename, it should be one of the following: .JPG, .PNG, .TGA, .BMP, .DDS, .KTX2, .BASIS ```lua diff --git a/WickedEngine/wiHelper.cpp b/WickedEngine/wiHelper.cpp index f051a7bee..9f3ed8162 100644 --- a/WickedEngine/wiHelper.cpp +++ b/WickedEngine/wiHelper.cpp @@ -430,6 +430,26 @@ namespace wi::helper unsigned error = lodepng::encode(filedata, src_bigendian, desc.width, desc.height, LCT_GREY, 16); return error == 0; } + if (desc.format == Format::R16G16_UNORM || desc.format == Format::R16G16_UINT) + { + // Specialized handling for 16-bit PNG: + // Two channel RG data is expanded to RGBA (2-channel PNG is not good because that is interpreted as red and alpha) + wi::vector src_bigendian = texturedata; + const uint32_t* src_rg = (const uint32_t*)src_bigendian.data(); + wi::vector dest_rgba(desc.width * desc.height); + for (uint32_t i = 0; i < desc.width * desc.height; ++i) + { + uint32_t rg = src_rg[i]; + wi::Color16& rgba = dest_rgba[i]; + uint16_t r = rg & 0xFFFF; + r = (r >> 8) | ((r & 0xFF) << 8); // little endian to big endian + uint16_t g = (rg >> 16u) & 0xFFFF; + g = (g >> 8) | ((g & 0xFF) << 8); // little endian to big endian + rgba = wi::Color16(r, g, 0xFFFF, 0xFFFF); + } + unsigned error = lodepng::encode(filedata, (const unsigned char*)dest_rgba.data(), desc.width, desc.height, LCT_RGBA, 16); + return error == 0; + } if (desc.format == Format::R16G16B16A16_UNORM || desc.format == Format::R16G16B16A16_UINT) { // Specialized handling for 16-bit PNG: diff --git a/WickedEngine/wiTextureHelper.cpp b/WickedEngine/wiTextureHelper.cpp index f80cb4beb..133fa9026 100644 --- a/WickedEngine/wiTextureHelper.cpp +++ b/WickedEngine/wiTextureHelper.cpp @@ -480,7 +480,7 @@ namespace wi::texturehelper float scale = 1.0f / (radius * 2); float edge = 1.0f - edge_smoothness; - wi::vector data(width * height); + wi::vector data(width * height); for (uint32_t y = 0; y < height; ++y) { for (uint32_t x = 0; x < width; ++x) @@ -502,17 +502,16 @@ namespace wi::texturehelper uv.x = uv.x * dp; uv.y = uv.y * dp; - XMFLOAT4 color = XMFLOAT4(uv.x * 0.5f + 0.5f, uv.y * 0.5f + 0.5f, 1, 1); + XMFLOAT2 color = XMFLOAT2(uv.x * 0.5f + 0.5f, uv.y * 0.5f + 0.5f); float s = smoothstep(1.0f, edge, d) * blend; color.x = lerp(0.5f, color.x, s); color.y = lerp(0.5f, color.y, s); - color.z = lerp(1.0f, color.z, s); - data[x + y * width] = wi::Color16::fromFloat4(color); + data[x + y * width] = (uint32_t(color.x * 65535) & 0xFFFF) | (uint32_t(color.y * 65535) & 0xFFFF) << 16u; } } Texture texture; - CreateTexture(texture, data.data(), width, height, Format::R16G16B16A16_UNORM); + CreateTexture(texture, data.data(), width, height, Format::R16G16_UNORM); return texture; } diff --git a/WickedEngine/wiTexture_BindLua.cpp b/WickedEngine/wiTexture_BindLua.cpp index 1440e70f3..244f06ce5 100644 --- a/WickedEngine/wiTexture_BindLua.cpp +++ b/WickedEngine/wiTexture_BindLua.cpp @@ -11,6 +11,7 @@ namespace wi::lua Luna::FunctionType Texture_BindLua::methods[] = { lunamethod(Texture_BindLua, GetLogo), lunamethod(Texture_BindLua, CreateGradientTexture), + lunamethod(Texture_BindLua, CreateLensDistortionNormalMap), lunamethod(Texture_BindLua, Save), { NULL, NULL } }; @@ -121,6 +122,66 @@ namespace wi::lua Luna::push(L, texture); return 1; } + int Texture_BindLua::CreateLensDistortionNormalMap(lua_State* L) + { + uint32_t width = 256; + uint32_t height = 256; + XMFLOAT2 uv_start = XMFLOAT2(0.5f, 0.5f); + float radius = 0.5f; + float squish = 1; + float blend = 1; + float edge_smoothness = 0.04f; + + int argc = wi::lua::SGetArgCount(L); + if (argc > 0) + { + width = (uint32_t)wi::lua::SGetInt(L, 1); + if (argc > 1) + { + height = (uint32_t)wi::lua::SGetInt(L, 2); + if (argc > 2) + { + Vector_BindLua* v1 = Luna::lightcheck(L, 3); + if (v1) + { + uv_start = v1->GetFloat2(); + } + else + { + wi::lua::SError(L, "CreateLensDistortionNormalMap() uv_start argument is not a vector!"); + } + + if (argc > 3) + { + radius = wi::lua::SGetFloat(L, 4); + if (argc > 4) + { + squish = wi::lua::SGetFloat(L, 5); + if (argc > 5) + { + blend = wi::lua::SGetFloat(L, 6); + if (argc > 6) + { + edge_smoothness = wi::lua::SGetFloat(L, 7); + } + } + } + } + } + } + } + + wi::graphics::Texture texture = wi::texturehelper::CreateLensDistortionNormalMap( + width, height, + uv_start, + radius, + squish, + blend, + edge_smoothness + ); + Luna::push(L, texture); + return 1; + } int Texture_BindLua::Save(lua_State* L) { if (wi::lua::SGetArgCount(L) == 0) diff --git a/WickedEngine/wiTexture_BindLua.h b/WickedEngine/wiTexture_BindLua.h index 8a97923f3..1420d4159 100644 --- a/WickedEngine/wiTexture_BindLua.h +++ b/WickedEngine/wiTexture_BindLua.h @@ -23,6 +23,7 @@ namespace wi::lua int GetLogo(lua_State* L); int CreateGradientTexture(lua_State* L); + int CreateLensDistortionNormalMap(lua_State* L); int Save(lua_State* L); static void Bind(); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 2cbf373c5..e99301bf9 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 485; + const int revision = 486; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);