diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-03-20 01:53:34 +1100 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-03-20 01:53:34 +1100 |
commit | 6d76a11e256cd96c9cdd7ae5a10c0276e6347277 (patch) | |
tree | d52459889408115d1e0eb657a05dc58e098e50eb /source/base/StarCellularLightArray.hpp | |
parent | 58a346e563df12af9194c198c7ffe974411abb28 (diff) |
experiment: unclamped lighting
Diffstat (limited to 'source/base/StarCellularLightArray.hpp')
-rw-r--r-- | source/base/StarCellularLightArray.hpp | 72 |
1 files changed, 10 insertions, 62 deletions
diff --git a/source/base/StarCellularLightArray.hpp b/source/base/StarCellularLightArray.hpp index d73cacf..225d42b 100644 --- a/source/base/StarCellularLightArray.hpp +++ b/source/base/StarCellularLightArray.hpp @@ -11,6 +11,7 @@ struct ScalarLightTraits { static float spread(float source, float dest, float drop); static float subtract(float value, float drop); + static float multiply(float v1, float v2); static float maxIntensity(float value); static float minIntensity(float value); @@ -26,6 +27,7 @@ struct ColoredLightTraits { static Vec3F spread(Vec3F const& source, Vec3F const& dest, float drop); static Vec3F subtract(Vec3F value, float drop); + static Vec3F multiply(Vec3F value, float drop); static float maxIntensity(Vec3F const& value); static float minIntensity(Vec3F const& value); @@ -139,6 +141,10 @@ inline float ScalarLightTraits::subtract(float c, float drop) { return std::max(c - drop, 0.0f); } +inline float ScalarLightTraits::multiply(float v1, float v2) { + return v1 * v2; +} + inline float ScalarLightTraits::maxIntensity(float value) { return value; } @@ -179,6 +185,10 @@ inline Vec3F ColoredLightTraits::subtract(Vec3F c, float drop) { return c; } +inline Vec3F ColoredLightTraits::multiply(Vec3F c, float drop) { + return c * drop; +} + inline float ColoredLightTraits::maxIntensity(Vec3F const& value) { return value.max(); } @@ -388,68 +398,6 @@ void CellularLightArray<LightTraits>::calculateLightSpread(size_t xMin, size_t y } template <typename LightTraits> -void CellularLightArray<LightTraits>::calculatePointLighting(size_t xmin, size_t ymin, size_t xmax, size_t ymax) { - float perBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; - float perBlockAirAttenuation = 1.0f / m_pointMaxAir; - - for (PointLight light : m_pointLights) { - if (light.position[0] < 0 || light.position[0] > m_width - 1 || light.position[1] < 0 || light.position[1] > m_height - 1) - continue; - - float maxIntensity = LightTraits::maxIntensity(light.value); - Vec2F beamDirection = Vec2F(1, 0).rotate(light.beamAngle); - - float maxRange = maxIntensity * m_pointMaxAir; - // The min / max considering the radius of the light - size_t lxmin = std::floor(std::max<float>(xmin, light.position[0] - maxRange)); - size_t lymin = std::floor(std::max<float>(ymin, light.position[1] - maxRange)); - size_t lxmax = std::ceil(std::min<float>(xmax, light.position[0] + maxRange)); - size_t lymax = std::ceil(std::min<float>(ymax, light.position[1] + maxRange)); - - for (size_t x = lxmin; x < lxmax; ++x) { - for (size_t y = lymin; y < lymax; ++y) { - LightValue lvalue = getLight(x, y); - // + 0.5f to correct block position to center - Vec2F blockPos = Vec2F(x + 0.5f, y + 0.5f); - - Vec2F relativeLightPosition = blockPos - light.position; - float distance = relativeLightPosition.magnitude(); - if (distance == 0.0f) { - setLight(x, y, LightTraits::max(light.value, lvalue)); - continue; - } - - float attenuation = distance * perBlockAirAttenuation; - if (attenuation >= 1.0f) - continue; - - Vec2F direction = relativeLightPosition / distance; - if (light.beam > 0.0f) { - attenuation += (1.0f - light.beamAmbience) * clamp(light.beam * (1.0f - direction * beamDirection), 0.0f, 1.0f); - if (attenuation >= 1.0f) - continue; - } - - float remainingAttenuation = maxIntensity - LightTraits::minIntensity(lvalue) - attenuation; - if (remainingAttenuation <= 0.0f) - continue; - - // Need to circularize manhattan attenuation here - float circularizedPerBlockObstacleAttenuation = perBlockObstacleAttenuation / max(fabs(direction[0]), fabs(direction[1])); - float blockAttenuation = lineAttenuation(blockPos, light.position, circularizedPerBlockObstacleAttenuation, remainingAttenuation); - - // Apply single obstacle boost (determine single obstacle by one - // block unit of attenuation). - attenuation += blockAttenuation + min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; - - if (attenuation < 1.0f) - setLight(x, y, LightTraits::max(LightTraits::subtract(light.value, attenuation), lvalue)); - } - } - } -} - -template <typename LightTraits> float CellularLightArray<LightTraits>::lineAttenuation(Vec2F const& start, Vec2F const& end, float perObstacleAttenuation, float maxAttenuation) { // Run Xiaolin Wu's line algorithm from start to end, summing over colliding |