Page 2 of 4
Re: Gaussian blur in real time?
Posted: Mon Oct 14, 2019 7:51 am
by Mijikai
I just messed around maybe its useful somehow
example 1:
example 2:
Code (whats needed):
Code: Select all
Structure RGBA_STRUCT
code.l
EndStructure
Global *p1.RGBA_STRUCT
Global *p2.RGBA_STRUCT
Global *p3.RGBA_STRUCT
;Coordinates:
;bx = X
;by = Y
;bw = Width
;bh = Height
bh = by + bh - 1
bw = bx + bw - 1
If StartDrawing(ScreenOutput())
*buffer = DrawingBuffer()
buffer_pitch = DrawingBufferPitch()
For bb = 1 To 2;<- change this to get one of the effects above! (bb = 2 To 3)
For iy = by To bh Step 1
For ix = bx To bw Step 2
*p1 = *buffer + (ix * 4) + (iy * buffer_pitch)
*p2 = *buffer + (ix * 4) + ((iy + bb) * buffer_pitch) + 4
*p3 = *buffer + ((ix - bb) * 4) + (iy * buffer_pitch)
*p1\code = *p2\code
*p2\code = *p3\code
Next
Next
Next
DrawingMode(#PB_2DDrawing_Outlined)
Box(bx,by,300,300)
StopDrawing()
Re: Gaussian blur in real time?
Posted: Mon Oct 14, 2019 8:08 am
by Joubarbe
Uuuhhh, sorry but that's not a blur
In
the video STARGÅTE linked, you can see a perfect example of what I'm looking for.
My idea of "pre-bluring" elements that are likely to get behind the GUI is really not great... It would require a lot of clipping to blur one part but not the other, and a lot of pixel collisions calculation. And it's ugly.
Re: Gaussian blur in real time?
Posted: Mon Oct 14, 2019 8:52 am
by Mijikai
I thought it might help to get a nice blur
So i dont think its wrong that i posted it.
Here is a very fast and nice blur done with what i posted before:
Code: Select all
Procedure.i BlurSurface(X.i,Y.i,Width.i,Height.i,BorderColor.i)
Protected ix.i
Protected iy.i
Protected bw.i
Protected bh.i
Protected offset.i
Protected *buffer
Protected buffer_pitch.i
Protected scanline.i
Protected Dim *pixel.Long(2)
If StartDrawing(ScreenOutput())
*buffer = DrawingBuffer()
buffer_pitch = DrawingBufferPitch()
bh = Y + Height - 2
bw = X + Width - 1
offset = buffer_pitch + 4
For iy = Y To bh
scanline = *buffer + (iy * buffer_pitch)
For ix = X To bw
*pixel(0) = scanline + (ix * 4)
*pixel(1) = *pixel(0) + offset
*pixel(2) = *pixel(0) - 4
*pixel(0)\l = *pixel(1)\l
*pixel(1)\l = *pixel(2)\l
ix + 1
Next
Gaussian1D(scanline,bw)
Next
DrawingMode(#PB_2DDrawing_Outlined)
Box(X,Y,Width,Height,BorderColor)
StopDrawing()
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
I added the function provided by Michael Vogel some posts before.
Result:
Re: Gaussian blur in real time?
Posted: Mon Oct 14, 2019 7:48 pm
by STARGÅTE
Joubarbe wrote:EDIT: Could you explain briefly what is the method you used for this blur behind the GUI?
After the scene rendering (on a texture) this texture is will reduced in resolution (scaled down).
The scaled texture of the screen is then pixel by pixel used in a shader to blend the GUI with the background.
Therefore a GUI window under an other window is not blured.
Re: Gaussian blur in real time?
Posted: Tue Oct 15, 2019 1:20 pm
by wilbert
@Joubarbe,
Do the objects you want to blur have 24 or 32 bits internally ?
Re: Gaussian blur in real time?
Posted: Tue Oct 15, 2019 3:51 pm
by Joubarbe
I only use alpha channel drawing, so 32.
Re: Gaussian blur in real time?
Posted: Wed Oct 16, 2019 8:27 am
by wilbert
Joubarbe wrote:I only use alpha channel drawing, so 32.
That's good to know.
I'm working on some new blur code based on the idea I mentioned.
I probably try to support 24 bit also but it's good to know that it is not a priority.
Re: Gaussian blur in real time?
Posted: Wed Oct 16, 2019 9:18 am
by Joubarbe
Working without alpha is a problem when it comes to mixing sprites and the vector drawing library. 99% of the time now, when I draw a sprite in PB, I use the following function:
Code: Select all
Procedure Convert(*sprite._sprite)
StartDrawing(SpriteOutput(*sprite\hl_sprite))
DrawingMode(#PB_2DDrawing_AllChannels)
DrawImage(ImageID(*sprite\hl_image), 0, 0)
StopDrawing()
EndProcedure
IMO, 24bits is obsolete; any serious project needs transparency, especially in games. Plus, managing an alpha channel is not
that expensive.
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 7:14 am
by wilbert
I finally have something for you to test
viewtopic.php?f=12&t=73821
I tried hard to make it as fast as I could but it still might be not fast enough for you.
Just try and let me know how it performs.
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 8:47 am
by Joubarbe
Wow man, how much do I owe you?
Impressive results.
Code: Select all
Static sprite_tmp.i,
*buffer
If IsSprite(sprite_tmp) : FreeSprite(sprite_tmp) : EndIf
sprite_tmp = GrabSprite(#PB_Any, 100, 100, 800, 800)
StartDrawing(SpriteOutput(sprite_tmp))
*buffer = DrawingBuffer()
DirectionalBlur::BlurPixelBuf32(*buffer, OutputWidth(), OutputHeight(), 10, DirectionalBlur::#Blur_Full)
StopDrawing()
DisplaySprite(sprite_tmp, 100, 100)
At 800x800, your DirectionalBlur costs me 2 FPS with #Blur_Full, which is great. However, GrabSprite() is a lot more expensive than I thought. 15 FPS in that case (800x800).
The strength option doesn't seem to cost more at 30.
I'm not sure how exactly the LineStride option works. Putting random values is fun
But yeah, again, the following is the most expensive:
Code: Select all
Static sprite_tmp.i,
*buffer
If IsSprite(sprite_tmp) : FreeSprite(sprite_tmp) : EndIf
sprite_tmp = GrabSprite(#PB_Any, 100, 100, 800, 800)
DisplaySprite(sprite_tmp, 100, 100)
I'm pretty sure that I should be doing something else
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 9:05 am
by wilbert
Thanks for the feedback
Joubarbe wrote:I'm not sure how exactly the LineStride option works.
It is similar to DrawingBufferPitch()
Both stride and pitch are words that are used for this.
It's the amount of bytes a line occupies in memory. It's required if padding bytes are added to the end of a line.
For 32 bit images you can usually omit it or pass 0 since normally padding bytes are not used for 32 bit images.
If you pass 0 it will assume a line takes up 4 times the width (4 bytes for each pixel).
Joubarbe wrote:However, GrabSprite() is a lot more expensive than I thought. 15 FPS in that case (800x800).
You could try StartDrawing(ScreenOutput()) together with BlurRect if you want to blur part of a screen.
The PB manual mentions ScreenOutput() is slow on macOS and Linux but doesn't mention Windows.
I don't know how fast or slow it will be on Windows.
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 9:15 am
by Joubarbe
Pretty slow
From my experience, ScreenOutput() is really something to avoid when dealing in real time.
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 10:42 am
by #NULL
On my Windows 10 with Onboard Graphics an empty Screen/Drawing Block takes only 0-2 ms, and ~3-6 ms including drawing a full circle r=100 and including Filpbuffers() and ClearScreen().
Since in the code of my previous posts the copying of the drawing buffer into another memory buffer wasn't that expensive I have another idea:
Copy the drawingbuffer from a screen drawing block. then the main loop can continue while a separate thread can blur the copied buffer (and possibly copy it into a sprite). The next frame can then use the blurred buffer and copy it back (or draw the sprite).
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 11:01 am
by Joubarbe
I'm pretty sure you're aware of that, but 60 FPS means you have a ~16ms frame to do all the things you need done. Wasting 3 to 6ms for a ScreenOutput() operation is out of the question for me (considering that GUI elements take more than 100 pixels of radius).
Copying the buffer into another thread seems a good idea. I'll run some tests with that. I'm a bit worried about the GPU this new DirectionalBlur takes though. I'm at 70% (if Win10 is not drunk), so I definitely need to find a way to not having to update that operation so often.
There's also the idea of grabbing a small part of the screen and zooming it widely. With a strong blur, it might be aesthetic as well.
At the end, it might be too expensive for just "a cool effect".
Re: Gaussian blur in real time?
Posted: Thu Oct 17, 2019 11:19 am
by wilbert
Joubarbe wrote:I'm a bit worried about the GPU this new DirectionalBlur takes though. I'm at 70% (if Win10 is not drunk)
Do you really mean GPU or is that a typo and do you mean CPU ?
The blur computations from that module are all done by CPU, there's no GPU acceleration.