Skip to content

Commit e6b59de

Browse files
committed
Add ability to transform scene color in shaders.
1 parent 2a8ee68 commit e6b59de

File tree

9 files changed

+95
-2
lines changed

9 files changed

+95
-2
lines changed

builtin/game/misc_s.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ core.protocol_versions = {
130130
["5.10.0"] = 46,
131131
["5.11.0"] = 47,
132132
["5.12.0"] = 48,
133+
["5.13.0"] = 49,
133134
}
134135

135136
setmetatable(core.protocol_versions, {__newindex = function()

client/shaders/second_stage/opengl_fragment.glsl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ centroid varying vec2 varTexCoord;
3131
varying float exposure; // linear exposure factor, see vertex shader
3232
#endif
3333

34+
uniform mat3 colorTransformMatrix;
35+
3436
#ifdef ENABLE_BLOOM
3537

3638
vec4 applyBloom(vec4 color, vec2 uv)
@@ -103,6 +105,12 @@ vec3 screen_space_dither(highp vec2 frag_coord) {
103105
}
104106
#endif
105107

108+
vec4 applyColorVision(vec4 color)
109+
{
110+
vec3 transformedColor = colorTransformMatrix * color.rgb;
111+
return vec4(transformedColor, color.a);
112+
}
113+
106114
void main(void)
107115
{
108116
vec2 uv = varTexCoord.st;
@@ -133,6 +141,7 @@ void main(void)
133141
color = applyBloom(color, uv);
134142
#endif
135143

144+
color = applyColorVision(color);
136145

137146
color.rgb = clamp(color.rgb, vec3(0.), vec3(1.));
138147

doc/lua_api.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9064,6 +9064,23 @@ child will follow movement and rotation of that bone.
90649064
* Currently, bloom `intensity` and `strength_factor` affect volumetric
90659065
lighting `strength` and vice versa. This behavior is to be changed
90669066
in the future, do not rely on it.
9067+
* `color_transform_matrix`: is a matrix with default value (identity matrix):
9068+
```lua
9069+
{ {1.0, 0.0, 0.0}, -- r
9070+
{0.0, 1.0, 0.0}, -- g
9071+
{0.0, 0.0, 1.0}} -- b
9072+
```
9073+
9074+
* Work as `transformed_color_RGB = color_transform_matrix * color_RGB`
9075+
* Can be used for creation color blind effect, base for night vision effect etc.
9076+
* Request client with protocol version 49 or higger.
9077+
9078+
```lua
9079+
-- example of night vision like transform
9080+
{ {0.0, 0.0, 0.0},
9081+
{1.0, 9.0, 1.0},
9082+
{0.0, 0.0, 0.0}}
9083+
```
90679084

90689085
* `get_lighting()`: returns the current state of lighting for the player.
90699086
* Result is a table with the same fields as `light_definition` in `set_lighting`.

src/client/game.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter
231231
CachedPixelShaderSetting<float>
232232
m_volumetric_light_strength_pixel{"volumetricLightStrength"};
233233

234+
CachedPixelShaderSetting<float, 9>
235+
m_color_transform_matrix{"colorTransformMatrix"};
236+
234237
static constexpr std::array<const char*, 1> SETTING_CALLBACKS = {
235238
"exposure_compensation",
236239
};
@@ -321,6 +324,8 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter
321324
m_bloom_radius_pixel.set(&radius, services);
322325
}
323326

327+
m_color_transform_matrix.set(lighting.vision_effects.color_transform_matrix.data(), services);
328+
324329
float saturation = lighting.saturation;
325330
m_saturation_pixel.set(&saturation, services);
326331

src/lighting.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ struct AutoExposure
4040
{}
4141
};
4242

43+
struct VisionEffects
44+
{
45+
std::array<float, 9> color_transform_matrix;
46+
47+
constexpr VisionEffects()
48+
: color_transform_matrix{
49+
1.0f, 0.0f, 0.0f,
50+
0.0f, 1.0f, 0.0f,
51+
0.0f, 0.0f, 1.0f}
52+
{}
53+
};
54+
4355
/** Describes ambient light settings for a player
4456
*/
4557
struct Lighting
@@ -52,4 +64,5 @@ struct Lighting
5264
float bloom_intensity {0.05f};
5365
float bloom_strength_factor {1.0f};
5466
float bloom_radius {1.0f};
67+
VisionEffects vision_effects;
5568
};

