Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak fire effect pointlight #3698

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/ivis_opengl/gfx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ namespace gfx_api
float unused2;
std::array<glm::vec4, max_lights> PointLightsPosition;
std::array<glm::vec4, max_lights> PointLightsColorAndEnergy;
std::array<glm::ivec4, 64> bucketOffsetAndSize;
std::array<glm::ivec4, bucket_dimension * bucket_dimension> bucketOffsetAndSize;
std::array<glm::ivec4, max_indexed_lights> indexed_lights;
};

Expand Down
69 changes: 42 additions & 27 deletions lib/ivis_opengl/pielighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,24 @@ namespace {
glm::vec3 vertical(0.f, 1.0f, 0.f);
glm::vec3 forward(0.f, 0.f, 1.0f);

auto horizRange = horizontal * range;
auto verticalRange = vertical * range;
auto forwardRange = forward * range;

auto centerMinusHorizRange = center - horizRange;
auto centerPlusHorizRange = center + horizRange;
auto verticalRangeMinusForwardRange = verticalRange - forwardRange;
auto verticalRangePlusForwardRange = verticalRange + forwardRange;

return BoundingBox{
center - horizontal * range - vertical * range - forward * range,
center - horizontal * range - vertical * range + forward * range,
center - horizontal * range + vertical * range - forward * range,
center - horizontal * range + vertical * range + forward * range,
center + horizontal * range - vertical * range - forward * range,
center + horizontal * range - vertical * range + forward * range,
center + horizontal * range + vertical * range - forward * range,
center + horizontal * range + vertical * range + forward * range
centerMinusHorizRange - verticalRangeMinusForwardRange,
centerMinusHorizRange - verticalRangePlusForwardRange,
centerMinusHorizRange + verticalRangeMinusForwardRange,
centerMinusHorizRange + verticalRangePlusForwardRange,
centerPlusHorizRange - verticalRangeMinusForwardRange,
centerPlusHorizRange - verticalRangePlusForwardRange,
centerPlusHorizRange + verticalRangeMinusForwardRange,
centerPlusHorizRange + verticalRangePlusForwardRange
};
}

