Skip to content

Commit

Permalink
Implemented vertex light 2d sampling.
Browse files Browse the repository at this point in the history
  • Loading branch information
Relintai committed Mar 26, 2024
1 parent 42171f1 commit d2ed14c
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
75 changes: 75 additions & 0 deletions modules/vertex_lights_2d/vertex_light_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,61 @@ void VertexLights2DServer::VertexLightQuadrant2D::get_lights(List<VertexLightDat
}
}

Color VertexLights2DServer::VertexLightQuadrant2D::sample_light(const Color &p_current_color, const Vector2 &p_position, const int p_item_cull_mask, const int p_layer) {
Color c = p_current_color;

for (uint32_t i = 0; i < lights.size(); ++i) {
VertexLightData2D *l = lights[i];

if (!l->enabled) {
continue;
}

if (l->range.x == 0 || l->range.y == 0) {
continue;
}

if ((l->item_cull_mask & p_item_cull_mask) == 0) {
continue;
}

if (p_layer < l->z_range.x || p_layer > l->z_range.y) {
continue;
}

Vector2 light_to_pos = p_position - l->position;

Vector2 light_to_pos_normal_space = light_to_pos;
light_to_pos_normal_space.x /= static_cast<real_t>(l->range.x);
light_to_pos_normal_space.y /= static_cast<real_t>(l->range.y);

real_t ltpnsl = light_to_pos_normal_space.length();

// Position is outside the light's range.
if (ltpnsl >= 1) {
continue;
}

real_t attenuation = pow(1.0 - ltpnsl, l->attenuation);

Color ac = l->color * attenuation;

switch (l->mode) {
case VertexLights2DServer::VERTEX_LIGHT_2D_MODE_ADD: {
c += ac;
} break;
case VertexLights2DServer::VERTEX_LIGHT_2D_MODE_SUB: {
c -= ac;
} break;
case VertexLights2DServer::VERTEX_LIGHT_2D_MODE_MIX: {
c = c.blend(ac);
} break;
}
}

return c;
}

//VertexLightMap2D

void VertexLights2DServer::VertexLightMap2D::recreate_quadrants() {
Expand Down Expand Up @@ -124,3 +179,23 @@ void VertexLights2DServer::VertexLightMap2D::clear() {
l->quadrant = NULL;
}
}

Color VertexLights2DServer::VertexLightMap2D::sample_light(const Vector2 &p_position, const int p_item_cull_mask, const int p_layer) {
Color c = Color();

Vector2i quadrant_position = to_quadrant_position(p_position);

for (int x = quadrant_position.x - 1; x <= quadrant_position.x + 1; ++x) {
for (int y = quadrant_position.y - 1; y <= quadrant_position.y + 1; ++y) {
Vector2i qp = Vector2i(x, y);

if (quadrants.has(qp)) {
VertexLightQuadrant2D *q = quadrants[qp];

c = q->sample_light(c, p_position, p_item_cull_mask, p_layer);
}
}
}

return c;
}
13 changes: 13 additions & 0 deletions modules/vertex_lights_2d/vertex_lights_2d_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,15 @@ void VertexLights2DServer::light_set_item_cull_mask(RID p_light, const int p_ite
light->item_cull_mask = p_item_cull_mask;
}

// Sampling

Color VertexLights2DServer::sample_light(RID p_map, const Vector2 &p_position, const int p_item_cull_mask, const int p_layer) {
VertexLightMap2D *map = map_owner.getornull(p_map);
ERR_FAIL_COND_V(map == NULL, Color());

return map->sample_light(p_position, p_item_cull_mask, p_layer);
}

// Rest

void VertexLights2DServer::free(RID p_rid) {
Expand Down Expand Up @@ -337,6 +346,10 @@ void VertexLights2DServer::_bind_methods() {

ClassDB::bind_method(D_METHOD("light_get_item_cull_mask", "light"), &VertexLights2DServer::light_get_item_cull_mask);
ClassDB::bind_method(D_METHOD("light_set_item_cull_mask", "light", "item_cull_mask"), &VertexLights2DServer::light_set_item_cull_mask);

// Sampling

ClassDB::bind_method(D_METHOD("sample_light", "map", "position", "item_cull_mask", "layer"), &VertexLights2DServer::sample_light, DEFVAL(1), DEFVAL(0));

// Rest

Expand Down
8 changes: 7 additions & 1 deletion modules/vertex_lights_2d/vertex_lights_2d_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class VertexLights2DServer : public Object {

Vector2i light_get_range(RID p_light);
void light_set_range(RID p_light, const Vector2i &p_range);

real_t light_get_attenuation(RID p_light);
void light_set_attenuation(RID p_light, const real_t p_attenuation);

Expand All @@ -104,6 +104,8 @@ class VertexLights2DServer : public Object {

// Sampling

Color sample_light(RID p_map, const Vector2 &p_position, const int p_item_cull_mask = 1, const int p_layer = 0);

// Rest

void free(RID p_rid);
Expand Down Expand Up @@ -161,6 +163,8 @@ class VertexLights2DServer : public Object {
VertexLightMap2D *map;

void get_lights(List<VertexLightData2D *> *p_lights);

Color sample_light(const Color &p_current_color, const Vector2 &p_local_position, const int p_item_cull_mask, const int p_layer);

VertexLightQuadrant2D() {
map = NULL;
Expand All @@ -186,6 +190,8 @@ class VertexLights2DServer : public Object {
void set_light_position(VertexLightData2D *p_light, const Vector2 &p_position);

void clear();

Color sample_light(const Vector2 &p_position, const int p_item_cull_mask = 1, const int p_layer = 0);

_FORCE_INLINE_ Vector2i to_quadrant_position(const Vector2 &p_position) {
return Vector2i(p_position.x / quadrant_size.x, p_position.y / quadrant_size.y);
Expand Down

0 comments on commit d2ed14c

Please sign in to comment.