src/network/clientpackethandler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,4 +1794,9 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
17941794
>> lighting.bloom_strength_factor
17951795
>> lighting.bloom_radius;
17961796
}
1797+
if (pkt->getRemainingBytes() >= 36) {
1798+
for (int i = 0; i < 9; ++i) {
1799+
*pkt >> lighting.vision_effects.color_transform_matrix[i];
1800+
}
1801+
}
17971802
}

src/network/networkprotocol.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,13 @@
6565
PROTOCOL VERSION 48
6666
Add compression to some existing packets
6767
[scheduled bump for 5.12.0]
68+
PROTOCOL VERSION 49
69+
Add "vision_effects" to TOCLIENT_SET_LIGHTING packet
70+
[scheduled bump for 5.13.0]
6871
*/
6972

7073
// Note: Also update core.protocol_versions in builtin when bumping
71-
const u16 LATEST_PROTOCOL_VERSION = 48;
74+
const u16 LATEST_PROTOCOL_VERSION = 49;
7275

7376
// See also formspec [Version History] in doc/lua_api.md
7477
const u16 FORMSPEC_API_VERSION = 9;

src/script/lua_api/l_object.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,32 @@ int ObjectRef::l_set_lighting(lua_State *L)
26962696
lighting.bloom_radius = getfloatfield_default(L, -1, "radius", lighting.bloom_radius);
26972697
}
26982698
lua_pop(L, 1); // bloom
2699-
}
2699+
2700+
lua_getfield(L, 2, "color_transform_matrix");
2701+
2702+
// if none or nil, keep color transform matrix unchanged
2703+
if (!lua_isnoneornil(L, -1)) {
2704+
if (!lua_istable(L, -1))
2705+
throw LuaError("vision_effects.color_transform_matrix is not a table");
2706+
2707+
for (int row = 1; row <= 3; ++row) {
2708+
lua_rawgeti(L, -1, row);
2709+
if (!lua_istable(L, -1))
2710+
throw LuaError("color_transform_matrix should be in format {{a, b, c},{d, e, f},{g, a, h}}");
2711+
2712+
for (int col = 1; col <= 3; ++col) {
2713+
lua_rawgeti(L, -1, col);
2714+
if (!lua_isnumber(L, -1))
2715+
throw LuaError("color_transform_matrix should be in format {{a, b, c},{d, e, f},{g, a, h}}");
2716+
2717+
lighting.vision_effects.color_transform_matrix[(row - 1) * 3 + (col - 1)] = (float)lua_tonumber(L, -1);
2718+
lua_pop(L, 1); // Pop the value at [row][col]
2719+
}
2720+
lua_pop(L, 1); // Pop the row table
2721+
}
2722+
}
2723+
lua_pop(L, 1); // color_transform_matrix
2724+
}
27002725

27012726
getServer(L)->setLighting(player, lighting);
27022727
return 0;
@@ -2748,6 +2773,17 @@ int ObjectRef::l_get_lighting(lua_State *L)
27482773
lua_pushnumber(L, lighting.bloom_radius);
27492774
lua_setfield(L, -2, "radius");
27502775
lua_setfield(L, -2, "bloom");
2776+
lua_newtable(L); // "color_transform_matrix"
2777+
// Create the nested table structure {{a, b, c}, {d, e, f}, {g, h, i}}
2778+
for (int row = 0; row < 3; row++) {
2779+
lua_newtable(L); // Create inner row table
2780+
for (int col = 0; col < 3; col++) {
2781+
lua_pushnumber(L, lighting.vision_effects.color_transform_matrix[row * 3 + col]); // Push the value
2782+
lua_rawseti(L, -2, col + 1); // Set value in inner table with 1-based indexing
2783+
}
2784+
lua_rawseti(L, -2, row + 1); // Set inner table in the outer matrix table
2785+
}
2786+
lua_setfield(L, -2, "color_transform_matrix");
27512787
return 1;
27522788
}
27532789

src/server.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,10 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
19521952
pkt << lighting.bloom_intensity << lighting.bloom_strength_factor <<
19531953
lighting.bloom_radius;
19541954

1955+
for (int i = 0; i < 9; ++i) {
1956+
pkt << lighting.vision_effects.color_transform_matrix[i];
1957+
}
1958+
19551959
Send(&pkt);
19561960
}
19571961

0 commit comments

Comments
 (0)