Gamestudio Links
Zorro Links
Newest Posts
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
Help with plotting multiple ZigZag
by degenerate_762. 04/30/24 23:23
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (dr_panther, 7th_zorro), 1,203 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
Newest Members
firatv, wandaluciaia, Mega_Rod, EternallyCurious, howardR
19050 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
gaussian kernel for bilinear filtering #373019
06/06/11 20:12
06/06/11 20:12
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline OP
Expert
Joey  Offline OP
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
hey,

since blurring is quite important in many shaders I thought I could give you a little speedup. Cards can filter samples in a bilinear way, thus saving you half the samples when calculating something like a gaussian blur. so here
Code:
samples[width_] := Module[{t, p, l, w},
  w = Max[Round[width], 1];
  t = Table[
    N[PDF[NormalDistribution[0, w/2.2], x]], {x, -w - .5, w + .5}];
  p = Partition[t, 2];
  {#[[1]] + #[[2]], 1 - #[[1]]/(#1[[1]] + #1[[2]])} & /@ p
  ]


is the generating code for anyone who wants to use it and here are some sample kernels:
4
Code:
{{0.0653515, 0.833874}, {0.433296, 0.631295}, {0.433296, 
  0.368705}, {0.0653515, 0.166126}}


6
Code:
{{0.0341105, 0.724721}, {0.149481, 0.641251}, {0.312518, 
  0.548249}, {0.312518, 0.451751}, {0.149481, 0.358749}, {0.0341105, 
  0.275279}}


10
Code:
{{0.0178401, 0.631295}, {0.0457636, 0.60307}, {0.0927521, 
  0.574141}, {0.148539, 0.544695}, {0.187973, 0.514934}, {0.187973, 
  0.485066}, {0.148539, 0.455305}, {0.0927521, 0.425859}, {0.0457636, 
  0.39693}, {0.0178401, 0.368705}}


16
Code:
{{0.0105133, 0.579974}, {0.0191392, 0.569459}, {0.0319842, 
  0.558881}, {0.0490657, 0.548249}, {0.0690956, 0.537573}, {0.0893212,
   0.526863}, {0.105996, 0.516128}, {0.115467, 0.505378}, {0.115467, 
  0.494622}, {0.105996, 0.483872}, {0.0893212, 0.473137}, {0.0690956, 
  0.462427}, {0.0490657, 0.451751}, {0.0319842, 0.441119}, {0.0191392,
   0.430541}, {0.0105133, 0.420026}}



If you need any specific sizes you can ask me. Usage is as follows:
Code:
static const float2 kernel[NUM]=...; // here goes the sample output I posted above

for(int i = 0; i < NUM; i++)
{
	pixel = tex2D(mytex,texcoord0 + float2(kernel[i].y-NUM+2*i,0)/resolution_x)*kernel[i].x;
	color += pixel;
}



same goes for the y direction, so you need to do two passes. Could be that the kernel is off one pixel, I'm not sure atm, but the shader gurus (for whom this is intended) should be able to tell.

Joey

btw. you could replace the NormalDistribution by anything you like.



Last edited by Joey; 06/06/11 21:46. Reason: divide offset by resolution
Re: gaussian kernel for bilinear filtering [Re: Joey] #373021
06/06/11 20:47
06/06/11 20:47
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
First, it is not "bilinear", but "seperated". Bilinear sampling refers to texture filtering whereas seperability refers to the fact that a square-kernel could be seperate into a vector and a transposed vector, which, multiplied, generate the original kernel again. That way, a convolution K * I can be replaced by the convolution v * ( v^T * I), which requires less arithmetics.

The problem you have is that your kernel is always even. That way, you never sample the pixel on which the kernel is applied to. You could shift the kernel pivot, so that you sample the original pixel, but then you have an odd weighting scheme for the surrounding pixels and you are weighting more the next right (or left pixel), so an odd NUM value is beneficial.

Second, I don't get why you sample in an intended fashion bilinear texture samples (this time this is the correct term) by adding a fraction on the tex-coord:

... texcoord0 + float2(kernel[i].y ...

Why don't you simply use vecViewport to get the pixel size and sample "real" neighbour pixels.

Third, you are sampling in a tapped fashion. Since your NUM value is storing the number of samples, you are going a length of NUM to the left (or up) and the double of the i-counter to the right (or down). You should divide both values by 2 to get a non-tapped sampling.

Fourth, since the gaussian bell is symmetric, it is totally sufficient to store only the weights of the half of the bell. Though, I don't know if the arithmetic overhead then generates more instructions, but I would only store half the kernel weights.

Best regards,
-Christian

Last edited by HeelX; 06/06/11 20:49.
Re: gaussian kernel for bilinear filtering [Re: HeelX] #373026
06/06/11 21:20
06/06/11 21:20
Joined: May 2005
Posts: 2,713
Lübeck
Slin Offline
Expert
Slin  Offline
Expert

Joined: May 2005
Posts: 2,713
Lübeck
I am not sure about every point but I think in most points you are wrong HeelX.
But now I am confused.
The trick however is to sample between the pixels to take advantage of the bilineral filtering which allows you to use half the samples by keeping the same quality.

Re: gaussian kernel for bilinear filtering [Re: Slin] #373027
06/06/11 21:30
06/06/11 21:30
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Ah. I thought this was an ordinary filter smile stupid me!

So can anyone tell me a reason why I get the same result with less samples when using the interpolated values?

Last edited by HeelX; 06/06/11 21:33.
Re: gaussian kernel for bilinear filtering [Re: HeelX] #373030
06/06/11 21:54
06/06/11 21:54
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline OP
Expert
Joey  Offline OP
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
well, imagine i want to sample pixel a and pixel b and weight them both by 50% (average them). i can do that by two tex2D's or by one, sampling halfway between them (assuming they're neighbours). now imagine i want to weight them differently, say 90% a and 10% b. i can still do that with only one tex2D, now 10% away from a in direction of b.
that's what i'm calculating. instead of just the weights for each pixel i store a sampling position and a combined weight. also, the kernel is not symmetric (the weights are, but then, it's only some bytes). you could calculate everything in a shader, only storing one side of the gaussian convolution and reconstructing the rest, of course. but that will definitely be slower, way slower.
i think i see how you misunderstood my idea, so i'm sorry for not being more precise ^^.

edit: by the way, odd numbers work fine as well.

Last edited by Joey; 06/06/11 22:00.
Re: gaussian kernel for bilinear filtering [Re: Joey] #373035
06/06/11 23:01
06/06/11 23:01
Joined: Jul 2001
Posts: 6,904
H
HeelX Offline
Senior Expert
HeelX  Offline
Senior Expert
H

Joined: Jul 2001
Posts: 6,904
Interesting, never heard of this. Do you have a paper or reference? Does this work for box blurs, too?

I am doing a very exhaustive (yet seperated) box-blur stage in my SSAO shader (with depth/normal checking) and if there is a chance that I can do that with less lookups, this would be very awesome.

Re: gaussian kernel for bilinear filtering [Re: HeelX] #373043
06/07/11 01:03
06/07/11 01:03
Joined: Mar 2006
Posts: 3,538
WA, Australia
J
JibbSmart Offline
Expert
JibbSmart  Offline
Expert
J

Joined: Mar 2006
Posts: 3,538
WA, Australia
I've been using something like this for my anti-aliasing (so pp effects can be used with it, the effect isn't just on the edges of objects, and it can be toggled on/off instantly) -- I render the scene to a bmap with twice the dimensions of the screen, and then render the result to the screen using one sample per pixel -- each sample being in the corner between four pixels on the larger bmap. It works like a charm. I also use it for my bloom, whether I'm using anti-aliasing or not.

Jibb


Formerly known as JulzMighty.
I made KarBOOM!
Re: gaussian kernel for bilinear filtering [Re: JibbSmart] #373052
06/07/11 06:16
06/07/11 06:16
Joined: Jan 2003
Posts: 4,615
Cambridge
Joey Offline OP
Expert
Joey  Offline OP
Expert

Joined: Jan 2003
Posts: 4,615
Cambridge
yeah, it's really really useful. You find it for instance in gpu gems 3, though I don't remember where exactly. Sure, it also works for box blurs, in this case it's very simple: always sample halfway between the pixels for every second pixel. No need to store weights either, just divide by the number of pixels in the end.


Moderated by  Blink, Hummel, Superku 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1