Skip to content

Commit 24ace38

Browse files
committed
configurable lights limit; fix spot light
1 parent f742dda commit 24ace38

File tree

5 files changed

+34
-30
lines changed

5 files changed

+34
-30
lines changed

data/cage/shader/engine/fragment.glsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ vec4 lighting(Material material)
124124
if (intensity < CAGE_SHADER_MAX_LIGHTINTENSITYTHRESHOLD)
125125
continue;
126126
intensity *= egacShadowedIntensity(uni);
127+
if (intensity < CAGE_SHADER_MAX_LIGHTINTENSITYTHRESHOLD)
128+
continue;
127129
res.rgb += egacLightBrdf(material, uni.light) * intensity;
128130
}
129131
}

data/cage/shader/engine/uniforms.glsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ layout(std140, binding = CAGE_SHADER_UNIBLOCK_LIGHTS) uniform LightsBlock
7070
{
7171
UniLight uniLights[CAGE_SHADER_MAX_LIGHTS];
7272
};
73+
7374
layout(std140, binding = CAGE_SHADER_UNIBLOCK_SHADOWEDLIGHTS) uniform ShadowedLightsBlock
7475
{
7576
UniShadowedLight uniShadowedLights[CAGE_SHADER_MAX_SHADOWMAPSCUBE + CAGE_SHADER_MAX_SHADOWMAPS2D];

sources/include/cage-engine/scene.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,12 @@ namespace cage
7272
TextAlignEnum align = TextAlignEnum::Center;
7373
};
7474

75-
struct CameraCommonProperties
75+
struct CAGE_ENGINE_API CameraCommonProperties
7676
{
7777
Vec3 ambientColor = Vec3(); // sRGB
7878
Real ambientIntensity = 1;
7979
uint32 sceneMask = 1;
80+
uint32 maxLights = 100;
8081
};
8182

8283
struct CAGE_ENGINE_API CameraComponent : public CameraCommonProperties

sources/libengine/graphics/renderPipeline.cpp

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,12 @@ namespace cage
194194
return uni;
195195
}
196196

