16

Every time I drunk browse so I see an unanswered fwidth question. And it makes me wonder what it actually was designed to do.

Reading the docs it is: abs(dFdx(p)) + abs(dFdy(p))

So it is not classic mip selection which is max(dx,dy). Is it for alternative mip selection? But I fail to find a case where abs(dx) + abs(dy) would be better. There must be some siggraph paper or common algorithm I am completely missing that uses that function. And it must be really popular because it made it into GLSL. The only thing I can think of is some 2d post filter I am missing.
But what? I am sure somebody here knows and once you see it it's obvious. So: What algorithm uses abs(dx) + abs(dy)?

Nick Friskel
  • 2,369
  • 2
  • 20
  • 33
starmole
  • 4,974
  • 1
  • 28
  • 48
  • 1
    The 2D post filtering you mention is a decent example actually. – Bart Jul 23 '11 at 13:11
  • 4
    Take your pick. Anti-aliasing, edge detection, anisotropic filtering. Actually, after some Google-ing I found an example use [here](http://prideout.net/blog/?p=22) where it's used for anti-aliasing of a cel shading shader. – Bart Jul 23 '11 at 13:16
  • chatting in comments now :) i found that stuff also but it does not seem important enough to make it into the language. there must be something else! for 2d the only thing i could think of is that it is maybe an ok prediction. i still feel like there is some blaring obvious thing for it though. – starmole Jul 23 '11 at 13:25
  • 2
    @starmole: Just because it doesn't "seem important" to you doesn't mean that it isn't important. Bart gave you 4 scenarios where the function would be of value. By all rights, that should have been an answer. – Nicol Bolas Jul 23 '11 at 17:20
  • 2
    @starmole I don't know how much more magical you expect it to be, in order to count as important? It's an often used type of function in scenarios similar to those I mentioned. I don't know the nitty gritty details of what it boils down to in terms of the actual "code" sent to the GPU, but I could imagine some advantage of this single function over evaluating calls to dFdx and dFdy yourself. But that's pure speculation on my part. – Bart Jul 23 '11 at 17:55

2 Answers2

13

You're actually quite on the money with the 2D filtering suggestion. Any filter which relies on some sort of metric for the rate of change between a pixel and its neighbors could benefit from this function.

Examples would be anti-aliasing, edge detection, anisotropic filtering. I'm sure there are more examples one could think of.

It seems from your question and comments that you expect there to be a mind-blowing reason for this function to be included in GLSL. I would just say that it's a useful function to have. Perhaps someone with more in-depth knowledge about the actual internals of this function could provide more detail on what happens behind the scenes (i.e. if there is any performance improvement over a handwritten equivalent with dFdx and dFdy).

Bart
  • 19,692
  • 7
  • 68
  • 77
  • Thank you for the answer. It does make sense. What I was looking for was really something "mindblowing". For example looking at the GLSL noise function, I know what why it is there, why it needs to be driven by input etc. But only because I knew about Perlin noise before! So I kind of assume this function is similarly important in some algorithm I just don't know about. But with the age of the question and nobody answering with a siggraph link you are probably right: It's a useful shortcut, easy to implement and emulate. Anyhow, thanks for the patience and sorry if I seemed a bit douchy :) – starmole Aug 29 '11 at 08:26
  • Here is a good-looking example of shader using fwidth as well: [terrain-contour-lines](http://www.gamedev.net/topic/529926-terrain-contour-lines-using-pixel-shader/) – wip Feb 12 '15 at 09:50
4

this is the total derivative for the function DF = dF/dx*dx + dF/dy*dy .see the similarity? fWidth >= DF or in words fWidth is maximum possible change in a fragment variable F, between any of a current fragmants neighboring pixels. ie the 8 surrounding pixels in the 3x3 neighborhood.

TimW
  • 41
  • 1