Expand All @@ -107,20 +116,21 @@ namespace {
void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, LightMap&, const glm::mat4& worldViewProjectionMatrix)
{
PointLightBuckets result;
const bool yAxisInverted = gfx_api::context::get().isYAxisInverted();

// Pick the first lights inside the view frustum
auto viewFrustum = IntersectionOfHalfSpace{
[](const glm::vec3& in) { return in.x >= -1.f; },
[](const glm::vec3& in) { return in.x <= 1.f; },
[](const glm::vec3& in) {
if (gfx_api::context::get().isYAxisInverted())
[yAxisInverted](const glm::vec3& in) {
if (yAxisInverted)
{
return -in.y >= -1.f;
}
return in.y >= -1.f;
},
[](const glm::vec3& in) {
if (gfx_api::context::get().isYAxisInverted())
[yAxisInverted](const glm::vec3& in) {
if (yAxisInverted)
{
return -in.y <= 1.f;
}
Expand All @@ -130,7 +140,7 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, L
[](const glm::vec3& in) { return in.z <= 1; }
};

std::vector<LIGHT> culledLights;
culledLights.clear();
for (const auto& light : data.lights)
{
if (culledLights.size() >= gfx_api::max_lights)
Expand All @@ -142,13 +152,13 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, L
{
continue;
}
culledLights.push_back(light);
culledLights.push_back({light, clipSpaceBoundingBox});
}


for (size_t lightIndex = 0, end = culledLights.size(); lightIndex < end; lightIndex++)
{
const auto& light = culledLights[lightIndex];
const auto& light = culledLights[lightIndex].light;
result.positions[lightIndex].x = light.position.x;
result.positions[lightIndex].y = light.position.y;
result.positions[lightIndex].z = light.position.z;
Expand All @@ -168,20 +178,26 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, L
std::array<size_t, gfx_api::max_indexed_lights * 4> lightList;
for (size_t i = 0; i < gfx_api::bucket_dimension; i++)
{
auto bucketFrustumX0 = -1.f + 2 * static_cast<float>(i) / gfx_api::bucket_dimension;
auto bucketFrustumX1 = -1.f + 2 * static_cast<float>(i + 1) / gfx_api::bucket_dimension;

for (size_t j = 0; j < gfx_api::bucket_dimension; j++)
{
auto bucketFrustumY0 = -1.f + 2 * static_cast<float>(j) / gfx_api::bucket_dimension;
auto bucketFrustumY1 = -1.f + 2 * static_cast<float>(j + 1) / gfx_api::bucket_dimension;

auto frustum = IntersectionOfHalfSpace{
[i](const glm::vec3& in) { return in.x >= -1.f + 2 * static_cast<float>(i) / gfx_api::bucket_dimension; },
[i](const glm::vec3& in) { return in.x <= -1.f + 2 * static_cast<float>(i + 1) / gfx_api::bucket_dimension; },
[j](const glm::vec3& in) {
if (gfx_api::context::get().isYAxisInverted())
return -in.y >= -1.f + 2 * static_cast<float>(j) / gfx_api::bucket_dimension;
return in.y >= -1.f + 2 * static_cast<float>(j) / gfx_api::bucket_dimension;
[bucketFrustumX0](const glm::vec3& in) { return in.x >= bucketFrustumX0; },
[bucketFrustumX1](const glm::vec3& in) { return in.x <= bucketFrustumX1; },
[bucketFrustumY0, yAxisInverted](const glm::vec3& in) {
if (yAxisInverted)
return -in.y >= bucketFrustumY0;
return in.y >= bucketFrustumY0;
},
[j](const glm::vec3& in) {
if (gfx_api::context::get().isYAxisInverted())
return -in.y <= -1.f + 2 * static_cast<float>(j + 1) / gfx_api::bucket_dimension;
return in.y <= -1.f + 2 * static_cast<float>(j + 1) / gfx_api::bucket_dimension;
[bucketFrustumY1, yAxisInverted](const glm::vec3& in) {
if (yAxisInverted)
return -in.y <= bucketFrustumY1;
return in.y <= bucketFrustumY1;
},
[](const glm::vec3& in) { return in.z >= 0; },
[](const glm::vec3& in) { return in.z <= 1; }
Expand All @@ -194,8 +210,7 @@ void renderingNew::LightingManager::ComputeFrameData(const LightingData& data, L
{
continue;
}
const LIGHT& light = culledLights[lightIndex];
BoundingBox clipSpaceBoundingBox = transformBoundingBox(worldViewProjectionMatrix, getLightBoundingBox(light));
const BoundingBox& clipSpaceBoundingBox = culledLights[lightIndex].clipSpaceBoundingBox;

if (isBBoxInClipSpace(frustum, clipSpaceBoundingBox))
{
Expand Down
10 changes: 10 additions & 0 deletions lib/ivis_opengl/pielighting.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@

#include "lib/ivis_opengl/pietypes.h"
#include "gfx_api.h"
#include "culling.h"
#include <glm/glm.hpp>
#include <memory>
#include <array>
#include <vector>

struct LIGHT
{
Expand Down Expand Up @@ -95,6 +97,14 @@ namespace renderingNew
struct LightingManager final : ILightingManager
{
void ComputeFrameData(const LightingData& data, LightMap& lightmap, const glm::mat4& worldViewProjectionMatrix) override;
private:
// cached containers to avoid frequent reallocations
struct CulledLightInfo
{
const LIGHT& light;
BoundingBox clipSpaceBoundingBox;
};
std::vector<CulledLightInfo> culledLights;
};
}

Expand Down
5 changes: 4 additions & 1 deletion src/effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,8 +1303,11 @@ static bool updateFire(EFFECT *psEffect, LightingData& lightData)
percent = 100;
}

constexpr int fireLightHeightAboveGround = 28;

light.position = psEffect->position;
light.range = (percent * psEffect->radius * 3) / 100;
light.position.y += fireLightHeightAboveGround;
light.range = (percent * psEffect->radius * 6) / 100;
light.colour = pal_Colour(255, 0, 0);
lightData.lights.push_back(light);

Expand Down
Loading