mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add ability to transform scene color in shaders.
This commit is contained in:
parent
81d62d01d1
commit
0fe53a3cf2
10 changed files with 104 additions and 2 deletions
|
@ -47,6 +47,7 @@ core.features = {
|
||||||
particle_blend_clip = true,
|
particle_blend_clip = true,
|
||||||
remove_item_match_meta = true,
|
remove_item_match_meta = true,
|
||||||
httpfetch_additional_methods = true,
|
httpfetch_additional_methods = true,
|
||||||
|
vision_color_transform = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function core.has_feature(arg)
|
function core.has_feature(arg)
|
||||||
|
|
|
@ -130,6 +130,7 @@ core.protocol_versions = {
|
||||||
["5.10.0"] = 46,
|
["5.10.0"] = 46,
|
||||||
["5.11.0"] = 47,
|
["5.11.0"] = 47,
|
||||||
["5.12.0"] = 48,
|
["5.12.0"] = 48,
|
||||||
|
["5.13.0"] = 49,
|
||||||
}
|
}
|
||||||
|
|
||||||
setmetatable(core.protocol_versions, {__newindex = function()
|
setmetatable(core.protocol_versions, {__newindex = function()
|
||||||
|
|
|
@ -31,6 +31,8 @@ centroid varying vec2 varTexCoord;
|
||||||
varying float exposure; // linear exposure factor, see vertex shader
|
varying float exposure; // linear exposure factor, see vertex shader
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uniform mat3 colorTransformMatrix;
|
||||||
|
|
||||||
#ifdef ENABLE_BLOOM
|
#ifdef ENABLE_BLOOM
|
||||||
|
|
||||||
vec4 applyBloom(vec4 color, vec2 uv)
|
vec4 applyBloom(vec4 color, vec2 uv)
|
||||||
|
@ -103,6 +105,12 @@ vec3 screen_space_dither(highp vec2 frag_coord) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vec4 applyColorVision(vec4 color)
|
||||||
|
{
|
||||||
|
vec3 transformedColor = colorTransformMatrix * color.rgb;
|
||||||
|
return vec4(transformedColor, color.a);
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec2 uv = varTexCoord.st;
|
vec2 uv = varTexCoord.st;
|
||||||
|
@ -133,6 +141,7 @@ void main(void)
|
||||||
color = applyBloom(color, uv);
|
color = applyBloom(color, uv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
color = applyColorVision(color);
|
||||||
|
|
||||||
color.rgb = clamp(color.rgb, vec3(0.), vec3(1.));
|
color.rgb = clamp(color.rgb, vec3(0.), vec3(1.));
|
||||||
|
|
||||||
|
|
|
@ -5810,6 +5810,8 @@ Utilities
|
||||||
remove_item_match_meta = true,
|
remove_item_match_meta = true,
|
||||||
-- The HTTP API supports the HEAD and PATCH methods (5.12.0)
|
-- The HTTP API supports the HEAD and PATCH methods (5.12.0)
|
||||||
httpfetch_additional_methods = true,
|
httpfetch_additional_methods = true,
|
||||||
|
-- Scene color can be transformed by transform matrix (5.13.0)
|
||||||
|
vision_color_transform = true,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -9048,6 +9050,20 @@ child will follow movement and rotation of that bone.
|
||||||
* Currently, bloom `intensity` and `strength_factor` affect volumetric
|
* Currently, bloom `intensity` and `strength_factor` affect volumetric
|
||||||
lighting `strength` and vice versa. This behavior is to be changed
|
lighting `strength` and vice versa. This behavior is to be changed
|
||||||
in the future, do not rely on it.
|
in the future, do not rely on it.
|
||||||
|
* `vision_effects`: is a table that controls vision effects
|
||||||
|
* `color_transform_matrix`: is a matrix with default value (identity matrix):
|
||||||
|
```lua
|
||||||
|
{ {1.0, 0.0, 0.0},
|
||||||
|
{0.0, 1.0, 0.0},
|
||||||
|
{0.0, 0.0, 1.0}}
|
||||||
|
```
|
||||||
|
* can be used for creation color blind effect, base for night vision effect etc.
|
||||||
|
```lua
|
||||||
|
-- example of night vision like transform
|
||||||
|
{ {0.0, 0.0, 0.0},
|
||||||
|
{1.0, 9.0, 1.0},
|
||||||
|
{0.0, 0.0, 0.0}}
|
||||||
|
```
|
||||||
|
|
||||||
* `get_lighting()`: returns the current state of lighting for the player.
|
* `get_lighting()`: returns the current state of lighting for the player.
|
||||||
* Result is a table with the same fields as `light_definition` in `set_lighting`.
|
* Result is a table with the same fields as `light_definition` in `set_lighting`.
|
||||||
|
|
|
@ -231,6 +231,9 @@ class GameGlobalShaderUniformSetter : public IShaderUniformSetter
|
||||||
CachedPixelShaderSetting<float>
|
CachedPixelShaderSetting<float>
|
||||||
m_volumetric_light_strength_pixel{"volumetricLightStrength"};
|
m_volumetric_light_strength_pixel{"volumetricLightStrength"};
|
||||||
|
|
||||||
|
CachedPixelShaderSetting<float, 9>
|
||||||
|
m_color_transform_matrix{"colorTransformMatrix"};
|
||||||
|
|
||||||
static constexpr std::array<const char*, 1> SETTING_CALLBACKS = {
|
static constexpr std::array<const char*, 1> SETTING_CALLBACKS = {
|
||||||
"exposure_compensation",
|
"exposure_compensation",
|
||||||
};
|
};
|
||||||
|
@ -321,6 +324,8 @@ public:
|
||||||
m_bloom_radius_pixel.set(&radius, services);
|
m_bloom_radius_pixel.set(&radius, services);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_color_transform_matrix.set(lighting.vision_effects.color_transform_matrix.data(), services);
|
||||||
|
|
||||||
float saturation = lighting.saturation;
|
float saturation = lighting.saturation;
|
||||||
m_saturation_pixel.set(&saturation, services);
|
m_saturation_pixel.set(&saturation, services);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,18 @@ struct AutoExposure
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VisionEffects
|
||||||
|
{
|
||||||
|
std::array<float, 9> color_transform_matrix;
|
||||||
|
|
||||||
|
constexpr VisionEffects()
|
||||||
|
: color_transform_matrix{
|
||||||
|
1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
/** Describes ambient light settings for a player
|
/** Describes ambient light settings for a player
|
||||||
*/
|
*/
|
||||||
struct Lighting
|
struct Lighting
|
||||||
|
@ -52,4 +64,5 @@ struct Lighting
|
||||||
float bloom_intensity {0.05f};
|
float bloom_intensity {0.05f};
|
||||||
float bloom_strength_factor {1.0f};
|
float bloom_strength_factor {1.0f};
|
||||||
float bloom_radius {1.0f};
|
float bloom_radius {1.0f};
|
||||||
|
VisionEffects vision_effects;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1794,4 +1794,9 @@ void Client::handleCommand_SetLighting(NetworkPacket *pkt)
|
||||||
>> lighting.bloom_strength_factor
|
>> lighting.bloom_strength_factor
|
||||||
>> lighting.bloom_radius;
|
>> lighting.bloom_radius;
|
||||||
}
|
}
|
||||||
|
if (pkt->getRemainingBytes() >= 36) {
|
||||||
|
for (int i = 0; i < 9; ++i) {
|
||||||
|
*pkt >> lighting.vision_effects.color_transform_matrix[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,13 @@
|
||||||
PROTOCOL VERSION 48
|
PROTOCOL VERSION 48
|
||||||
Add compression to some existing packets
|
Add compression to some existing packets
|
||||||
[scheduled bump for 5.12.0]
|
[scheduled bump for 5.12.0]
|
||||||
|
PROTOCOL VERSION 49
|
||||||
|
Add "vision_effects" to TOCLIENT_SET_LIGHTING packet
|
||||||
|
[scheduled bump for 5.13.0]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Note: Also update core.protocol_versions in builtin when bumping
|
// Note: Also update core.protocol_versions in builtin when bumping
|
||||||
const u16 LATEST_PROTOCOL_VERSION = 48;
|
const u16 LATEST_PROTOCOL_VERSION = 49;
|
||||||
|
|
||||||
// See also formspec [Version History] in doc/lua_api.md
|
// See also formspec [Version History] in doc/lua_api.md
|
||||||
const u16 FORMSPEC_API_VERSION = 9;
|
const u16 FORMSPEC_API_VERSION = 9;
|
||||||
|
|
|
@ -2694,7 +2694,39 @@ int ObjectRef::l_set_lighting(lua_State *L)
|
||||||
lighting.bloom_radius = getfloatfield_default(L, -1, "radius", lighting.bloom_radius);
|
lighting.bloom_radius = getfloatfield_default(L, -1, "radius", lighting.bloom_radius);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); // bloom
|
lua_pop(L, 1); // bloom
|
||||||
}
|
|
||||||
|
lua_getfield(L, 2, "vision_effects");
|
||||||
|
if (!lua_isnoneornil(L, -1)) {
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
throw LuaError("vision_effects is not a table");
|
||||||
|
|
||||||
|
lua_getfield(L, 3, "color_transform_matrix");
|
||||||
|
|
||||||
|
// if none or nil, keep color transform matrix unchanged
|
||||||
|
if (!lua_isnoneornil(L, -1)) {
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
throw LuaError("vision_effects.color_transform_matrix is not a table");
|
||||||
|
|
||||||
|
for (int row = 1; row <= 3; ++row) {
|
||||||
|
lua_rawgeti(L, -1, row);
|
||||||
|
if (!lua_istable(L, -1))
|
||||||
|
throw LuaError("color_transform_matrix should be in format {{a, b, c},{d, e, f},{g, a, h}}");
|
||||||
|
|
||||||
|
for (int col = 1; col <= 3; ++col) {
|
||||||
|
lua_rawgeti(L, -1, col);
|
||||||
|
if (!lua_isnumber(L, -1))
|
||||||
|
throw LuaError("color_transform_matrix should be in format {{a, b, c},{d, e, f},{g, a, h}}");
|
||||||
|
|
||||||
|
lighting.vision_effects.color_transform_matrix[(row - 1) * 3 + (col - 1)] = (float)lua_tonumber(L, -1);
|
||||||
|
lua_pop(L, 1); // Pop the value at [row][col]
|
||||||
|
}
|
||||||
|
lua_pop(L, 1); // Pop the row table
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1); // color_transform_matrix
|
||||||
|
}
|
||||||
|
lua_pop(L, 1); // vision_effects
|
||||||
|
}
|
||||||
|
|
||||||
getServer(L)->setLighting(player, lighting);
|
getServer(L)->setLighting(player, lighting);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2746,6 +2778,19 @@ int ObjectRef::l_get_lighting(lua_State *L)
|
||||||
lua_pushnumber(L, lighting.bloom_radius);
|
lua_pushnumber(L, lighting.bloom_radius);
|
||||||
lua_setfield(L, -2, "radius");
|
lua_setfield(L, -2, "radius");
|
||||||
lua_setfield(L, -2, "bloom");
|
lua_setfield(L, -2, "bloom");
|
||||||
|
lua_newtable(L); // "vision_effects"
|
||||||
|
lua_newtable(L); // "color_transform_matrix"
|
||||||
|
// Create the nested table structure {{a, b, c}, {d, e, f}, {g, h, i}}
|
||||||
|
for (int row = 0; row < 3; row++) {
|
||||||
|
lua_newtable(L); // Create inner row table
|
||||||
|
for (int col = 0; col < 3; col++) {
|
||||||
|
lua_pushnumber(L, lighting.vision_effects.color_transform_matrix[row * 3 + col]); // Push the value
|
||||||
|
lua_rawseti(L, -2, col + 1); // Set value in inner table with 1-based indexing
|
||||||
|
}
|
||||||
|
lua_rawseti(L, -2, row + 1); // Set inner table in the outer matrix table
|
||||||
|
}
|
||||||
|
lua_setfield(L, -2, "color_transform_matrix");
|
||||||
|
lua_setfield(L, -2, "vision_effects");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1953,6 +1953,10 @@ void Server::SendSetLighting(session_t peer_id, const Lighting &lighting)
|
||||||
pkt << lighting.bloom_intensity << lighting.bloom_strength_factor <<
|
pkt << lighting.bloom_intensity << lighting.bloom_strength_factor <<
|
||||||
lighting.bloom_radius;
|
lighting.bloom_radius;
|
||||||
|
|
||||||
|
for (int i = 0; i < 9; ++i) {
|
||||||
|
pkt << lighting.vision_effects.color_transform_matrix[i];
|
||||||
|
}
|
||||||
|
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue