Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: left to right gradient #4

Open
mikrosk opened this issue Nov 15, 2022 · 16 comments
Open

Feature request: left to right gradient #4

mikrosk opened this issue Nov 15, 2022 · 16 comments

Comments

@mikrosk
Copy link

mikrosk commented Nov 15, 2022

Not sure whether this is something you'd be interested in but for vertical gradients I'm using this: https://gecdesigns.com/color-gradient-generator ... and while it works, it can't be compared with the features offered by your tool! :)

@grahambates
Copy link
Owner

I could add an option to the PNG output format to save in different orientations and potentially offer different preview modes in the editor. Is this what you had in mind?

@mikrosk
Copy link
Author

mikrosk commented Nov 16, 2022

Yes, that would be sufficient. I realize that storing it as asm output would be a bit more difficult (because you are not writing palette values anymore but real pixels) so I'm totally fine with a bitmap output only for such cases.

grahambates added a commit that referenced this issue Nov 16, 2022
@grahambates
Copy link
Owner

I've added a horizontal option to the PNG output mode:

image

Changing the editor display too would be bit more complex as I'd need to redo the dragging behaviour. Is this something that's important to you?

@mikrosk
Copy link
Author

mikrosk commented Nov 16, 2022

Wow, that was fast. I doesn't need it to be rotated, not at all.

However I have noticed one thing which was perhaps not that important for the horizontal version: differentiating between resolution and the number of steps.

The horizontal version is basically built around the idea that you can change the colour on every scanline (or every second scanline etc) from an unlimited number of colours (limited only by the palette).

However the vertical version doesn't have this luxury: if I want to create a vertical gradient, I must write pixels there. So now, if I want to create a gradient with 16 steps, I get... a 16-column image. It would be cool if one could specify the amount of pixels to write these steps into (maybe even for the horizontal version?) so one can say "hey, I want 16 colours/shades distributed over 320 pixels".

Is it asking too much? ;-)

EDIT: it's totally ok to do this only for the PNG export.

@grahambates
Copy link
Owner

Ok so we're talking about limiting the gradient to a distinct number of palette entries, regardless of steps. This would be really useful but I'll need to think about the best way to implement it. It needs to go in further up the chain when it's calculating the hex values, taking into account dithering, colour models etc. rather than just being part of the output module.

I would really like to implement this though so leave it with me!

@mikrosk
Copy link
Author

mikrosk commented Nov 16, 2022

Frankly, I could even work around it in my code: all it takes is to have an integral multiplier of the final value. So for instance I generate 16 vertical steps (i.e. using 16 colours), save it as 16xN PNG and every 320/16 = 20th step I just fill the same colour for 16 the next pixels.

But you are right, if you want to do this nicely (especially with the dithering in play), this has to be calculated on a higher level, too.

@grahambates
Copy link
Owner

Another thing to consider is that currently this tool only does one dimensional dithering, given that the expected output format was a single array of colour values. When we look at bitmap output formats this opens up the scope to 2D dither patterns such as bayer or Floyd Steinberg that repeat over multiple lines. This changes the scope of this tool a bit, but I'll think about whether there's a good way to incorporate this.

@mikrosk
Copy link
Author

mikrosk commented Nov 16, 2022

You could also think about stuff like two dimensional gradients :) But if we stay with the initial requirements (one line / one column gradient), I think you don't have to worry about 2D dithering at all.

@grahambates
Copy link
Owner

Yeah the simple option would be to just add a 'scale' option to the PNG output that just repeats pixels as you described. I'd like to have a go at implementing the more 'correct' solution though :-)

@mikrosk
Copy link
Author

mikrosk commented Mar 4, 2023

Hey, any updates on this?

@grahambates
Copy link
Owner

Sorry, I started this and completely forgot about it! I'll pick it up again this week.

@grahambates
Copy link
Owner

I've got a working implementation of the limited palette option we discussed. It's available in a dev build on https://gradient-blaster-4kf2vtxta-grahambates.vercel.app

There are a couple of bugs to iron out, but it would be good to check if this meets you use case. To use it, enable the 'palette size' option and set the desired number of colours:

image

@mikrosk
Copy link
Author

mikrosk commented Mar 10, 2023

Maybe I'm not using it correctly but it produces odd results for me.

For instance, why is palette size = 16 and steps = 16 producing just one color?

Also, why palette size = 16 and steps = 320 (i.e. an integer result of 320/16 division) produces an irregular gradient? (even without dithering). For instance this one: https://gradient-blaster-4kf2vtxta-grahambates.vercel.app/?points=ffff00@0,0000ff@319&steps=320&blendMode=oklab&ditherMode=off&target=atariFalcon24 (set palette size to 16 afterwards) ... shouldn't it look more symmetric?

@grahambates
Copy link
Owner

Yeah so one of the bugs I'm looking at is that it doesn't work correctly on small ranges.

For your second example, the irregular nature is due to the way that the blending and colour proximity algorithms are based on perceptual distance, rather than linear RGB values. Basically the initial blending to create the gradient usually happens in a non-RGB colour space (e.g. OKLAB by default) to give a visually correct transition rather than even RGB steps. Then the palette reducing algorithm finds the best X colours (e.g. 16) to represent that gradient. This also takes into account the way the eye perceives colour rather than just the difference in RGB values.

Hope this explains the reasoning. I'm going to keep working on resolving the remaining bugs and tweaking parameters to get better results.

@mikrosk
Copy link
Author

mikrosk commented Mar 10, 2023

Yes, that reasoning sounds good, no objections from me. However if I were after the "raw steps" in RGB space, is there a way to achieve it? I tried to switch between different colour spaces but all of them gave me this irregular steps. That would be a nice feature IMHO.

@grahambates
Copy link
Owner

Changing 'Simple RGB' will do it for the first step i.e. the original gradient will be linear, but the palette reduction will still be perceptual. I'd need to add different modes for that too. I'll look into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants