-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add ability to transform scene color in shaders. #16260
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
base: master
Are you sure you want to change the base?
Conversation
4649e9f to
748ff70
Compare
|
Maybe, it will be better to add a new player method |
appgurueu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I think this is fine in set_lighting, though it may feel like a minor misnomer. Maybe we should have [sg]et_visual_effects, of which lighting would just be a part?
doc/lua_api.md
Outdated
| in the future, do not rely on it. | ||
| * `vision_effects`: is a table that controls vision effects | ||
| * `color_transform`: boolean value enable/disable vision color transform. | ||
| * `color_transform_matrix`: is a array of 9 float values represents 3x3 matrix used to transform color in scene. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs to be more precise. What I imagine given this description is something like:
{
a, b, c,
d, e, f,
g, h, i,
}but this also does not seem to match the code, which expects
{
{a, b, c},
{d, e, f},
{g, h, i},
}Personally I would prefer the first format (the second may be more convenient if you have rows lying around, but you might as well concatenate them).
Either way from this documentation it is unclear whether this is a matrix that deals with row or column vectors. In other words, what is the image of red = (1, 0, 0)? Is it the first row or the first column?
As said, an example would help here (but this should also be stated explicitly).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this is not adressed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer the version with vectors, because it nicely separates constants for each color.
019ec52 to
0fe53a3
Compare
Yes, something like make lighting part of So when something like horizontal/vertical scene flip will be added as a vision effect or something like that, it will be under one table. |
|
Can/should we retrofit the saturation setting into this? |
|
@lhofhansl |
|
|
||
| color = applyColorVision(color); | ||
|
|
||
| color.rgb = clamp(color.rgb, vec3(0.), vec3(1.)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clamping the values in [0,1] often causes hue distortions, see for example https://bottosson.github.io/posts/gamutclipping/
I think with gamut clipping in a perceptual colour space, e.g. OKLab, the clipped result would be much more similar to how it would look like if it clamping was not needed.
Even a simple clamp in YCbCr may look better than clamping in RGB, but I haven't thoroughly tested it:
// RGB to YCbCr, ranges [0, 1]
vec3 rgb_to_ycbcr(vec3 rgb) {
float y = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;
float cb = (rgb.b - y) * 0.565;
float cr = (rgb.r - y) * 0.713;
return vec3(y, cb, cr);
}
// YCbCr to RGB
vec3 ycbcr_to_rgb(vec3 yuv) {
return vec3(
yuv.x + 1.403 * yuv.z,
yuv.x - 0.344 * yuv.y - 0.714 * yuv.z,
yuv.x + 1.770 * yuv.y
);
}
// Clamp the saturation in YCbCr before a clamp in RGB for a better chroma
// preservation
vec3 clamp_saturation(vec3 color)
{
vec3 yuv = rgb_to_ycbcr(color.rgb);
yuv.yz = clamp(yuv.yz, vec2(-0.5), vec2(0.5));
return ycbcr_to_rgb(yuv);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With certain matrices, hue distortions are currently very noticeable.
/lua local t={1,0,8} me:set_lighting({color_transform_matrix = {t,t,t}})
Pull Request (commit e6b59de):

With clamp_saturation() applied:

Other examples with noticeable distortion (values for t in the above command): {1,4,0}, {1,2,0}, {3,8,1.5}
In my opinion it looks better with clamp_saturation(). As far as I know, if light of any colour reaches the human eye and is too bright for the cone cells, the human usually perceives it as white light.
This discussion could be related: w3c/csswg-drafts#10579
|
|
||
| * Work as `transformed_color_RGB = color_transform_matrix * color_RGB` | ||
| * Can be used for creation color blind effect, base for night vision effect etc. | ||
| * Request client with protocol version 49 or higger. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the documentation mention that the matrix is applied before the saturation and tone mapping?
And should it mention the behaviour with out-of-bounds colours and if this behaviour is subject to change?
| } | ||
| #endif | ||
|
|
||
| vec4 applyColorVision(vec4 color) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the meaning of "vision" in the function name applyColorVision?
Can these two lines be inlined into main()?
41f1804 to
e6b59de
Compare
| {0.0, 0.0, 1.0}} -- b | ||
| ``` | ||
|
|
||
| * Work as `transformed_color_RGB = color_transform_matrix * color_RGB` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it currently behaves like transformed_color_RGB = color_transform_matrix^T * color_RGB
|
A more general solution would be to support color lookup tables (LUT) supported by engines such as Unreal Engine. It is simply a texture (256×16 in Unreal) which is indexed by the RGB components of colors and maps them to a different color. Considering that can be used for the same things but also lots of other effects it may be worth considering as an alternative. I am pretty sure what you can do with a 3×3 matrix is very limited by comparison. |
|
Yes, color lookup tables sound like a more flexible solution. |


Add a color transform matrix to shaders, which can be used to transform scene color.
Allows modders to apply custom color transformation matrices for visual effects such as color blindness simulation and night vision.
player:set_lightingmethod table now reads tablevision_effects. See more in the doc.It should help with the possibility of implementing Feature Request: Night Vision. #6509.
To do
This PR is Ready for Review.
How to test
Get
serverprivilege and use the commandplayer_editor lightingto changevision_effects.