Closed juanpaexpedite closed 7 years ago
I think the strategy might not be to adjust anything about the gradient itself, but to use a DiscreteTransferEffect. The discrete transfer effect will allow you to "bucket"-ize the intensities of colors into a number of "buckets" of your choosing.
There's a screenshot of this effect on the Direct2D help page.
Really interesting, I've just tested that with the following result:
CanvasCommandList cl = new CanvasCommandList(session.Device);
using (CanvasDrawingSession clds = cl.CreateDrawingSession())
{
clds.FillGeometry(geometry2, pen, opacityBrush);
}
DiscreteTransferEffect effect = new DiscreteTransferEffect();
float[] table = { 0.0f, 0.5f, 1.0f };
effect.GreenTable = table;
effect.RedTable = table;
effect.BlueTable = table;
effect.Source = cl;
session.DrawImage(effect);
May I have to use different values in the table?
Anyway thank you I'll investigate examples about that...
Afraid I am not following what you are trying to do. What is the difference between your first and second images, other than the obvious low resolution of the second?
I think it is clear in the third image, using the DiscreteTransferEffect appear 4 colors for the gradient. That is exactly what I want but with the right values according to the gradient colors ramp.
How should I adapt the values to follow the color ramp?
Thank you.
Yeah, thinking about it- a drawback of using DiscreteTransferEffect is that while you'll get the banding, it won't honor your exact source colors.
What about if you add more stops? For example, if you wanted just red-green-blue,
CanvasGradientStop[] gradientStops = new CanvasGradientStop[6];
gradientStops[0].Color = Colors.Red;
gradientStops[0].Position = 0;
gradientStops[1].Color = Colors.Red;
gradientStops[1].Position = 0.33f;
gradientStops[2].Color = Colors.Green;
gradientStops[2].Position = 0.33f;
gradientStops[3].Color = Colors.Green;
gradientStops[3].Position = 0.66f;
gradientStops[4].Color = Colors.Blue;
gradientStops[4].Position = 0.66f;
gradientStops[5].Color = Colors.Blue;
gradientStops[5].Position = 1.0f;
Yes, It is what I thought in first instance. Create a Method that gives me the color for the band position and then create an stepped gradient like you shown.
Let's see how I figure out the band extraction. Anyway thank you now I will see all the effects to see what can I add to the tool app I am developing!
Definitely, you could try something like
CanvasGradientStop[] CreateBandedStops(Color color1, Color color2, int numberOfSteps)
{
CanvasGradientStop[] gradientStops = new CanvasGradientStop[numberOfSteps * 2];
float increment = 1.0f / (float)(numberOfSteps);
float colorIncrementCount = numberOfSteps - 1;
float redIncrement = ((float)color2.R - (float)color1.R) / colorIncrementCount;
float greenIncrement = ((float)color2.G - (float)color1.G) / colorIncrementCount;
float blueIncrement = ((float)color2.B - (float)color1.B) / colorIncrementCount;
float red = color1.R;
float green = color1.G;
float blue = color1.B;
float position = 0;
int index = 0;
while (index < gradientStops.Length)
{
Color currentColor = Color.FromArgb(255, (byte)red, (byte)green, (byte)blue);
gradientStops[index].Color = currentColor;
gradientStops[index].Position = position;
index++;
position += increment;
gradientStops[index].Color = currentColor;
gradientStops[index].Position = position;
index++;
red += redIncrement;
green += greenIncrement;
blue += blueIncrement;
}
return gradientStops;
}
If this is helpful, then I'll close the issue for now, but definitely feel free to re-open if there's anything else you need.
Yes I understand the idea, (it was a bit late around here).This morning I remembered my first shader and I start to look a solution using a shader because the colors might be multiple, the stops are not really equally separated and finally with easy code I found the following solution:
D2D_PS_ENTRY(D2D_ENTRY)
{
float4 color = D2DGetInput(0);
int levels = floor(Levels);
color.rgb *= levels;
color.rgb = floor(color.rgb);
color.rgb /= levels;
color.rgb *= color.a;
return color;
}
Pretty cool. I tested it with 32 levels. It might be possible to make it more perfect (I appreciate any advices) but at the moment is the most I get about bands.
Now I have found a way to make it work with dithering like the following:
I am not an expert neither in shaders nor dithering so that's the most accurate shader I was able to create. Let's see if in the future I take it with more patience.
Thank you.
Great, it looks like you were able to get the kind of gradient banding that you want. Gradient banding isn't exposed directly in D2D and therefore it is not exposed in Win2D, but the foundation blocks are there.
Ah I love the dithering, it reminds me of old DOS games. What makes a good dithering technique is highly dependent on the content you're trying to apply gradients to- there are choices in how many bands you want, the palletization method, type of dither pattern, etc. It looks like you found something that works well for your purposes.
I've successfully parsed the linked gradients from Inkscape to Win2D. This question is a bit difficult to explain, so suppose we have the following green gradient:
I would like to achieve a gradient with for instance 10 stop colors values to have an effect like the following (do not mind the resolution):
At the moment the only solution I think it is possible is do by hand recreating the gradient with 10 stops and adjusting the stops by hand, but before doing that, It is possible a better way?
I know it is not relevant for the library but in case it is possible I have not realize how to do that. Thank you!