Hello community,
I’ve found an interesting plasma shader on Shadertoy. I’ve ported the GLSL
code to C/C++. I fill a render buffer while the fragment shader draw the screen.
I haven’t found any equivalent to dFdx and dFdy. Even in GLM. Why?
Do I have to write my own code? If yes, how?
Any answer appreciated,
azerty
dFdx/y are computed based on how GPU’s threading hardware works. The short version is that a 2x2 square of neighboring fragments are all executing on the same computational unit at the same time. Each thread within this group is executing the exact same code at the exact same time. They all share register and local memory storage, but much of that storage is allocated for the different “threads” of execution.
But since those registers and storage are all right there, dFdx/y can just peek at a neighboring thread’s value and compute the difference between that value and the current thread’s value. The X and Y determines whether it peeks at the horizontal neighbor’s thread or the vertical neighbor’s thread.
If you’re trying to “port” a rendering process to C++, then you’re probably computing each fragment completely separately. So… you have to not do that. You have to compute each 2x2 quad in lock-step the way a GPU would and take the difference between neighboring values.
dFdx
and dFdy
are effectively computed by,
getting the values passed to dFdx
(or dFdy
) for 2x2 adjacent texels being drawn
p0 = value passed to dFdx at fragCoord x, y
p1 = value passed to dFdx at fragCoord x + 1, y
p2 = value passed to dFdx at fragCoord x, y + 1
p3 = value passed to dFdx at fragCoord x + 1, y + 1
Effectively p0,p1,p2,p3 represent the values passed to dFdx in a 2x2 square
p0----p1
| |
| |
p2----p3
dFdx
is the average delta in x and dFdy
is the average delta in y
dFdx = (p1 - p0 + p3 - p2) / 2 // average of horizontal change
dFdy = (p2 - p0 + p3 - p1) / 2 // average of vertical change