Great video! Love this sort of technical breakdown. I mean this in a good way, you sound like the TA I wish I had in school. You're rather straightforward, clear and concise. EDIT: I am a sucker for pain, GIVE ME MORE!!!
I did basically this exact same thing a while ago but never posted it anywhere cuz I did it very sloppy lol. I feel vindicated to know somebody else came up with the same solution :) People used to do so many cool things using indexed color mode back in the day like color cycling and palette shifting but the knowledge seems to be lost to the ages.
I love watching cool palette swap/sweep animations people made!.. an old art form... haha it's a shame it's not "needed" to save so much space amymore..anymore... But... why not! Haha you are valid!
I use a shader that replaces distinct shades of gray with colors of your choosing. So instead of dealing with an index number per pixel, you deal with a shade of gray per pixel. Recoloring existing artwork is pretty easy, usually just requiring a color replace; and the fewer colors included in your sprite, the quicker it is. With this method it is very easy to color cycle, palette swap, hue shift, darken/brighten etc.
I know this is old, but to make sure that other pixels weren't being affected, you could've just used a texture map and used it to indicate the region where the pallete should be changed. I actually also worked on something similar but it doesn't use a pallete. What my shader does is use normal maps to define regions where there will be a hue shift, I then convert those pixels colors to hsv, shift the hue to whatever color is specified in the uniform, and then convert back to rgb, allowing for multiregion dying armor and etc.
I love seeing your implementation of this. Adding this method into the vault for possible ways to torture myself in the future. I am a sucker for pain, GIVE ME MORE!!!
Hi I am back with new question (with a hope that you dlnt mind) So if you don't want to separate sprite into different Pieces and if you want to add some ingame iteam like hat which a player receive on quest completion Or his hair changes when he goes in super saint stage. Then i guess would have to use different sprites...??? Or simply asking At 2:30 if you dont want to have car ears as a different sprite then how else would you add that?
Hi! I don't mind questions haha ,but forgive me if I'm quite delayed at times. So, conceptually you are still "seaparating" but instead of as colors just assigning spot on a palette. Of course if there are details that needs to be added on during the game play (like item wearing) you still would probably want that as separate sprite. However, if you have a static base sprite with lots of details you don't want to have to separate the sprites out everytime for every character. The palette manipulation allows for features like "here are primary colors of this sprite change it one way." Then separately go "let's change secondary group of colors" Best example I can think of is in 3d how you can control light and shadow color separately. Also, if you have features to "dye" clothes you can tint/change colors of the "primary" and "secondary" separately. Ie) shirt color vs buttons on a shirt.
@@drac8854 ah lol sorry... talking about this over UA-cam comment is so confusing haha wish I could just share screen and talk lol. Uhhh I was gonna try and do some live stream this month if you don't mind bringing the question there!
Could you have just given the hair a weird color that you would never want to use anywhere other than the shader code, and then modify it in the shader to the red or whatever? Learning about the internals of PNG is fun though!
Haha yea that could work. Only problem is it's such a pain to design and work on art with the color that you wouldn't be using in the game. There's some work around to it and maybe I could get used to it... but.. what if I want to outsource the art? Haha, but yea regardless I enjoyed learning png! Hope you did too!
Can you make a tutorial on accessing multiple colour material from a single shader script and how to access and change material of a foreign scene such as blend file or how to convert it to a single mesh but remaining metarials or other files accessable the same way it just normally. (Note:I know it's possible to change properties if you duplicate the nodes and use that but I don't want to do that.)
Few questions if you dont mind (IDK if these are questions or some statements) 1. I dont think its ready to use. I guess this would work on 64*64 res of png what of i have 32*32 2. How can de define how many colour we want in palate. Maybe i want to add a colour for skin. 3 how are we indexing the palate to which part of sprite it needs to change. 4. as i see in the screen plate and sprite are 1png file i cant show palate to players.
Hey! Thanks for watching! I can comment on some of these and it's harder to answer some parts but I'll try my best haha. 1. The way Sprite2D.gd calls the ong reader and generate "index image" takes the width and height from the sprite Metadata and should not care about the size. Other words, it should work for ANY size of sprite. 2. So adding more palette cannot be done in Godot, but rather the way it was meant to be used is to assign the desired palette/index while creating the sprite. Just to clarify, when png file is saved as "indexed mode" the entire sprite will be palette/index based, so any color you have in the sprite should be in the palette. 3. Yea so that's the tricky part. That is up to the creator to define. I personally am reserving certain range of palette index to specific type. For example, palette 1~5 hair primary color, 6~10 hair secondary, 11~15 skin primary.. so on Ah yes showing the palette to the player isn't part of the script, but if you wanted to I can imagine a way to implement it by creating sprite by reading palette information, but yea the example code doesn't by itself show the palettes. Easiest way to do it tho I think.. is to make a separate sprites for showing palette. I could deeper dive to do what you want it to do on later videos if you can describe what you want the code to do for you!
(idrk if its the same... but) damn, i tried making my own shader, and it just uses the colors on the texture as the base color so you never accidentally convert the new colors to another colors, with both original image and the result image seperated, i didnt have to wory about overlaps and ofc if i wanna make every part customizable i can make the shader go for the hues instead, the base sprite will have all parts seperated into different hues, so no overlaps between parts there too, and i just put the intended hues of each part in the shader by default
This is the part that I hate while making games in Godot.It's a rapid hole and I waste almost two to three years just to figure out how to make multiplayer system but ended up failing and I could just learn other stuff and progress on my others and main games on those years😢
Why do you want this as a shader? Can't you just precalculate it for the sprite once instead of making shader work every frame? And if you want a shader could you just use a second color coded image as a mask?
Hi Ezra, thx for your devlog videos ! Maybe you went a bit too far with these shaders XD ? Why not use sprites with black and white values ? Then when you use modulate, you get the exact colour you pick !
That is definitely an option! But still the problem of isolating spots in the sprite for separate customization will be there! Of course, separating the sprites would solve it, but honestly working with index/palette is so fun! There's a whole genre of palette swap based animation that does cool things while saving space!
I am a sucker for pain, GIVE ME MORE!!!
Great video! Love this sort of technical breakdown. I mean this in a good way, you sound like the TA I wish I had in school. You're rather straightforward, clear and concise.
EDIT: I am a sucker for pain, GIVE ME MORE!!!
Haha thanks! As someone who has thought about becoming an educator at one point this definitely validating and compliment!
I am a sucker for pain... Give me more!!!
Seeing more Godot tutorials makes me happy 😂
Great video! I loved the breakdown of PNG's compression algorithm, it's crazy!
Thank you!!
I did basically this exact same thing a while ago but never posted it anywhere cuz I did it very sloppy lol. I feel vindicated to know somebody else came up with the same solution :) People used to do so many cool things using indexed color mode back in the day like color cycling and palette shifting but the knowledge seems to be lost to the ages.
I love watching cool palette swap/sweep animations people made!.. an old art form... haha it's a shame it's not "needed" to save so much space amymore..anymore...
But... why not! Haha you are valid!
Dude, I love this! I'm definitely gonna use this!
Yay! Pardon the messy code. Let me know if you got any questions on it!
This video has your best editing yet!
So much editing...
Following now. Will study this on future. Thanks
This was a cool video. Very fun and informative.
Also, I almost forgot. I'm a sucker for pain, give me more!
Thanks!
I use a shader that replaces distinct shades of gray with colors of your choosing. So instead of dealing with an index number per pixel, you deal with a shade of gray per pixel. Recoloring existing artwork is pretty easy, usually just requiring a color replace; and the fewer colors included in your sprite, the quicker it is. With this method it is very easy to color cycle, palette swap, hue shift, darken/brighten etc.
That is super neat! Thanks for the info!
I know this is old, but to make sure that other pixels weren't being affected, you could've just used a texture map and used it to indicate the region where the pallete should be changed. I actually also worked on something similar but it doesn't use a pallete. What my shader does is use normal maps to define regions where there will be a hue shift, I then convert those pixels colors to hsv, shift the hue to whatever color is specified in the uniform, and then convert back to rgb, allowing for multiregion dying armor and etc.
I am a sucker for pain... Give me more!!!
Thanks. Let's see how many more Godot bugs you find.
🤞
I love seeing your implementation of this. Adding this method into the vault for possible ways to torture myself in the future.
I am a sucker for pain, GIVE ME MORE!!!
This is the way!
I am a sucker for pain... GIVE ME MORE!!!!
Hi
I am back with new question (with a hope that you dlnt mind)
So if you don't want to separate sprite into different Pieces and if you want to add some ingame iteam like hat which a player receive on quest completion
Or his hair changes when he goes in super saint stage. Then i guess would have to use different sprites...???
Or simply asking At 2:30 if you dont want to have car ears as a different sprite then how else would you add that?
Hi! I don't mind questions haha ,but forgive me if I'm quite delayed at times.
So, conceptually you are still "seaparating" but instead of as colors just assigning spot on a palette.
Of course if there are details that needs to be added on during the game play (like item wearing) you still would probably want that as separate sprite.
However, if you have a static base sprite with lots of details you don't want to have to separate the sprites out everytime for every character.
The palette manipulation allows for features like "here are primary colors of this sprite change it one way." Then separately go "let's change secondary group of colors"
Best example I can think of is in 3d how you can control light and shadow color separately.
Also, if you have features to "dye" clothes you can tint/change colors of the "primary" and "secondary" separately. Ie) shirt color vs buttons on a shirt.
@@ezthedev I wasnt talking about the colour..😅
@@drac8854 ah lol sorry... talking about this over UA-cam comment is so confusing haha wish I could just share screen and talk lol. Uhhh I was gonna try and do some live stream this month if you don't mind bringing the question there!
@@ezthedev sure sure
I am a sucker for pain, GIVE ME MORE!!!
I really hope they add a built in method for getting image color palettes for the ones that support it
You are a great teacher!
Thanks dad
I am a sucker for pain, GIVE ME MORE!!!
I am a sucker for pain... Give me more!!
Literally don't code or use Godot but I love the way you explain stuff
Lol thanks!
Could you have just given the hair a weird color that you would never want to use anywhere other than the shader code, and then modify it in the shader to the red or whatever? Learning about the internals of PNG is fun though!
Haha yea that could work. Only problem is it's such a pain to design and work on art with the color that you wouldn't be using in the game.
There's some work around to it and maybe I could get used to it... but.. what if I want to outsource the art? Haha, but yea regardless I enjoyed learning png! Hope you did too!
Thank you very much for the code!
Thanks for watching!
Can you make a tutorial on accessing multiple colour material from a single shader script and how to access and change material of a foreign scene such as blend file or how to convert it to a single mesh but remaining metarials or other files accessable the same way it just normally.
(Note:I know it's possible to change properties if you duplicate the nodes and use that but I don't want to do that.)
You know what? As long as there's someone who is interested, I'll make it! Haha let me put that in my list of todos
I am a sucker for pain, GIVE ME MORE!!!
Few questions if you dont mind
(IDK if these are questions or some statements)
1. I dont think its ready to use. I guess this would work on 64*64 res of png what of i have 32*32
2. How can de define how many colour we want in palate. Maybe i want to add a colour for skin.
3 how are we indexing the palate to which part of sprite it needs to change.
4. as i see in the screen plate and sprite are 1png file i cant show palate to players.
Hey! Thanks for watching! I can comment on some of these and it's harder to answer some parts but I'll try my best haha.
1. The way Sprite2D.gd calls the ong reader and generate "index image" takes the width and height from the sprite Metadata and should not care about the size. Other words, it should work for ANY size of sprite.
2. So adding more palette cannot be done in Godot, but rather the way it was meant to be used is to assign the desired palette/index while creating the sprite. Just to clarify, when png file is saved as "indexed mode" the entire sprite will be palette/index based, so any color you have in the sprite should be in the palette.
3. Yea so that's the tricky part. That is up to the creator to define. I personally am reserving certain range of palette index to specific type. For example, palette 1~5 hair primary color, 6~10 hair secondary, 11~15 skin primary.. so on
Ah yes showing the palette to the player isn't part of the script, but if you wanted to I can imagine a way to implement it by creating sprite by reading palette information, but yea the example code doesn't by itself show the palettes.
Easiest way to do it tho I think.. is to make a separate sprites for showing palette. I could deeper dive to do what you want it to do on later videos if you can describe what you want the code to do for you!
4:50 i used to have to read a lot of RFCs. Glad i don't have to read them as often.
haha i'm glad i don't have to read them all the time!
I am a sucker for pain… I NEED MORE
(idrk if its the same... but)
damn, i tried making my own shader, and it just uses the colors on the texture as the base color so you never accidentally convert the new colors to another colors, with both original image and the result image seperated, i didnt have to wory about overlaps
and ofc if i wanna make every part customizable i can make the shader go for the hues instead, the base sprite will have all parts seperated into different hues, so no overlaps between parts there too, and i just put the intended hues of each part in the shader by default
Haha this would certainly work and a good solution!
When you go to godot shader docs and find nothing it's still like that hehe, but if you look around enough you can eventually scrounge up the info
how to change different types of cloths,shoes,hats
This is the part that I hate while making games in Godot.It's a rapid hole and I waste almost two to three years just to figure out how to make multiplayer system but ended up failing and I could just learn other stuff and progress on my others and main games on those years😢
Haha the pain of growing with the engine! Luckily things keep improving!
Can you make a 3D version of it like changing the eye color of characters.(I want to make a game like genshin impact and scotl)
Ooo I gotta look into that next!
@@ezthedev thank you❤️
I'm a sucker for overcomplicated workflows! (and pain) GIVE ME MORE!
Why do you want this as a shader? Can't you just precalculate it for the sprite once instead of making shader work every frame? And if you want a shader could you just use a second color coded image as a mask?
Hi Ezra, thx for your devlog videos ! Maybe you went a bit too far with these shaders XD ?
Why not use sprites with black and white values ? Then when you use modulate, you get the exact colour you pick !
That is definitely an option! But still the problem of isolating spots in the sprite for separate customization will be there!
Of course, separating the sprites would solve it, but honestly working with index/palette is so fun! There's a whole genre of palette swap based animation that does cool things while saving space!
I am pain.. GIVE ME MORE!!!!
We are painnnn
No one says "ping" when reading PNG
Lol I've heard it only once!
I am a sucker for pain, give me more!!!
I feel dirty haha
Yea... it's.. you know often you gotta get a little dirty for deeper knowledge. Heh
I am a sucker for pain (and I WILL subscribe), GIVE ME MORE!
Haha thanks! I'm putting together more pain for people to enjoy haha
@ cool. Have my sub
Bro is da biggest yapper
Yappa yappa fluent I'm yappanese
Bob from chrono trigger??? hahaha
Lol
Too much code. This is really all you need.
uniform vec4 new_color: source_color;
void fragment() {
vec4 curr_color = texture(TEXTURE, UV);
if (curr_color.rba == vec3(0, 0, 1) && curr_color.g > 0.0) {
COLOR.rgb = new_color.rgb * curr_color.g;
}
}
"PNG is pronounced ping" NO NO NOOOOOOOOO
it's sinful but i've heard someone say it ... in IRL?! *shudders*
Meanwhile all of it, all of it solvable by simple color ID masks, in use by graphic artists for generations.
I am a sucker for pain, GIVE ME MORE!!!
I am a sucker for pain... Give me more!!!
I am a sucker for pain... GIVE ME MORE!!!!
I am a sucker for pain... Give me more!!!
I am a sucker for pain, GIVE ME MORE!!!