Muncher 101 Report post Posted October 3, 2006 I was reading John Carmacks old blogs: http://www.armadilloaerospace.com/n.x/johnc/Recent%20Updates when i got to the section about derivative instructions in pixel shaders. Firstly, whats a derivative.. and second, whats a derivative? Thanks for any help... 0 Share this post Link to post Share on other sites
TheAdmiral 1122 Report post Posted October 4, 2006 The derivative of a [differentiable] function is the result of differentiating it. I'm not sure how much calculus you know, but that's where its essence lies.Imagne a smooth curve, perhaps like a rollercoaster. The derivative of the curve at a point along its length is its gradient at that point. When the curve is 'level', the derivative is zero. When it is 'uphill', the derivative is positive; when it's very uphill, the derivative is even more positive. Predictably, downhill <=> negative derivative. Roughly speaking, vertical points on a curve correspond to 'infinite' derivatives.For discretely sampled data, the derivative isn't so well defined, but can still be calculated by sampling the surrounding points and dividing y_difference by x_difference.I suggest you do some reading if you want to be completely comfortable with derivatives, as this topic goes deep. Very deep. Very deep indeed. [wink]RegardsAdmiral 0 Share this post Link to post Share on other sites
Guest Anonymous Poster Report post Posted October 4, 2006 To maybe add some clarity, the derivatives instructions simply compute the texture coordinate deltas in each 2x2 block, at least this is the way it's done on current hardware. 0 Share this post Link to post Share on other sites
Plasmadog 205 Report post Posted October 4, 2006 Actually, I have been wondering about this myself recently. I know what derivatives are in the calculus sense, but how exactly do they relate to pixel shaders? I have seen example shaders that use the ddx and ddy functions, or the fwidth function, as part of an antialiasing technique. In these cases, the pixel's object-space x or y position was used as the parameter, like so:float w = abs(ddx(IN.ObjPos.x)) + abs(ddy(IN.ObjPos.x));//or alternatively...float w = fwidth(IN.ObjPos.x); // does the same thing, according to docs.What would the return value represent when used in that way? 0 Share this post Link to post Share on other sites
Pragma 395 Report post Posted October 4, 2006 The derivative instructions just measure the difference of a given expression between neighbouring pixels. I believe all current hardware computes these differences in 2x2 blocks.They are useful particularly in anti-aliasing; if ddx(texCoord) and ddy(texCoord) are large then the hardware knows to use a smaller mipmap level, if they are small, it uses a bigger mipmap level. 0 Share this post Link to post Share on other sites
TheAdmiral 1122 Report post Posted October 5, 2006 In the shader sense, 'derivative' usually means 'partial derivative', defined on a single channel of the image.You may want to imagine a 2D greyscale texture that represents a heightmap. It will have two natural partial derivatives: The u derivative (¶y/¶u) will be the slope of the corresponding terrain as you move in the positive u direction, and similarly for v. A basic calculation would sample the texture at nearby points, often once to either side of the point in question, find the difference and divide by the separation of the two samples. For example, suppose the following 3x3 block appears in a channel of a texture:3 6 82 5 62 4 4From this we can approximate the partial derivatives at the central point (the 5):¶y/¶u = (6 - 2) / dimension¶y/¶v = (4 - 6) / dimension.The value of dimension will correspond to the texture scaling: The more the texture is stretched, the shallower the 'bumps' will be.There are many other (better) ways to calculate discrete partial derivatives, but this is the simlest and fastest. It does tend to cause real trouble on images with a lot of aliasing though.RegardsAdmiral 0 Share this post Link to post Share on other sites
Plasmadog 205 Report post Posted October 5, 2006 @TheAdmiral: That would all make perfect sense to me, if only the derivative functions din't take arbitrary expressions as input.I think I understand Pragma's explanation. Let me see if I have it. If, in a pixel shader, I pass the pixel's object-space position into one of these functions, e.g. ddx(IN.Pos.x). This shader program, as I understand it, will be executed for every screen pixel covered by the same polygon, and in each execution the same function will be called with a different input value. So, what I take from Pragma's explanation is that the function will essentially say "what was the value of IN.Pos.x when I processed the pixel next to this one on the x axis, and what is the value for the pixel I'm processing now?" And then, based on TheAdmiral's formula, the function presumably returns the average of those two values.Is that more or less right? If it is right, how does it handle cases where the adjacent pixel was not handled by the same shader? Or cases where it was the same shader, but a different polygon? 0 Share this post Link to post Share on other sites
Pragma 395 Report post Posted October 5, 2006 Yes, I think you've understood it exactly. But TheAdmiral's formula is not quite right - his is based on central differencing but the GPU's only do derivatives in 2x2 blocks or "quads".ie. if the block looks likef = a b c dthenddx(f) = b-a b-a d-c d-cddy(f) = a-c b-d a-c b-dThe GPU rasterizes everything in quads - so if your polygon touches just one pixel out of a quad, the whole thing will be rasterized. That way the pixel always has two neighbours to compare against and you can always compute derivatives. 0 Share this post Link to post Share on other sites
Plasmadog 205 Report post Posted October 5, 2006 Thanks Pragma. I'm not sure I understand that last part, but you've certainly given me enough to make sense of the examples I've seen. 0 Share this post Link to post Share on other sites
TheAdmiral 1122 Report post Posted October 6, 2006 Quote:Original post by Pragma...TheAdmiral's formula is not quite right - his is based on central differencing but the GPU's only do derivatives in 2x2 blocks or "quads".I won't pretend that I knew that, but I'm stubborn enough to insist that my definition isn't wrong. It is impossible to calculate the derivative of discretely sampled data (as the definition inloves a limit tending to zero): my approximation and the industry-standard methods may disagree, but they're both just approximations to the real thing [smile].RegardsAdmiral 0 Share this post Link to post Share on other sites