diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-03-26 07:31:33 +1100 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2024-03-26 07:31:33 +1100 |
commit | c484fab32dcac655164f082805d1d55d1d058f2f (patch) | |
tree | 9eeabdaee723a88bbebdd77d41d1bb93ee3def83 /source/base | |
parent | 77d7f8eb81af21dd231f6384951fc2c14c149d5c (diff) |
experiment: auto-conversion of object spread lights to hybrid spread/point lights
Diffstat (limited to 'source/base')
-rw-r--r-- | source/base/StarCellularLightArray.cpp | 53 | ||||
-rw-r--r-- | source/base/StarCellularLightArray.hpp | 1 | ||||
-rw-r--r-- | source/base/StarCellularLighting.cpp | 6 | ||||
-rw-r--r-- | source/base/StarCellularLighting.hpp | 2 |
4 files changed, 43 insertions, 19 deletions
diff --git a/source/base/StarCellularLightArray.cpp b/source/base/StarCellularLightArray.cpp index 60a6d95..99490ce 100644 --- a/source/base/StarCellularLightArray.cpp +++ b/source/base/StarCellularLightArray.cpp @@ -1,12 +1,13 @@ #include "StarCellularLightArray.hpp" +#include "StarInterpolation.hpp" // just specializing these in a cpp file so I can iterate on them without recompiling like 40 files!! namespace Star { template <> void CellularLightArray<ScalarLightTraits>::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; + float pointPerBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; + float pointPerBlockAirAttenuation = 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) @@ -14,8 +15,10 @@ void CellularLightArray<ScalarLightTraits>::calculatePointLighting(size_t xmin, float maxIntensity = ScalarLightTraits::maxIntensity(light.value); Vec2F beamDirection = Vec2F(1, 0).rotate(light.beamAngle); + float perBlockObstacleAttenuation = light.asSpread ? 1.0f / m_spreadMaxObstacle : pointPerBlockObstacleAttenuation; + float perBlockAirAttenuation = light.asSpread ? 1.0f / m_spreadMaxAir : pointPerBlockAirAttenuation; - float maxRange = maxIntensity * m_pointMaxAir; + float maxRange = maxIntensity * (light.asSpread ? m_spreadMaxAir : 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)); @@ -40,7 +43,7 @@ void CellularLightArray<ScalarLightTraits>::calculatePointLighting(size_t xmin, continue; Vec2F direction = relativeLightPosition / distance; - if (light.beam > 0.0f) { + if (light.beam > 0.0001f) { attenuation += (1.0f - light.beamAmbience) * clamp(light.beam * (1.0f - direction * beamDirection), 0.0f, 1.0f); if (attenuation >= 1.0f) continue; @@ -54,12 +57,21 @@ void CellularLightArray<ScalarLightTraits>::calculatePointLighting(size_t xmin, float circularizedPerBlockObstacleAttenuation = perBlockObstacleAttenuation / max(fabs(direction[0]), fabs(direction[1])); float blockAttenuation = lineAttenuation(blockPos, light.position, circularizedPerBlockObstacleAttenuation, remainingAttenuation); + attenuation += blockAttenuation; // 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, lvalue + ScalarLightTraits::subtract(light.value, attenuation)); + if (!light.asSpread) + attenuation += min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; + + if (attenuation < 1.0f) { + auto newLight = ScalarLightTraits::subtract(light.value, attenuation); + if (ScalarLightTraits::maxIntensity(newLight) > 0.0001f) { + if (light.asSpread) + setLight(x, y, lvalue + newLight * 0.25f); + else + setLight(x, y, lvalue + newLight); + } + } } } } @@ -67,8 +79,8 @@ void CellularLightArray<ScalarLightTraits>::calculatePointLighting(size_t xmin, template <> void CellularLightArray<ColoredLightTraits>::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; + float pointPerBlockObstacleAttenuation = 1.0f / m_pointMaxObstacle; + float pointPerBlockAirAttenuation = 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) @@ -76,8 +88,10 @@ void CellularLightArray<ColoredLightTraits>::calculatePointLighting(size_t xmin, float maxIntensity = ColoredLightTraits::maxIntensity(light.value); Vec2F beamDirection = Vec2F(1, 0).rotate(light.beamAngle); + float perBlockObstacleAttenuation = light.asSpread ? 1.0f / m_spreadMaxObstacle : pointPerBlockObstacleAttenuation; + float perBlockAirAttenuation = light.asSpread ? 1.0f / m_spreadMaxAir : pointPerBlockAirAttenuation; - float maxRange = maxIntensity * m_pointMaxAir; + float maxRange = maxIntensity * (light.asSpread ? m_spreadMaxAir : 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)); @@ -116,12 +130,21 @@ void CellularLightArray<ColoredLightTraits>::calculatePointLighting(size_t xmin, float circularizedPerBlockObstacleAttenuation = perBlockObstacleAttenuation / max(fabs(direction[0]), fabs(direction[1])); float blockAttenuation = lineAttenuation(blockPos, light.position, circularizedPerBlockObstacleAttenuation, remainingAttenuation); + attenuation += blockAttenuation; // 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, lvalue + ColoredLightTraits::subtract(light.value, attenuation)); + if (!light.asSpread) + attenuation += min(blockAttenuation, circularizedPerBlockObstacleAttenuation) * m_pointObstacleBoost; + + if (attenuation < 1.0f) { + auto newLight = ColoredLightTraits::subtract(light.value, attenuation); + if (ColoredLightTraits::maxIntensity(newLight) > 0.0001f) { + if (light.asSpread) + setLight(x, y, lvalue + newLight * 0.25f); + else + setLight(x, y, lvalue + newLight); + } + } } } } diff --git a/source/base/StarCellularLightArray.hpp b/source/base/StarCellularLightArray.hpp index 225d42b..587ae1f 100644 --- a/source/base/StarCellularLightArray.hpp +++ b/source/base/StarCellularLightArray.hpp @@ -56,6 +56,7 @@ public: float beam; float beamAngle; float beamAmbience; + bool asSpread; }; void setParameters(unsigned spreadPasses, float spreadMaxAir, float spreadMaxObstacle, diff --git a/source/base/StarCellularLighting.cpp b/source/base/StarCellularLighting.cpp index 579f48a..3e5cf9a 100644 --- a/source/base/StarCellularLighting.cpp +++ b/source/base/StarCellularLighting.cpp @@ -109,12 +109,12 @@ void CellularLightingCalculator::addSpreadLight(Vec2F const& position, Vec3F con m_lightArray.left().addSpreadLight({arrayPosition, light}); } -void CellularLightingCalculator::addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience) { +void CellularLightingCalculator::addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience, bool asSpread) { Vec2F arrayPosition = position - Vec2F(m_calculationRegion.min()); if (m_monochrome) - m_lightArray.right().addPointLight({arrayPosition, light.max(), beam, beamAngle, beamAmbience}); + m_lightArray.right().addPointLight({arrayPosition, light.max(), beam, beamAngle, beamAmbience, asSpread}); else - m_lightArray.left().addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience}); + m_lightArray.left().addPointLight({arrayPosition, light, beam, beamAngle, beamAmbience, asSpread}); } void CellularLightingCalculator::calculate(Image& output) { diff --git a/source/base/StarCellularLighting.hpp b/source/base/StarCellularLighting.hpp index 7cb230f..7c29bb8 100644 --- a/source/base/StarCellularLighting.hpp +++ b/source/base/StarCellularLighting.hpp @@ -136,7 +136,7 @@ public: void setCellIndex(size_t cellIndex, Vec3F const& light, bool obstacle); void addSpreadLight(Vec2F const& position, Vec3F const& light); - void addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience); + void addPointLight(Vec2F const& position, Vec3F const& light, float beam, float beamAngle, float beamAmbience, bool asSpread = false); // Finish the calculation, and put the resulting color data in the given // output image. The image will be reset to the size of the region given in |