How do I divide a sprite into colored bars using a shader?
Asked Answered
H

6

0

So I'm using a canvas item shader with the fragment function, and I'm trying to make it so that different sections of the player sprite are a different color based on each pixel's y position relative to the said player sprite (in other words, I am not trying to use each pixel's position in the world. I'm trying to divide the sprite into bars, each with their own color). This is proving more difficult for me than I expected. Here's what I have:

shader_type canvas_item;

void fragment() {
	vec4 previous_color = texture(TEXTURE, UV);
	vec4 pink = vec4(vec3(216.0/255.0, 9.0/255.0, 126.0/255.0), previous_color.a);
	vec4 purple = vec4(vec3(140.0/255.0, 87.0/255.0, 156.0/255.0), previous_color.a);
	vec4 blue = vec4(vec3(36.0/255.0, 70.0/255.0, 142.0/255.0), previous_color.a);
	
	if(UV.y >= 0.6) {
		COLOR = pink;
	}
	
}

This just results in a white rectangle. Any help would be greatly appreciated! Also idk why only the if statement gets the code block this formatting is weird

Hipster answered 19/4, 2022 at 8:55 Comment(0)
V
0
This discussion was caught in the moderation queue since you have not confirmed your account yet.
Upon creating your account you should have received an account verification email. The confirmation email may have been incorrectly flagged as spam, so please also check your spam filter. Without confirming your account, future posts may also be caught in the moderation queue. You can resend a confirmation email when you log into your account if you cannot find the first verification email.
If you need any help, please let us know! You can find ways to contact forum staff on the Contact page. Thanks! :smile:

---

@Flanito said: Also idk why only the if statement gets the code block this formatting is weird

because it is indented. I've fixed the formatting by adding ~~~ on lines before and after the code.

Vitric answered 19/4, 2022 at 8:57 Comment(0)
V
0

You could probably use the UV.y value to drive a mix() function to lerp from one color/value to another. Thats for a simple case of mixing between just 2 colors though.

For more colors than that tho, I'm drawing a blank right now but I want to say it shouldn't be too hard to actually render a rainbow gradient. Could probably google a glsl example and port that.

Vitric answered 19/4, 2022 at 9:3 Comment(0)
L
0

Oddly enough, I did a rainbow as an exercise recently. I don't know how much it will help, but here it is:

shader_type canvas_item;

vec3 hsb2rgb(vec3 c) {
	vec3 t = vec3(0.0, 4.0, 2.0);
    vec3 rgb = mod(c.x * 6.0 + t, 6.0);
    rgb = clamp(abs(rgb - 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);
}

vec4 rainbow(vec2 uv) {
	vec3 color = vec3(1.0);
	
	float x = uv.x;
	vec2 c1 = vec2(0.5, -0.2);
	vec2 c2 = vec2(0.5, 0.2);
	float r2 = 0.7 * 0.7;
	float y2 = sqrt(r2 - pow(x - c1.x, 2)) + c1.y;
	float y1 = sqrt(r2 - pow(x - c2.x, 2)) + c2.y;

	y1 = 1.0 - y1;
	y2 = 1.0 - y2;
	float hue = 1.0;
	vec3 bow = vec3(1.0);
	
	if (uv.y > y1 && uv.y < y2) 
	{
		hue = (uv.y - y2) * 0.9 / 0.4 - 0.17;
		bow.r = 0.0;
		bow.g = 0.0;
		bow.b = 0.0;
		float t1 = 1.0;
		float t2 = 1.0;
		bow = hsb2rgb(vec3(hue, t1, t2));
		color = bow;
		return vec4(color * 0.2 + bow * 0.8, 1.0);
	} else
		return vec4(0.0, 0.5, 1.0,  1.0);

	return vec4(color, 1.0);
}

void fragment() {
	COLOR = rainbow(UV);
}

Edit: Removed some useless cruft.

Logion answered 20/4, 2022 at 4:10 Comment(0)
H
0

Gradients aren't really what i need for this case. Long story short, i'm trying to use shaders to turn the character sprite into different pride flags depending on the shader, so i just need solid rectangles. my code worked perfectly for someone else, so i don't know why it's not working for mine (like i said it just makes the whole sprite one color). we're both using the same version of godot and everything.

Hipster answered 21/4, 2022 at 15:10 Comment(0)
V
0

take UV.y multiply by 10 and min/max it under/over 5, you get a half size mask.

Vitric answered 21/4, 2022 at 15:13 Comment(0)
L
0

@Flanito said: my code worked perfectly for someone else, so i don't know why it's not working for mine.

Your code works fine for me as well.

All I did was paste it into a shader in a material on a sprite (and add a few colors). Maybe you could post a minimal version of your project that has the issue?

Logion answered 22/4, 2022 at 3:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.