Godot: Include functions for converting to and from hsb in shaders

Created on 16 May 2018  路  7Comments  路  Source: godotengine/godot

Godot version:
3.0.2 stable official

OS/device including version:
Windows 10

I think it would be super handy to have functions to go to and from hsb vectors as built in functions in the shader language. Like the following (from book of shaders):

// From https://thebookofshaders.com/06/
vec3 rgb2hsb(vec3 c){
    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 hsb2rgb(vec3 c){
    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
                    6.0)-3.0)-1.0,
                    0.0,
                    1.0 );
    rgb = rgb*rgb*(3.0-2.0*rgb);
    return c.z * mix(vec3(1.0), rgb, c.y);
}

It would allow really easy hue-shift shaders, like this one I just made:

shader_type canvas_item;

// How much you want to shift the hue by
uniform float shift_amount : hint_range(0, 1);

void fragment() {
    // Get color from the sprite texture at the current pixel we are rendering
    vec4 original_color = texture(TEXTURE, UV);
    vec3 col = original_color.rgb;
    // If not greyscale
    if(col[0] != col[1] || col[1] != col[2]) {
        vec3 hsb = rgb2hsb(col);
        // Shift the color by shift_amount, but rolling over the value goes over 1
        hsb.x = mod(hsb.x + shift_amount, 1.0);
        col = hsb2rgb(hsb);
    }
    COLOR = vec4(col.rgb, original_color.a);
}

Thoughts?

archived feature proposal rendering

Most helpful comment

@bojidar-bg It is already existing in visual shaders )

All 7 comments

It's pretty easy to google for one of these. Don't know why they'd need a built-in except for convenience when you're creating a lot of shaders. It might be easier to have imports for inlining functions you've already written and are planning to reuse throughout your project.

Another use case would be to randomize between certain saturation and brightness values, you could set the shader params with a script and easily convert them to rgb without any extra work.

Though there's no other built in functions for converting (CYMK or LAB), so I can see why these might not be included by default. How would you go about importing functions? That would be super handy, because I do plan on using the functions in more than one shader.

There is a PR for adding #include and #ifdef support: https://github.com/godotengine/godot/pull/17797

I think that would be a better alternative to this request!

#26164 adds such functionality to VisualShaders. (Nevermind, see below)

@bojidar-bg It is already existing in visual shaders )

Feature and improvement proposals for the Godot Engine are now being discussed and reviewed in a dedicated Godot Improvement Proposals (GIP) (godotengine/godot-proposals) issue tracker. The GIP tracker has a detailed issue template designed so that proposals include all the relevant information to start a productive discussion and help the community assess the validity of the proposal for the engine.

The main (godotengine/godot) tracker is now solely dedicated to bug reports and Pull Requests, enabling contributors to have a better focus on bug fixing work. Therefore, we are now closing all older feature proposals on the main issue tracker.

If you are interested in this feature proposal, please open a new proposal on the GIP tracker following the given issue template (after checking that it doesn't exist already). Be sure to reference this closed issue if it includes any relevant discussion (which you are also encouraged to summarize in the new proposal). Thanks in advance!

Was this page helpful?
0 / 5 - 0 ratings