From 17e23e41d4da0fa193f7dd335fd7a821fc5b18b7 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 22 Jun 2024 01:16:15 +0300 Subject: [PATCH] Support specular highlight in vecr lighting colorizer --- libs/vecr/include/psemek/vecr/colorizer.hpp | 3 +++ libs/vecr/source/colorizer.cpp | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libs/vecr/include/psemek/vecr/colorizer.hpp b/libs/vecr/include/psemek/vecr/colorizer.hpp index b3ffb9be..60f3efd4 100644 --- a/libs/vecr/include/psemek/vecr/colorizer.hpp +++ b/libs/vecr/include/psemek/vecr/colorizer.hpp @@ -24,6 +24,9 @@ namespace psemek::vecr any shape = {}; gfx::color_rgba color0 = {0, 0, 0, 0}; gfx::color_rgba color1 = {0, 0, 0, 0}; + gfx::color_rgba specular_color = {0, 0, 0, 0}; + float specular_power = 0.f; + float specular_intensity = 0.f; float slope = 1.f; geom::vector direction = {0.f, 0.f, 1.f}; }; diff --git a/libs/vecr/source/colorizer.cpp b/libs/vecr/source/colorizer.cpp index 48746336..2c4542c6 100644 --- a/libs/vecr/source/colorizer.cpp +++ b/libs/vecr/source/colorizer.cpp @@ -24,10 +24,23 @@ namespace psemek::vecr auto normal = geom::swizzle<0, 1, -1>(real_sample.gradient * lighting.slope); normal[2] = 1.f; + normal = geom::normalized(normal); - auto factor = 0.5f + 0.5f * geom::dot(geom::normalized(normal), lighting.direction); + geom::vector view{0.f, 0.f, 1.f}; - return gfx::lerp(gfx::to_colorf(lighting.color0), gfx::to_colorf(lighting.color1), factor); + auto reflected = 2.f * geom::dot(normal, lighting.direction) * normal - lighting.direction; + + auto NdotL = geom::dot(normal, lighting.direction); + auto RdotV = geom::dot(reflected, view); + + auto lightness = 0.5f + 0.5f * NdotL; + + auto specular = lighting.specular_intensity * std::pow(std::max(0.f, RdotV), lighting.specular_power); + + auto result = gfx::lerp(gfx::to_colorf(lighting.color0), gfx::to_colorf(lighting.color1), lightness); + result = gfx::lerp(result, gfx::to_colorf(lighting.specular_color), specular); + + return result; } }