Jump to content

_koh_

Members
  • Posts

    78
  • Joined

  • Last visited

Everything posted by _koh_

  1. For sure I should do this. That's what I get when Ctrl+Shift+C in PDN right? Each layer blended in integer. A bit difficult to explain, but when a layer having opacity = 16, it's like the layer using 12bit color instead of 8, and when I use excessive parameters I can see the differences between FP blended images and INT blended images. But I agree this is "Why you even need this?" kind of thing. While I know this, I thought having them in one liners makes overall code simpler, but that's just my taste. Standard way is c' = c / 255 -> (do things) -> c = trunc(c' * 255 + 0.5) But I'm team c' = (c + 0.5) / 256 -> (do things) -> c = trunc(c' * 256) In this way, I don't need to worry about div 0 or 255 converted into infinity in the HDR color space. And if I want dithering, I can simply swap 0.5 to random noise so it's more convenient. Yeah, documents saying HLSL do this, but ComputeSharp don't have bool operators for bool vectors and have bit operators instead for whatever the reason. So if we can have the conditional operator, that's very welcome!
  2. OK this worked. Thanks! Haven't narrowed down the condition but if I uncomment that line I get this error. Do you need full stack trace? System.ArgumentException: Value does not fall within the expected range. (InteropError.InvalidArgument 0x80070057)
  3. OK I've found a solution. I think now my shader running only once. Problem is, my shader is relatively simple and HistogramEffect is basically slow, so I have no idea I'm making it faster. var cdc = deviceContext.CreateCompatibleDeviceContext(Environment.Document.Size, null, DevicePixelFormats.Prgba128Float); using (cdc.UseBeginDraw()) cdc.DrawImage(shader); var (input, output) = (shader.GetInput(0), cdc.Bitmap); return new MixEffect(deviceContext, output, Graph(func, input, output, alpha), LayerBlendMode.Normal.ToMixMode()); Another finding. HistogramEffect gives me an error if I access Properties.Bins even by reading it, so I believe something going wrong somewhere. Full source code. LightBalanceGPU.zip
  4. Couldn't resist to see how it looks so I created DrawImage() shader output to CompatibleDeviceContext version. I believe this means my shader running 4 times (output + RGB histogram) so I'm not going to use it, but at least it worked. IDeviceImage Graph(Func<Vector4, Vector4> func, IDeviceImage iimg, IDeviceImage oimg, float alpha) { var hist = (IDeviceImage img) => { using var cdc = deviceContext.CreateCompatibleDeviceContext(desiredPixelFormat: DevicePixelFormats.Prgba128Float); using var tile = new CropEffect(cdc, img, RectFloat.Intersect(new(0, 0, 4096, 4096), new(0, 0, Environment.Document.Size))); using var hist = new HistogramEffect(cdc); hist.SetInput(0, tile); var data = (ChannelSelector ch) => { hist.Properties.ChannelSelect.SetValue(ch); cdc.BeginDraw(); cdc.DrawImage(hist); cdc.EndDraw(); return hist.Properties.HistogramOutput.GetValue(); }; var o = (R: data(ChannelSelector.R), G: data(ChannelSelector.G), B: data(ChannelSelector.B)); return Enumerable.Range(0, 256).Select((i) => new Vector4(o.R[i], o.G[i], o.B[i], 0)); }; var tpnt = Enumerable.Range(0, 256).Select((i) => new Vector4(i + 0.5f)).Select((c) => (c, func(c / 256) * 256)); var ipnt = hist(iimg).Select((v, i) => (new Vector4(i), v * 8192)); var opnt = hist(oimg).Select((v, i) => (v * 8192, new Vector4(i))); var list = new (IEnumerable<(Vector4 X, Vector4 Y)>, Func<Vector4, float>, ColorRgb96Float)[] { (ipnt, (c) => c.X, new(4/8f, 0, 0)), (ipnt, (c) => c.Y, new(0, 2/8f, 0)), (ipnt, (c) => c.Z, new(0, 0, 4/8f)), (opnt, (c) => c.X, new(6/8f, 0, 0)), (opnt, (c) => c.Y, new(0, 3/8f, 0)), (opnt, (c) => c.Z, new(0, 0, 6/8f)), (tpnt, (c) => c.X, new(8/8f, 0, 0)), (tpnt, (c) => c.Y, new(0, 4/8f, 0)), (tpnt, (c) => c.Z, new(0, 0, 8/8f)), }; var graph = deviceContext.CreateCommandList(); using var _ = graph.UseBeginDraw(deviceContext); using var brush = deviceContext.CreateSolidColorBrush(new()); var scale = Math.Min(Environment.Document.Size.Width, Environment.Document.Size.Height) / 256f; deviceContext.Transform = new(scale, 0, 0, -scale, 0, Environment.Document.Size.Height); foreach (var (p, v, c) in list) { brush.Color = new(c, alpha); deviceContext.DrawCurve(p.Select((o) => new Point2Float(v(o.X), v(o.Y))).ToArray(), brush, 1.6f); } return graph; } Some findings. While built-in effects output image size information, my shader doesn't. So not to skew histogram data, I needed to crop shader output to document size to add size information. I was curious if I give 3 HistogramEffect to CompositeEffect then draw it to CDC, my shader need to run only once. But I got invalid graph error so it didn't work. This is multi pass rendering thing after all, and while GpuEffect makes multi pass rendering simpler (e.g. I can blur my rendering result), if I want to rely on D2D drawing I still need to know what to draw beforehand. So having compute shader may not change this particular case.
  5. So I can control where to write and can create "array" texture and use it as an input for following shader? That's cool. Too much things I don't know about and currently I'm fairly limited when it comes to data structure.
  6. Wow thanks a lot. That's a bit more code than I expected especially that tiling part. I currently have functional histogram in my BitmapEffect version which is done in a totally different manner, and evaluating if I can replicate this in GpuEffect. Yeah, now I totally get that. I somehow overlooked that when I coded this one. Now I'm wondering, is it possible to have input + shader output histograms on GPU?
  7. Code below is functional because I commented out the given part. I'm within a DrawingScope so I can call DrawImage() and can visualize IEnumerable<float>. Fine. protected override IDeviceImage OnCreateOutput(IDeviceContext deviceContext) { var graph = deviceContext.CreateCommandList(); using (graph.UseBeginDraw(deviceContext)) { var brush = deviceContext.CreateSolidColorBrush(new(1, 0, 0, 1)); var scale = Math.Min(Environment.Document.Size.Width, Environment.Document.Size.Height) / 256f; deviceContext.Transform = new(scale, 0, 0, -scale, 0, Environment.Document.Size.Height); deviceContext.DrawCurve(Hist().Select((v, i) => new Point2Float(i, v * 256)).ToArray(), brush, 1.6f); } return new MixEffect(deviceContext, Environment.SourceImage, graph, MixMode.CompositeSourceOver); IEnumerable<float> Hist() { var hist = new HistogramEffect(deviceContext); hist.Properties.Input.Set(Environment.SourceImage); hist.Properties.ChannelSelect.SetValue(ChannelSelector.R); //deviceContext.DrawImage(hist); //return hist.Properties.HistogramOutput.GetValue(); deviceContext.DrawImage(new EmptyEffect(deviceContext)); return Enumerable.Range(0, 256).Select((i) => i / 256f); } } But if I uncomment DrawImage(hist), I get this error. System.ArgumentException: Value does not fall within the expected range. (InteropError.InvalidArgument 0x80070057) What am I doing it wrong?
  8. Got this when I closed the app and first time this happened. pdncrash.1.log
  9. I believe whenever we average / add RGB values, we should do it in linear color space. a ^ 2.2 + b ^ 2.2 != (a + b) ^ 2.2 https://stackoverflow.com/a/13558570
  10. I want built-in Black and White adjustment to support this gamma thing coz currently it looks a bit wrong. original gamma color space B&W (built-in) linear color space B&W
  11. Another small UI glitch. You can't change amount of Exposure Adjustment by arrow buttons or arrow keys.
  12. Small UI glitch. When I switch to multi layered image by Ctrl+Tab, the last layer mouse cursor was on has "Hover highlight" and doesn't go away until I hover it again. Light blue highlight which third layer has is what I'm talking about.
  13. Tiny problems. Auto update tries to update CodeLab v6.7 to CodeLab v6.6. Theme: Auto doesn't reflect PDN setting, need to set CodeLab theme separately. PDN v5.0 build 8382 / CodeLab v6.7
  14. Just trace the edge with wide and soft eraser. It blurs the edge. https://www.getpaint.net/doc/latest/EraserTool.html You can duplicate / marge layers in Layers Window, and the normal blending layer just does fine. https://www.getpaint.net/doc/latest/LayersWindow.html
  15. Duplicate the layer instead of preserving background, rotate the foreground layer, soften the edge with width 20 hardness 0 ish eraser, then marge them. I think this is the easiest. If you still have the original image, set it as the background layer then use the eraser.
  16. Ahh, interesting. My background surface is from clipboard, so I'm doing alignment like this, ColorBgra b = aux.GetBilinearSample(x - sel.Left, y - sel.Top); and blending is a preparation so can't get rid of nested loops anyway, but I overlooked built-in functions.
  17. Thanks. What I'm actually doing is adding background to transparent images just like OP, so "How can I emulate layer blending with ColorBgra.Blend()?" was the appropriate question. Code you posted gave me the answer and now it's working. Thank you!
  18. Yeah that was my goal. I was trying to replace my normal layer blending replicating code with ColorBgra.Blend(). c.R = (b.R * b.A + a.R * (255 - b.A)) / 255; And going by ColorBgra.Blend() code, seems like this is what I needed. c = ColorBgra.Blend(a.NewAlpha(255), b.NewAlpha(255), b.A); Thanks for answering folks and Happy New Year! EDIT: I should have realized this when I saw result being 169 (170 = 255 * 2 / 3). haha
  19. That was my 2nd test Debug.WriteLine(ColorBgra.Blend(a, b, 255)); and I got this for that. B: 0, G: 0, R: 0, A: 128 So neither 128 nor 255 alpha gives me an expected result which is RGB(127, 127, 127) at least in my CodeLab. But in your code, now ColorBgra.Blend() results matching your CustomBlend() results by using 255 for alpha, right?
  20. Sorry for bumping but having the same problem. I ran this code in CodeLab void PreRender(Surface dst, Surface src) { ColorBgra a = ColorBgra.White; ColorBgra b = ColorBgra.Black.NewAlpha(128); Debug.WriteLine(ColorBgra.Blend(a, b, 0)); Debug.WriteLine(ColorBgra.Blend(a, b, 255)); Debug.WriteLine(ColorBgra.Blend(a, b, b.A)); } and got this results. B: 255, G: 255, R: 255, A: 255 B: 0, G: 0, R: 0, A: 128 B: 169, G: 169, R: 169, A: 191 No idea how ColorBgra.Blend() works.
  21. Yeah, I understand layer sampling mode behaves like that. I was trying to see how much particular layer affecting the pixel color, so using image sampling mode while toggling the layer, then found out toggling has no effect.
  22. I found a tiny bug. Tool: Color picker Sampling: Image / Single Pixel 1. Create new canvas with white background. 2. Add new layer and paint it all black. 3. Select Color picker tool beforehand. 4. Uncheck black layer in layers pane and make it invisible. 5. Use Color picker tool in image sampling mode. It picks invisible black instead of visible white. It only picks wrong color right after the visible / invisible toggle, and if I do something between the toggle and using the tool, it has no problem.
  23. Maybe not worth reporting, but when I updated from 4.3.2 yesterday, auto update stuck at "unpacking and validating"-ish phase, so I had to cancel it. I remember progress bar showing 0% while text saying 99%. Then I tried Check Now button, and this time it worked.
×
×
  • Create New...