197-
UniLight initializeLightUni(const Mat4 &model, const LightComponent &lc)
197+
UniLight initializeLightUni(const Mat4 &model, const LightComponent &lc, const Vec3 &cameraCenter)
198198
{
199199
CAGE_ASSERT(lc.minDistance > 0 && lc.maxDistance > lc.minDistance);
200200
static constexpr Real RoundingOffset = 1e-7;
201201
UniLight uni;
202+
202203
uni.color = Vec4(colorGammaToLinear(lc.color), lc.intensity);
203204
{
204205
// move as much of the energy from the intensity to the color
@@ -207,20 +208,22 @@ namespace cage
207208
c = clamp(c, 0.01, 1);
208209
uni.color = Vec4(Vec3(uni.color) / c, uni.color[3] * c);
209210
}
211+
210212
uni.position = model * Vec4(0, 0, 0, 1);
211-
uni.direction = model * Vec4(0, 0, -1, 0);
212-
if (lc.lightType == LightTypeEnum::Directional)
213-
{
214-
uni.attenuation = Vec4(0);
215-
uni.position[3] = Real::Infinity();
216-
}
217-
else
213+
uni.direction = normalize(model * Vec4(0, 0, -1, 0));
214+
215+
if (lc.lightType != LightTypeEnum::Directional)
218216
{
219217
uni.attenuation[0] = (int)lc.attenuation + RoundingOffset;
220218
uni.attenuation[1] = lc.minDistance;
221219
uni.attenuation[2] = lc.maxDistance;
222-
uni.position[3] = lc.maxDistance;
223220
}
221+
222+
if (lc.lightType == LightTypeEnum::Point)
223+
uni.position[3] = lc.maxDistance / (distance(Vec3(uni.position), cameraCenter) + 1e-5);
224+
else
225+
uni.position[3] = Real::Infinity();
226+
224227
uni.params[0] = [&]() -> Real
225228
{
226229
switch (lc.lightType)
@@ -238,28 +241,22 @@ namespace cage
238241
uni.params[1] = lc.ssaoFactor;
239242
uni.params[2] = cos(lc.spotAngle * 0.5);
240243
uni.params[3] = lc.spotExponent;
244+
241245
return uni;
242246
}
243247

244-
void filterLightsOverLimit(std::vector<UniLight> &lights, Vec3 cameraCenter)
248+
void filterLightsOverLimit(std::vector<UniLight> &lights, uint32 limit)
245249
{
246-
std::sort(lights.begin(), lights.end(),
247-
[&](const UniLight &a, const UniLight &b)
248-
{
249-
const Real aa = a.position[3] / (1 + distance(Vec3(a.position), cameraCenter));
250-
const Real bb = b.position[3] / (1 + distance(Vec3(b.position), cameraCenter));
251-
return aa > bb;
252-
});
253-
if (lights.size() > CAGE_SHADER_MAX_LIGHTS)
254-
lights.resize(CAGE_SHADER_MAX_LIGHTS);
250+
std::sort(lights.begin(), lights.end(), [&](const UniLight &a, const UniLight &b) { return a.position[3] > b.position[3]; });
251+
limit = min(limit, (uint32)CAGE_SHADER_MAX_LIGHTS);
252+
if (lights.size() > limit)
253+
lights.resize(limit);
255254

256255
// fade-out lights close to limit
257-
Real intensity = 1;
258-
for (uint32 i = CAGE_SHADER_MAX_LIGHTS * 85 / 100; i < lights.size(); i++)
259-
{
260-
intensity *= 0.9;
261-
lights[i].color[3] *= intensity;
262-
}
256+
const uint32 s = max(limit * 85 / 100, 10u);
257+
const Real f = 1.0 / (limit - s + 1);
258+
for (uint32 i = s; i < lights.size(); i++)
259+
lights[i].color[3] *= saturate(1 - (i - s + 1) * f);
263260
}
264261

265262
void updateShaderRoutinesForTextures(const std::array<Holder<Texture>, MaxTexturesCountPerMaterial> &textures, UniOptions &options)
@@ -895,13 +892,13 @@ namespace cage
895892
return;
896893
if (e->has<ShadowmapComponent>())
897894
return;
898-
UniLight uni = initializeLightUni(modelTransform(e), lc);
895+
UniLight uni = initializeLightUni(modelTransform(e), lc, data.transform.position);
899896
if (lc.lightType == LightTypeEnum::Point && !intersects(frustum, Sphere(Vec3(uni.position), uni.position[3])))
900897
return;
901898
lights.push_back(uni);
902899
},
903900
+scene, false);
904-
filterLightsOverLimit(lights, data.transform.position);
901+
filterLightsOverLimit(lights, camera.maxLights);
905902
data.lightsCount = numeric_cast<uint32>(lights.size());
906903
if (!lights.empty())
907904
renderQueue->universalUniformArray<UniLight>(lights, CAGE_SHADER_UNIBLOCK_LIGHTS);
@@ -1176,6 +1173,7 @@ namespace cage
11761173
Holder<AsyncTask> prepareShadowmap(CameraData &camera, Entity *e, const LightComponent &lc, const ShadowmapComponent &sc) const
11771174
{
11781175
ShadowmapData &data = camera.shadowmaps[e];
1176+
CAGE_ASSERT(e->id() != 0); // lights with shadowmap may not be anonymous
11791177
data.name = Stringizer() + camera.name + "_shadowmap_" + e->id();
11801178
data.camera.sceneMask = camera.camera.sceneMask;
11811179
data.lightComponent = lc;
@@ -1216,7 +1214,7 @@ namespace cage
12161214

12171215
{
12181216
UniShadowedLight &uni = data.shadowUni;
1219-
(UniLight &)uni = initializeLightUni(data.model, data.lightComponent);
1217+
(UniLight &)uni = initializeLightUni(data.model, data.lightComponent, data.transform.position);
12201218
uni.shadowParams[2] = data.shadowmapComponent.normalOffsetScale;
12211219
uni.shadowParams[3] = data.shadowmapComponent.shadowFactor;
12221220
uni.params[0] += 1; // shadowed light type

sources/libsimple/statisticsGui.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ namespace cage
3434
[this](Entity *e)
3535
{
3636
const uint64 v = engineStatisticsValues(Flags, this->statisticsMode);
37-
if constexpr (Flags == StatisticsGuiFlags::CpuUtilization || Flags == StatisticsGuiFlags::DynamicResolution)
37+
if constexpr (Flags == StatisticsGuiFlags::DynamicResolution)
38+
e->value<GuiTextComponent>().value = engineDynamicResolution().enabled ? (Stringizer() + v + " %") : (Stringizer() + "off");
39+
else if constexpr (Flags == StatisticsGuiFlags::CpuUtilization)
3840
e->value<GuiTextComponent>().value = Stringizer() + v + " %";
3941
else if constexpr (Flags <= StatisticsGuiFlags::FrameTime)
4042
e->value<GuiTextComponent>().value = Stringizer() + (v / 1000) + " ms";

0 commit comments

Comments
 (0)