Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/base
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2024-03-26 07:31:33 +1100
committerKae <80987908+Novaenia@users.noreply.github.com>2024-03-26 07:31:33 +1100
commitc484fab32dcac655164f082805d1d55d1d058f2f (patch)
tree9eeabdaee723a88bbebdd77d41d1bb93ee3def83 /source/base
parent77d7f8eb81af21dd231f6384951fc2c14c149d5c (diff)
experiment: auto-conversion of object spread lights to hybrid spread/point lights
Diffstat (limited to 'source/base')
-rw-r--r--source/base/StarCellularLightArray.cpp53
-rw-r--r--source/base/StarCellularLightArray.hpp1
-rw-r--r--source/base/StarCellularLighting.cpp6
-rw-r--r--source/base/StarCellularLighting.hpp2
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