diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 816cc8018..a8d0db1da 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -5103,6 +5103,12 @@ function le_set_ambient_color(r, g, b)
-- ...
end
+--- @param count integer
+--- Sets the max amount of lights that can affect a vertex
+function le_set_max_lights_per_vertex(count)
+ -- ...
+end
+
--- @param pos Vec3f
--- @param out Color
--- @param lightIntensityScalar number
diff --git a/docs/lua/functions-4.md b/docs/lua/functions-4.md
index 545c0d19f..18fa49891 100644
--- a/docs/lua/functions-4.md
+++ b/docs/lua/functions-4.md
@@ -147,6 +147,29 @@ Sets the lighting engine ambient color
+## [le_set_max_lights_per_vertex](#le_set_max_lights_per_vertex)
+
+### Description
+Sets the max amount of lights that can affect a vertex
+
+### Lua Example
+`le_set_max_lights_per_vertex(count)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| count | `integer` |
+
+### Returns
+- None
+
+### C Prototype
+`void le_set_max_lights_per_vertex(u8 count);`
+
+[:arrow_up_small:](#)
+
+
+
## [le_calculate_lighting_color](#le_calculate_lighting_color)
### Description
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index e2cff77bf..943af169d 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -976,6 +976,7 @@
- [le_set_tone_mapping](functions-4.md#le_set_tone_mapping)
- [le_get_ambient_color](functions-4.md#le_get_ambient_color)
- [le_set_ambient_color](functions-4.md#le_set_ambient_color)
+ - [le_set_max_lights_per_vertex](functions-4.md#le_set_max_lights_per_vertex)
- [le_calculate_lighting_color](functions-4.md#le_calculate_lighting_color)
- [le_calculate_lighting_color_with_normal](functions-4.md#le_calculate_lighting_color_with_normal)
- [le_calculate_lighting_dir](functions-4.md#le_calculate_lighting_dir)
diff --git a/src/engine/lighting_engine.cpp b/src/engine/lighting_engine.cpp
index f3d6539f0..0a12b55d5 100644
--- a/src/engine/lighting_engine.cpp
+++ b/src/engine/lighting_engine.cpp
@@ -1,6 +1,7 @@
#include "lighting_engine.h"
extern "C" {
#include "math_util.h"
+#include "pc/lua/smlua.h"
}
#undef clamp
#undef min
@@ -13,17 +14,11 @@ extern "C" {
#define C_FIELD extern "C"
-#define LE_MAX_LIGHTS_PER_VERTEX 4
-
struct LELight
{
s16 id;
- f32 posX;
- f32 posY;
- f32 posZ;
- u8 colorR;
- u8 colorG;
- u8 colorB;
+ Vec3f pos;
+ Color color;
f32 radius;
f32 intensity;
bool useSurfaceNormals;
@@ -36,6 +31,7 @@ static s16 sLightID = -1;
static enum LEMode sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
static enum LEToneMapping sToneMapping = LE_TONE_MAPPING_WEIGHTED;
static bool sEnabled = false;
+static u8 sMaxLightsPerVertex = 4;
static inline f32 rsqrt(f32 value) {
#ifdef __SSE__
@@ -57,9 +53,8 @@ static inline void color_copy(Color dest, Color src) {
dest[2] = src[2];
}
-
-static inline u8 to_u8(float value) {
- int v = (int)value;
+static inline u8 clamp_u8(f32 value) {
+ s32 v = (s32)value;
v = v < 0 ? 0 : v;
v = v > 255 ? 255 : v;
return (u8)v;
@@ -93,22 +88,26 @@ C_FIELD void le_set_ambient_color(u8 r, u8 g, u8 b) {
sEnabled = true;
}
-static inline void le_tone_map_total_weighted(Color out, Color inAmbient, Vec3f inColor, float weight) {
- out[0] = to_u8((inAmbient[0] + inColor[0]) / weight);
- out[1] = to_u8((inAmbient[1] + inColor[1]) / weight);
- out[2] = to_u8((inAmbient[2] + inColor[2]) / weight);
+C_FIELD void le_set_max_lights_per_vertex(u8 count) {
+ sMaxLightsPerVertex = count;
}
-static inline void le_tone_map_weighted(Color out, Color inAmbient, Vec3f inColor, float weight) {
- out[0] = to_u8(inAmbient[0] + (inColor[0] / weight));
- out[1] = to_u8(inAmbient[1] + (inColor[1] / weight));
- out[2] = to_u8(inAmbient[2] + (inColor[2] / weight));
+static inline void le_tone_map_total_weighted(Color out, Color inAmbient, Vec3f inColor, f32 weight) {
+ out[0] = clamp_u8((inAmbient[0] + inColor[0]) / weight);
+ out[1] = clamp_u8((inAmbient[1] + inColor[1]) / weight);
+ out[2] = clamp_u8((inAmbient[2] + inColor[2]) / weight);
+}
+
+static inline void le_tone_map_weighted(Color out, Color inAmbient, Vec3f inColor, f32 weight) {
+ out[0] = clamp_u8(inAmbient[0] + (inColor[0] / weight));
+ out[1] = clamp_u8(inAmbient[1] + (inColor[1] / weight));
+ out[2] = clamp_u8(inAmbient[2] + (inColor[2] / weight));
}
static inline void le_tone_map_clamp(Color out, Color inAmbient, Vec3f inColor) {
- out[0] = to_u8(inAmbient[0] + inColor[0]);
- out[1] = to_u8(inAmbient[1] + inColor[1]);
- out[2] = to_u8(inAmbient[2] + inColor[2]);
+ out[0] = clamp_u8(inAmbient[0] + inColor[0]);
+ out[1] = clamp_u8(inAmbient[1] + inColor[1]);
+ out[2] = clamp_u8(inAmbient[2] + inColor[2]);
}
static inline void le_tone_map_reinhard(Color out, Color inAmbient, Vec3f inColor) {
@@ -116,12 +115,12 @@ static inline void le_tone_map_reinhard(Color out, Color inAmbient, Vec3f inColo
inColor[1] += inAmbient[1];
inColor[2] += inAmbient[2];
- out[0] = to_u8((inColor[0] / (inColor[0] + 255.0f)) * 255.0f);
- out[1] = to_u8((inColor[1] / (inColor[1] + 255.0f)) * 255.0f);
- out[2] = to_u8((inColor[2] / (inColor[2] + 255.0f)) * 255.0f);
+ out[0] = clamp_u8((inColor[0] / (inColor[0] + 255.0f)) * 255.0f);
+ out[1] = clamp_u8((inColor[1] / (inColor[1] + 255.0f)) * 255.0f);
+ out[2] = clamp_u8((inColor[2] / (inColor[2] + 255.0f)) * 255.0f);
}
-static inline void le_tone_map(Color out, Color inAmbient, Vec3f inColor, float weight) {
+static void le_tone_map(Color out, Color inAmbient, Vec3f inColor, f32 weight) {
switch (sToneMapping) {
case LE_TONE_MAPPING_TOTAL_WEIGHTED: le_tone_map_total_weighted(out, inAmbient, inColor, weight); break;
case LE_TONE_MAPPING_WEIGHTED: le_tone_map_weighted(out, inAmbient, inColor, weight); break;
@@ -139,11 +138,11 @@ static void le_update_active_lights() {
}
}
-static inline OPTIMIZE_O3 void le_calculate_light_contribution(const LELight& light, Vec3f pos, Vec3f normal, f32 lightIntensityScalar, Vec3f out_color, f32& weight, u8& contribution) {
+static inline OPTIMIZE_O3 void le_calculate_light_contribution(const LELight& light, Vec3f pos, Vec3f normal, f32 lightIntensityScalar, Vec3f outColor, f32& weight, u8& contribution) {
// vector to light
- f32 diffX = light.posX - pos[0];
- f32 diffY = light.posY - pos[1];
- f32 diffZ = light.posZ - pos[2];
+ f32 diffX = light.pos[0] - pos[0];
+ f32 diffY = light.pos[1] - pos[1];
+ f32 diffZ = light.pos[2] - pos[2];
// squared distance check
f32 dist2 = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
@@ -170,14 +169,14 @@ static inline OPTIMIZE_O3 void le_calculate_light_contribution(const LELight& li
}
// accumulate
- out_color[0] += light.colorR * brightness;
- out_color[1] += light.colorG * brightness;
- out_color[2] += light.colorB * brightness;
+ outColor[0] += light.color[0] * brightness;
+ outColor[1] += light.color[1] * brightness;
+ outColor[2] += light.color[2] * brightness;
weight += brightness;
contribution++;
}
-C_FIELD OPTIMIZE_O3 void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, Color out) {
+C_FIELD OPTIMIZE_O3 void le_calculate_vertex_lighting(const Vtx_t* v, Vec3f pos, VEC_OUT Color out) {
// clear color
Vec3f color = { 0 };
@@ -186,7 +185,7 @@ C_FIELD OPTIMIZE_O3 void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, Color
u8 contribution = 0;
for (LELight* light : sActiveLights) {
le_calculate_light_contribution(*light, pos, NULL, 1.0f, color, weight, contribution);
- if (contribution == LE_MAX_LIGHTS_PER_VERTEX) { break; }
+ if (contribution == sMaxLightsPerVertex) { break; }
}
// tone map and output
@@ -198,7 +197,7 @@ C_FIELD OPTIMIZE_O3 void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, Color
le_tone_map(out, vtxAmbient, color, weight);
}
-C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color(Vec3f pos, Color out, f32 lightIntensityScalar) {
+C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color(Vec3f pos, VEC_OUT Color out, f32 lightIntensityScalar) {
// clear color
Vec3f color = { 0 };
@@ -207,14 +206,14 @@ C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color(Vec3f pos, Color out, f32 l
u8 contribution = 0;
for (LELight* light : sActiveLights) {
le_calculate_light_contribution(*light, pos, NULL, lightIntensityScalar, color, weight, contribution);
- if (contribution == LE_MAX_LIGHTS_PER_VERTEX) { break; }
+ if (contribution == sMaxLightsPerVertex) { break; }
}
// tone map and output
le_tone_map(out, gLEAmbientColor, color, weight);
}
-C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, Color out, f32 lightIntensityScalar) {
+C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, VEC_OUT Color out, f32 lightIntensityScalar) {
// normalize normal
if (normal) { vec3f_normalize(normal); }
@@ -226,29 +225,29 @@ C_FIELD OPTIMIZE_O3 void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3
u8 contribution = 0;
for (LELight* light : sActiveLights) {
le_calculate_light_contribution(*light, pos, normal, lightIntensityScalar, color, weight, contribution);
- if (contribution == LE_MAX_LIGHTS_PER_VERTEX) { break; }
+ if (contribution == sMaxLightsPerVertex) { break; }
}
// tone map and output
le_tone_map(out, gLEAmbientColor, color, weight);
}
-C_FIELD void le_calculate_lighting_dir(Vec3f pos, Vec3f out) {
+C_FIELD void le_calculate_lighting_dir(Vec3f pos, VEC_OUT Vec3f out) {
Vec3f lightingDir = { 0, 0, 0 };
s16 count = 1;
for (LELight* light : sActiveLights) {
- f32 diffX = light->posX - pos[0];
- f32 diffY = light->posY - pos[1];
- f32 diffZ = light->posZ - pos[2];
+ f32 diffX = light->pos[0] - pos[0];
+ f32 diffY = light->pos[1] - pos[1];
+ f32 diffZ = light->pos[2] - pos[2];
f32 dist = (diffX * diffX) + (diffY * diffY) + (diffZ * diffZ);
f32 radius = light->radius * light->radius;
if (dist > radius) { continue; }
Vec3f dir = {
- pos[0] - light->posX,
- pos[1] - light->posY,
- pos[2] - light->posZ,
+ pos[0] - light->pos[0],
+ pos[1] - light->pos[1],
+ pos[2] - light->pos[2],
};
vec3f_normalize(dir);
@@ -267,16 +266,19 @@ C_FIELD void le_calculate_lighting_dir(Vec3f pos, Vec3f out) {
}
C_FIELD s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32 intensity) {
- if (sLightPool.size() >= LE_MAX_LIGHTS) { return -1; }
+ if (sLightPool.size() >= LE_MAX_LIGHTS) {
+ LOG_LUA_LINE("LE light count cannot exceed %d lights!", LE_MAX_LIGHTS);
+ return -1;
+ }
LELight newLight;
newLight.id = ++sLightID;
- newLight.posX = x;
- newLight.posY = y;
- newLight.posZ = z;
- newLight.colorR = r;
- newLight.colorG = g;
- newLight.colorB = b;
+ newLight.pos[0] = x;
+ newLight.pos[1] = y;
+ newLight.pos[2] = z;
+ newLight.color[0] = r;
+ newLight.color[1] = g;
+ newLight.color[2] = b;
newLight.radius = radius;
newLight.intensity = intensity;
newLight.useSurfaceNormals = true;
@@ -292,15 +294,16 @@ C_FIELD s16 le_add_light(f32 x, f32 y, f32 z, u8 r, u8 g, u8 b, f32 radius, f32
C_FIELD void le_remove_light(s16 id) {
if (id < 0) { return; }
- sLightPool.erase(
- std::remove_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- ),
- sLightPool.end()
+ auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
+ [id](const LELight& light) {
+ return light.id == id;
+ }
);
+ if (it != sLightPool.end()) {
+ sLightPool.erase(it);
+ }
+
le_update_active_lights();
}
@@ -318,8 +321,8 @@ C_FIELD bool le_light_exists(s16 id) {
);
}
-C_FIELD void le_get_light_pos(s16 id, VEC_OUT Vec3f out) {
- if (id < 0) { return; }
+static LELight* le_find_light(s16 id) {
+ if (id < 0) { return nullptr; }
auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
[id](const LELight& light) {
@@ -327,73 +330,51 @@ C_FIELD void le_get_light_pos(s16 id, VEC_OUT Vec3f out) {
}
);
- if (it != sLightPool.end()) {
- LELight& light = *it;
- vec3f_set(out, light.posX, light.posY, light.posZ);
+ // kinda cursed syntax but it works
+ return (it != sLightPool.end()) ? &(*it) : nullptr;
+}
+
+C_FIELD void le_get_light_pos(s16 id, VEC_OUT Vec3f out) {
+ if (id < 0) { return; }
+
+ if (auto* light = le_find_light(id)) {
+ vec3f_set(out, light->pos[0], light->pos[1], light->pos[2]);
}
}
C_FIELD void le_set_light_pos(s16 id, f32 x, f32 y, f32 z) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- light.posX = x;
- light.posY = y;
- light.posZ = z;
+ if (auto* light = le_find_light(id)) {
+ light->pos[0] = x;
+ light->pos[1] = y;
+ light->pos[2] = z;
}
}
C_FIELD void le_get_light_color(s16 id, VEC_OUT Color out) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- color_set(out, light.colorR, light.colorG, light.colorB);
+ if (auto* light = le_find_light(id)) {
+ color_set(out, light->color[0], light->color[1], light->color[2]);
}
}
C_FIELD void le_set_light_color(s16 id, u8 r, u8 g, u8 b) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- light.colorR = r;
- light.colorG = g;
- light.colorB = b;
+ if (auto* light = le_find_light(id)) {
+ light->color[0] = r;
+ light->color[1] = g;
+ light->color[2] = b;
}
}
C_FIELD f32 le_get_light_radius(s16 id) {
if (id < 0) { return 0.0f; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- return light.radius;
+ if (auto* light = le_find_light(id)) {
+ return light->radius;
}
return 0.0f;
@@ -402,15 +383,8 @@ C_FIELD f32 le_get_light_radius(s16 id) {
C_FIELD void le_set_light_radius(s16 id, f32 radius) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- light.radius = radius;
+ if (auto* light = le_find_light(id)) {
+ light->radius = radius;
}
le_update_active_lights();
@@ -419,15 +393,8 @@ C_FIELD void le_set_light_radius(s16 id, f32 radius) {
C_FIELD f32 le_get_light_intensity(s16 id) {
if (id < 0) { return 0.0f; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- return light.intensity;
+ if (auto* light = le_find_light(id)) {
+ return light->intensity;
}
return 0.0f;
@@ -436,15 +403,8 @@ C_FIELD f32 le_get_light_intensity(s16 id) {
C_FIELD void le_set_light_intensity(s16 id, f32 intensity) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- light.intensity = intensity;
+ if (auto* light = le_find_light(id)) {
+ light->intensity = intensity;
}
le_update_active_lights();
@@ -453,15 +413,8 @@ C_FIELD void le_set_light_intensity(s16 id, f32 intensity) {
C_FIELD bool le_get_light_use_surface_normals(s16 id) {
if (id < 0) { return false; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- return light.useSurfaceNormals;
+ if (auto* light = le_find_light(id)) {
+ return light->useSurfaceNormals;
}
return false;
@@ -470,30 +423,22 @@ C_FIELD bool le_get_light_use_surface_normals(s16 id) {
C_FIELD void le_set_light_use_surface_normals(s16 id, bool useSurfaceNormals) {
if (id < 0) { return; }
- auto it = std::find_if(sLightPool.begin(), sLightPool.end(),
- [id](const LELight& light) {
- return light.id == id;
- }
- );
-
- if (it != sLightPool.end()) {
- LELight& light = *it;
- light.useSurfaceNormals = useSurfaceNormals;
+ if (auto* light = le_find_light(id)) {
+ light->useSurfaceNormals = useSurfaceNormals;
}
}
void le_clear(void) {
sLightPool.clear();
- sLightID = 0;
+ sLightID = -1;
- gLEAmbientColor[0] = 127;
- gLEAmbientColor[1] = 127;
- gLEAmbientColor[2] = 127;
+ color_set(gLEAmbientColor, 127, 127, 127);
}
void le_shutdown(void) {
sEnabled = false;
sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
sToneMapping = LE_TONE_MAPPING_WEIGHTED;
+ sMaxLightsPerVertex = 4;
le_clear();
}
diff --git a/src/engine/lighting_engine.h b/src/engine/lighting_engine.h
index 0d038c750..cc0d4d725 100644
--- a/src/engine/lighting_engine.h
+++ b/src/engine/lighting_engine.h
@@ -35,8 +35,10 @@ void le_set_tone_mapping(enum LEToneMapping toneMapping);
void le_get_ambient_color(VEC_OUT Color out);
/* |description|Sets the lighting engine ambient color|descriptionEnd| */
void le_set_ambient_color(u8 r, u8 g, u8 b);
+/* |description|Sets the max amount of lights that can affect a vertex|descriptionEnd| */
+void le_set_max_lights_per_vertex(u8 count);
-void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, VEC_OUT Color out);
+void le_calculate_vertex_lighting(const Vtx_t* v, Vec3f pos, VEC_OUT Color out);
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and outputs the color in `out`|descriptionEnd|*/
void le_calculate_lighting_color(Vec3f pos, VEC_OUT Color out, f32 lightIntensityScalar);
/* |description|Calculates the lighting with `lightIntensityScalar` at a position and with a normal and outputs the color in `out`|descriptionEnd|*/
diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c
index e5ea2384b..1184eaba1 100644
--- a/src/pc/gfx/gfx_pc.c
+++ b/src/pc/gfx/gfx_pc.c
@@ -929,7 +929,7 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
if (affectAllVertexColored && !(rsp.geometry_mode & G_LIGHTING_ENGINE_EXT)) {
le_calculate_lighting_color(vpos, color, 1.0f);
} else {
- le_calculate_vertex_lighting((Vtx_t*)v, vpos, color);
+ le_calculate_vertex_lighting(v, vpos, color);
}
CTX_END(CTX_LIGHTING);
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 60ced0477..b20acc5cd 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -15768,6 +15768,23 @@ int smlua_func_le_set_ambient_color(lua_State* L) {
return 1;
}
+int smlua_func_le_set_max_lights_per_vertex(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "le_set_max_lights_per_vertex", 1, top);
+ return 0;
+ }
+
+ u8 count = smlua_to_integer(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "le_set_max_lights_per_vertex"); return 0; }
+
+ le_set_max_lights_per_vertex(count);
+
+ return 1;
+}
+
int smlua_func_le_calculate_lighting_color(lua_State* L) {
if (L == NULL) { return 0; }
@@ -37935,6 +37952,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "le_set_tone_mapping", smlua_func_le_set_tone_mapping);
smlua_bind_function(L, "le_get_ambient_color", smlua_func_le_get_ambient_color);
smlua_bind_function(L, "le_set_ambient_color", smlua_func_le_set_ambient_color);
+ smlua_bind_function(L, "le_set_max_lights_per_vertex", smlua_func_le_set_max_lights_per_vertex);
smlua_bind_function(L, "le_calculate_lighting_color", smlua_func_le_calculate_lighting_color);
smlua_bind_function(L, "le_calculate_lighting_color_with_normal", smlua_func_le_calculate_lighting_color_with_normal);
smlua_bind_function(L, "le_calculate_lighting_dir", smlua_func_le_calculate_lighting_dir);