How does fwidth work?

PG:

for all this. assume camera remains static.

okay so fwidth is supposed to be rate of change of any varying.
so if I draw a triangle w/ a chipped corner.


but use fwidth to control the width.

then if I raise the tops of the traingle (press “d”), this should happen,

  1. the thickness, being a % of the triangle should go up
  2. rate of change, or fwidth, should go down
  3. their factor, should remain constant

and indeed it does.

but something weird happens when I raise just one vertex of the triangle.

(press “f” for left, press “g” for right)

heh???

In this case did the point number 2 from earlier, the fwidth going down, just not happen?

I wanna understand this behavior.
and I wanna be able to align the chipping at the vertex to a normal at any constant width I want.

At a simplified level (w/o the fwidth), I know I can do it by manipulating the corner information I pass in to begin w/

and I sort of made it work

but I want this to be constant width by integrating fwidth. so i need to understand fwidth better.

I also don’t quite get the math, I did get it to work in that case. but given a random triangle and the normal for that corner, idk how I’d even calculate the angle, or the order in which I pass the -ve and +ve angles

Any help or clarity understanding this would be much appreciated ty <3

It makes a little more sense if you decompose fwidth with abs(dFdx) + abs(dFdY)
It works at pixel level but setting values at vertex makes it more difficult to visualize.
I’m not sure using the derivative is what you need actually.

Something like this maybe?

2 Likes

so a position based approach doesn’t quite work for me.

because I’m actually trying to draw edges using the material / a modified barycentric approach.

and the corner chipping thing is for cases like this.

the position based approach would require me to pass the whole line equation, which would take like, 2 x vec3 attributes for one vertex (point + normal), so 6 x vec3 attributes in the worst case.

this is on top of the vec3 barycentric attribute I’m already using. which I don’t want cuz that’s a lotta attributes.

Ik there’s a way that I can make the chipping adhere to an angle/normal that I pre-calculate and pass in through those very same barycentric attributes.

because the 2nd PG in the post does exactly that

the only problem is having it maintain constant width. which I was hoping fwidth could help me do : O

but if it’s as you say that fwidth isn’t exactly “rate of change” but “abs(dFdx) + abs(dFdY)” which is somehow different then I might need to reconsider this lol

oh wait you mean dFdx and dFdY are actually funcitons that exist in glsl???

this changes everything!! : O

not this particular question but the possibilitiiiez : DDD

I think I understand fwidth a little better now and you’re right, that won’t solve my problem here at ALL.

so dFdx is, on the screen, the rate of change of a varying horizontally (can be -ve)
and dFdY is, on the screen, the rate of change of a varying vertically (can be -ve)

fwidth as you mentioned is abs(dFdx) + abs(dFdY) and this can’t be -ve


for this particular issue in question, with my new found perspective, I’ve figured out what I’ll do though

I’ll cook up an imaginary virtual triangle which gives me exactly the results that I want. and then I’ll overload the supposed interpolation of it to get the actual “corner” varying values that’ll give me the correct result for the actual triangle as well : D

Thank you so much for this! this has cleared up a lotta stuff I didn’t previously know about : D

1 Like

got the virtual barycentric coords :3

these don’t distort on weird ahh changes to the triangle!

they’re also position independent so yeyy : D
here’s how I did the ~ virtual triangle interpolation math ~