New "ColorSwap" Post Processing Effect

As Roblox developers, it is currently impossible to swap colors individually on a post-processing level, and we need to resort to changing colors of actual parts or their textures, or changing the color globally via other post-processing effects, affecting every other color as well.

This is problematic in cases where we only want to swap certain colors of objects, without affecting other of their colors. Doing this on a post-processing level would remove the need to spend time and resources on adjusting every single color of every object in the game.


What we can do


Consider the below setup, with default colors, without any effects applied:

Now, below I included currently available options for post-processing level color adjustment.

Inverted Saturation:

Inverted Contrast:

Tint adjustment:
colorcorrect

Of course, these can be mixed together at different levels to achieve a unique set of “swapped colors”. The problem is—none of these options allow for individual color adjustment and instead they’re adjusting all colors the same way. Not to mention—using them that way has very little benefits.


What we can’t do


Let’s look at the setup again, with default colors:

Imagine I wanted to replace colors blue, red and green with white, blue, and orange respectively like so:


This is currently impossible without recoloring objects or retexturing them (assuming they use a texture).

Ok, but this is still just swapping colors for the sake of it, maybe for artistic expression.

What about swapping colors to support colorblindness of different kinds?

Below are representations of what colorblind people would see, without any swapped colors that would make it easier to differentiate them.

Deuteranomaly:

Deuteranopia:

Protanomaly:

Protanopia:

Tritanomaly:

Tritanopia:



Some colors get blended together, but color-swapping would help improve this.

If Roblox made it possible to adjust how the color of each pixel is rendered via a post-processing effect, it would allow us to make our experiences more accessible to those affected by colorblindness.


How it could work

The post-processing effect in question could work on the basis of a ColorSequence, used for example in Beam effects:
image

Adjusting the color spectrum via a similar interface would be very easy for developers to work with.
Also, it could potentially allow players themselves to adjust the spectrum to their needs.

35 Likes

before this gets pushed down as, “we can’t do it,” heres a proof of concept fragment shader:

// @venv
// This shader has been created in Godot Engine with their GDShader language.
// However, the syntax is similar to GLSL, so it's easy to port.

shader_type canvas_item;
uniform sampler2D screen : hint_screen_texture; // Screen Texture
uniform sampler2D color_swap_texture; // Colour Swap 1D Texture
vec3 rgb2hsv(vec3 c)
{
	// https://gist.github.com/983/e170a24ae8eba2cd174f
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));

    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

vec3 hsv2rgb(vec3 c)
{
	// https://gist.github.com/983/e170a24ae8eba2cd174f
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void fragment() {
	vec3 colour = texture(screen,SCREEN_UV).rgb; // Current frag colour.
	vec3 hsv_colour = rgb2hsv(colour);
	vec3 result_colour = texture(color_swap_texture,vec2(hsv_colour.r,0)).rgb; // Look up the swapped colour using the hues 0-360, which can be converted into UV values pretty easily
	result_colour = rgb2hsv(result_colour);
	result_colour.gb *= hsv_colour.gb;
	result_colour = hsv2rgb(result_colour);
	COLOR.rgb = result_colour;
}

the ColorSequence would instead be a 1D texture


10 Likes

I don’t know where you’ve gotten this idea that their main concern is implementation from, but I cannot remember a single time where they’ve turned something down because they have no idea how to do it.

1 Like

this post processing effect is very situational and wouldn’t see much use, I think a better use of time would be a way for us to make our own shaders or post processing effects using something like Godot’s GDShader language.

Well that’s assuming shaders like this can run on extremely low hardware and not destroy performance. As we all know roblox doesn’t like to drop support for devices that can’t even run roblox anyway.

Given the nature of how Roblox implemented other post-processing effects, I find it unlikely they’ll give us control like that, due to reasons you mentioned in the second part of your post.
A separate effect like the one I described seems to fit with how Roblox does things the most.

Also, I don’t see how this feature would be “very situational and wouldn’t see much use”.
It would allow colorblind accessibility (as one primary use case), and that could be used across all existing games to make them more accessible. So even if it’d be the sole purpose of this feature (and it would not), that purpose is—in my opinion—quite important to warrant adding a feature like that.

4 Likes

Its a real shame because a lot of these features are really not that hard to implement. Your feature being one of the MANY.

Realistically all this should take is:

  • Create a new class in C++ that derives from PostEffect
  • Add the necessary HLSL shader (afaik Roblox writes all shaders in HLSL, they are just translated to different languages.)

This applies to many MANY more feature requests which seem to just fly under the radar a lot. Especially graphically related features.

7 Likes

I suppose I never thought of using it for colorblind accessibility, that’s a good point :eyes:

I still think letting us to make our own shaders is a way better option than adding more post processing instances (assuming we get more of course) I could see it getting cluttered fast if many were to be added.

2 Likes

this post processing effect is very situational and wouldn’t see much use

This can be used for in-game photography, cinematic effects, toon graphics, and as mentioned, for people who are colour-blind

our own shaders

It isn’t easy getting custom shaders to run on consoles. That’s what I heard and is why it’s not a thing as of now

So the solution is to have prebuilt post-fx… which for some reason is neglected. Like the last time we’ve gotten one was the Depth Of Field effect from 2020, while others are almost a decade old

Like at this point who knows anymore

Well that’s assuming shaders like this can run on extremely low hardware and not destroy performance. As we all know roblox doesn’t like to drop support for devices that can’t even run roblox anyway.

This isn’t expensive to run and works on my shitty phone


https://no-venv.github.io/shader_demos/hsv_correction/export/New%20Game%20Project.html

2 Likes

Actually I remember a roblox staff replying to a feature request where we could turn billinear rendering to nearest neighbor dot.

1 Like

Honestly, it’s pretty unlikely that this’ll get added at least within the next 5 years which is when we get our free 1 post processing effect but I really hope that once they’re finished with some of the stuff on the roadmap they’ll get to adding more in the future because right now the post processing effects we have aren’t very satisfying to have on your game as they make very minimal amount of changes to how the game looks.

1 Like

Would be extremely useful, support