Sprite Color Palette Swap in Godot

Ғылым және технология

Easy, Fast and Simple palette swapping using a simple shader in Godot. Perfect for any 2D games. Could easily be used in any other engines too!
Follow me and support me, check out these links :
Support me on Patreon ► / ombarus
Join the discussion on Discord ► / discord
Twitter ► @Ombarus1
Instagram ► / ombarus1
Website ► www.ombarus.com
Email ► ombarus.dev@gmail.com
Github ► github.com/Ombarus
Music ► www.bensound.com
My name is Ombarus and I'm a programmer / game developer from Canada who moved to Japan and decided to try my own luck with game dev.

Пікірлер: 47

  • @AlfredReinoldBaudisch
    @AlfredReinoldBaudisch4 жыл бұрын

    The shader at 1:16 is mine. You are right about the fact that the approach I wrote was insanely bad, and I never used it anywhere other than that experiment (it was also my first foray into writing a Shader and I was felling super weird having to use a for inside a for to iterate EACH color of EACH sprite - really really stupid). BUT at least it worked FOR A SINGLE SPRITE and for my wall of shameful code - so it would be better if it wouldn't have worked haha - I even feel like deleting that post.

  • @AlfredReinoldBaudisch

    @AlfredReinoldBaudisch

    4 жыл бұрын

    Just finished watching the video, what a nice and straightforward approach that you came up with! Awesome, thanks for sharing.

  • @Ombarus

    @Ombarus

    4 жыл бұрын

    If you don't want to mess with the original sprite your way is the only sensible one which is why I thought I'd mention it. Still not very useful in a big project I think but it's a nice hack!

  • @AlfredReinoldBaudisch

    @AlfredReinoldBaudisch

    4 жыл бұрын

    @@Ombarus Yeah for just a few sprites, without too much work, my shader definitely is a fit, but for a game per se, it is very inefficient. I just posted your video as an answer to my Godot Answers topic :) It is good to finally find a solution to that, more than one year since I posted it.

  • @SolironBrightwoode

    @SolironBrightwoode

    3 жыл бұрын

    Bravo to you lads for acknowledging the strengths and weaknesses of your different methods. All the while without resorting to the standard flaming and jabbing. It's way to common and this conversation was refreshing.

  • @Axelloid1460
    @Axelloid146013 күн бұрын

    and this is how I finally get a shader that works on godot 4 and is actually easy to understand and implement!! Thanks Man, genius thinking here you had, saved in favorites, subscribed and liked

  • @gemininem4927
    @gemininem4927 Жыл бұрын

    In Godot 4 you need to add hints to the sampler2D so the palette isn't filtered, which will display wrong colors: uniform sampler2D palette: filter_nearest, repeat_disable;

  • @vaalalves

    @vaalalves

    Жыл бұрын

    King

  • @bagandtag4391
    @bagandtag43914 жыл бұрын

    This is genius dude. I've been using that mask thing for a very long time and I think I'm gonna try something like this the next time I need it.

  • @TetsuDeinonychus

    @TetsuDeinonychus

    3 жыл бұрын

    I'm curious about the mask thing. Namely, is the mask just a grey-scale version of the parts of the sprite you want to change? And if that's the case why not just use that as the sprite and for colors you want to keep the same, you just make them the same color on both palettes?

  • @Axelloid1460

    @Axelloid1460

    13 күн бұрын

    @@TetsuDeinonychus because as the pixel-by-pixel approach would work nice and fun with low amounts of entities (sprites), but once you have to do that with, for example, a 100 of them it's gonna to start taking it's toll either on you or your game or your pc

  • @ghaydn
    @ghaydn4 жыл бұрын

    That looks simple while you have one small picture. But with multiple objects I'd prefer to use something like hue shifting: COLOR = color.from_hsv(hue(color) + shift, saturation(color), brightness(color)). There's no such function in Godot shading language, but converting from rgb to hsv and back is quite simple and fast.

  • @TackerTacker
    @TackerTacker4 жыл бұрын

    That's so awesome, thank you!

  • @arthigo
    @arthigo4 жыл бұрын

    I use black and white textures and modulate the color. To get the bright spots back I use a little bloom.

  • @karzheenn1995
    @karzheenn19954 жыл бұрын

    Thanks for another great video.)

  • @bfvanish
    @bfvanish3 жыл бұрын

    Great! Thanks for sharing

  • @CaptainCarrotzz
    @CaptainCarrotzz Жыл бұрын

    Very useful. Thanks.

  • @kingzeeb319
    @kingzeeb3193 жыл бұрын

    Dude, 1,6k views for such an awesome solution? Well, if nothing else your stuff is on point.

  • @ieatsoap6389
    @ieatsoap6389 Жыл бұрын

    I really had a hard time understanding because my English comprehension sucks but I think I get the gist of it, thanks!.

  • @will7466
    @will7466Күн бұрын

    Genius

  • @EvilNickolas
    @EvilNickolas4 жыл бұрын

    Im just gonna throw this out there, you dont need to use colors as colors. RGBA gives you 4x8bits or 32bits to use any way you want. you could simply use one byte as an index to your pallet - the math would then simply be collumn is the index divided by width of the pallet (rounded down) and row would be the remainder a system ive seen in used in the past was. Red channel = brightness / grey scale of image green channel = pallet index blue channel = bitwize flags for effects (emmisive, mix modes, skip - etc) alpga chanel = for alpha

  • @jeffvenancius
    @jeffvenancius4 жыл бұрын

    I've done this by using a Gradient Mapping shader. It works too, but with that one I believe you could make animations - I mean, like they used to do, you know? You can do that with the Grad too, but you have some limitations, whick makes hard to put, let's say, different frames on the same place.

  • @Gramini
    @Gramini2 жыл бұрын

    I'm doing a project where I want users to be able to supply custom graphics which should use a palette. This approach is great, but doesn't seem very end-user friendly though. But I'll keep it in mind. Thanks.

  • @MiccDev
    @MiccDev Жыл бұрын

    Is there a way to do this for the blue channel as well?

  • @jlewwis1995
    @jlewwis19954 жыл бұрын

    A few months ago I made a palette mapping shader that supports swapping using 1D palettes instead of 2D, here is the code for that, for the few test images I used with it it seemed to work well though im not that experienced with shaders still so there may be some subtle bugs :) shader_type spatial; uniform sampler2D baseimage; uniform sampler2D palette; uniform uint current_palette; uniform uint number_of_palettes; void fragment() { vec4 base = texture(baseimage, UV); float index = base.r; vec4 color = texture(palette, vec2(index, float(current_palette) * (1.0 / float(number_of_palettes)))); ALBEDO = color.rgb; ALPHA = color.a; }

  • @madperson1996
    @madperson1996 Жыл бұрын

    I really don't understand that part (6:10), the green component is the V and the red component is the U, what that means? the first color is rgb(0, 0, 0) the second color is rgb(85, 0, 0), but how the third color is pink ? how do u get pink just changing the Red and Green channel?

  • @Ombarus

    @Ombarus

    Жыл бұрын

    U & V refer to the Horizontal and Vertical coordinate of the pixels in a texture. In my case I use the color of the sprite as a coordinate into my actual color texture.

  • @AgentNos
    @AgentNos4 жыл бұрын

    Out of curiosity, how would you go about making this in shader graph? I understand its probably a lot simpler in code, but im trying to expand my knowledge of visual stuff too. I had a mess about to try to come up with something but i couldn't get my head around it properly

  • @chimeforest

    @chimeforest

    3 жыл бұрын

    Something like this should work: i.imgur.com/MImZ8GT.png

  • @janmagtoast
    @janmagtoast3 жыл бұрын

    gradiant mapping would also work

  • @OhLookNoNumbers
    @OhLookNoNumbers3 жыл бұрын

    I've been following along with the tutorial and everything's mostly working, but at 7:39 where you're updating the object's palette in code I'm running into problems. It wants a .stex file rather than a .png for the texture. I can get a path to the associated .stex file for my .png from the editor, but it's in a hidden folder and has a long string of random letters and numbers on the end, indicating to me that these files aren't meant for use and may be temporary or subject to change at Godot's whims. So while it's working currently I suspect I'm doing something wrong. Is there a better way to locate or recreate a .stex file in code?

  • @Ombarus

    @Ombarus

    3 жыл бұрын

    the .stex file is the internal, imported and transformed texture that Godot uses. You should be able to use something like : "res:\\my_image.png" in the load() method. You shouldn't need to access the .stex file.

  • @OhLookNoNumbers

    @OhLookNoNumbers

    3 жыл бұрын

    @@Ombarus I found out what my problem was. I'm using C# instead of GDScript and I'd used the wrong load function. I had tried using Load() before when following the tutorial, but in C# it's GD.Load(). So I went on a wild goose chase trying other loading methods while the solution was staring me in the face.

  • @Gumpa2
    @Gumpa224 күн бұрын

    So what if I want to recolor non-Pixel Graphics? For example a plain old image from Photoshop, just normal painted shading, and I would love to have the "cntrl+u" hue slider in Godot. How could I do that? I try to build a kind of Character Editor at the moment, and currently all my assets are just grey, but I further down I would love to paint them properly and then the modify wont work correctly, as it will screw up the shading. Any suggestions?

  • @Ombarus

    @Ombarus

    23 күн бұрын

    If you want a smooth shading you might be better with a HSV shader (Hue-Saturation-Value). Something like this maybe (not my own) godotshaders.com/shader/hsv-adjustment/

  • @Gumpa2

    @Gumpa2

    23 күн бұрын

    @@Ombarus Thank you very much for your fast reply! I tried one hue shader that a friend send me, who knows the program better than I. That is already working good. :) So witht he other values it will be even more useful. Do I have to unserstand the lines that are in the shaders, or do I just copy and roll with it? I personally have barely any programming experience outside of BlueJ which was a decade ago in School. So I know there are full courses on Godot, but atm I have to figure out one by one what I actually need for my current Idea. I want do create a dragon-Character editer, and so Far I've only doen the sprites in Grey, as I didn't know if I were to color them, to easily change the tone. But with the HSV I can just adjust it like in Photoshop, without the need to do one sprite per color, which will make just a huge hazzle to implement. Its sad that there are no more personal messages on KZread, I only saw your reply by chance, as I had the video still open. If its ok, and I have another question, could I reach out to you via mail or something, when Iam getting into trouble with the programm? I want to have that project finished due to the exhibition on 25th, and want to spend most time on illustrating, so I tried to get all programming-difficulties out of the way beforehand :) I'll try the whole HSV shader later today. I also want a simply UI for the Character Editor, like triangles back and forth for the different assets, and a middle button to flick through 6-10 colours or so, but maybe a little palette would be cool, too, but I don't want the UI to get to overboarding, like in many other dressup games.

  • @toffeeFairy
    @toffeeFairy2 жыл бұрын

    Btw it's really simple to create a script in $yourLang to iterate over all images and apply those things. If you have a large collection of sprites, as godot isnt that good with sprite sheets

  • @TetsuDeinonychus
    @TetsuDeinonychus3 жыл бұрын

    Doesn't work for me. I keep getting "error (8): Unknown identifier in expression: veg4"

  • @Avenlith

    @Avenlith

    3 жыл бұрын

    vec4?

  • @TetsuDeinonychus

    @TetsuDeinonychus

    3 жыл бұрын

    @@Avenlith I might have meant to type "vec4", but I found one that works for me anyway.

  • @ghaydn
    @ghaydn4 жыл бұрын

    I accidently found this: kzread.info/dash/bejne/hqJsj9iIqcydgbw.html - looks similar to your palette swap but works different.

  • @toffeeFairy
    @toffeeFairy2 жыл бұрын

    This is awesome, 20000x better than creating stupid masks

  • @futublock
    @futublock Жыл бұрын

    bueno, pero no tienes que contar tu vida, solo como se hace

  • @guybashan9897
    @guybashan98974 жыл бұрын

    Why not just ask your graphics creator to make few versions of the sun in different colors?

  • @Ombarus

    @Ombarus

    4 жыл бұрын

    A few reason. I pay my artist per sprite which would be expensive if I want 10 different suns. Also, my sun is 384x384 pixels. So it's much lighter to load 10 4x4 texture palettes than 10 384x384 pixels sprites. Plus now adding or tweaking the colors is very easy.

  • @guybashan9897

    @guybashan9897

    4 жыл бұрын

    @@Ombarus your graphics creator will work about 5 more minutes on the colors. Since most of the work will be to create the first sun.. Probably he/she will know to better choose the best colors for the different suns. Regarding the weight: unless you want handreds of suns it should be neglible. At the worst case will add few hundreds of KBs to your game..

Келесі