What Exactly Is The Magnitude Of The Output Of The dPdu Node ?

  • Documented Definition:

    From p387 of the PP2014 Reference Manual:

    "The dPdu node represents a varying point surface shader variable. It is a vector perpendicular to the surface normal in the ‘U’ direction. Specifically, it indicates the derivative of the surface position along ‘U’. It has no user-definable attributes."

    The direction of the vector is fairly clear from that (e.g. the first diagram in post #46 of the CGbytes thread), but the magnitude (and thus the values of the individual X, Y, and Z components) isn't. At least not to me.

    Some Simple Tests To See What Sort Of Magnitudes We Get

    I did a couple of tests with a similar setup to my "Material Room Du Node Strange Behaviour (PP2014/Poser 9 Firefly) ?" thread.

    Create a 1 PNU square 4 vertex/1 face prop with its centre at the origin oriented so that you'll see it face on from Poser's front camera.
    Import it into Poser (I used PP2014)
    Apply my http://www.sharecg.com/v/85287/gallery/11/Poser/Signed-10-Digit-Integer-Visualizer-MT5 shader.
    Plug a dPdu node into it and set the multipler to one million
    Set all Front Camera scale values to 100% and dolly values to 0.0
    Set render size to 500x500.
    Render - note the value displayed on the square in the render
    Change a setting and re-render. Repeat as necessary.

    Here are my first test results:


    Front Camera 'Scale' value ... (1000000 x dPdu)
    100% ... 6046874
    200% ... 12093749
    400% ... 24187498
    800% ... 48374995 (very small text, so I might have misread it)

    That's almost perfect doubling each time. I'd expect dPdu and dPdv to be the same for this test, and I get the exact same values if I use dPdv instead of dPdu.

    Do those values make any sense?

    The square is 1 PNU wide, which is 103.2", which is 1032 'P' units (the P node output is in 0.1" units)

    The first render (scale 100%) is about 500 pixels wide.
    1032 'P' units across 500 pixels gives 2.064 'P' units per pixel
    The dPdu value I got is 6.046874, just under three times this.

    The second render (scale 200%) is about 250 pixels wide.
    1032 'P' units across 250 pixels gives 4.128
    The dPdu value I got is 12.093749, just under three times this.


    I recall (e.g. here) that if you want to extract just the X, Y, or Z value from a P node you need to multiply the value by 3. The output of the dPdu is a vector, so I'm thinking that the same may apply ?

    Tentative first guess at the equation:

    If that's true, then for this very simple test case:

    dPdu = 3 x (10 x square width in inches) / (square width in pixels on the render)
    dPdv = 3 x (10 x square height in inches) / (square height in pixels on the render)

    That' seems a good starting theory - next step would be to do something slightly different with the test and see if the results match what the equation gives us.

    (Note: I was surprised that the rendered size of the square seems to be involved...)

  • Unfortunately simply rotating the square through 60 degrees around the Y axis (which halves the rendered width) blows that theory out of the water.The rendered numeric value doesn't double. I get some weird values that I can't make sense of...


    Here's the numbers from those render screenshots

    yRot ... 1000000 x dPdu
    -60 ... +33037170
    0 ... +12093749
    +60 ... -885324

    I'm totally stumped trying to think of an explanation for this !

  • ...and displaying dPdv with rotations about the X axis...


    xRot ... 1000000 x dPdv
    +60 ... +18355968
    0 ... +12093749
    -60 ... -8856812

    I'd expect the +-60 dPdu and dPdv values to all be the same, around 24000000.
    But all four values (this post and the previous) are different. Very different.

    (Yes, it could be my shader. But I don't think so.)

  • Like Du, dPdu also appears to increase in discrete steps. My original suspicion was raised on post #37 of the CGbytes thread, and since that test was viewing a flat square perpindicular to the line of sight of an orthogonal camera I calculated values for dPdu based on the tentative equation posted in the OP here and posted the results in post #51 of the CGbytes thread.

    Since I'm using a similar test setup now (as described in the OP of this thread), I tried to see if I could reproduce these dPdu steps using my current setup by simply increasing Front Camera Scale from 100% to 420% in 10% steps, and plotting the rendered numeric values and values derived from my tentative dPdu equation on the same graph.


    Note: I didn't physically measure the pixel width each time - it's calculated as:

    Pixel_Width = 500 / (Cam_Scale / 100)

    The 'Calculated' value uses:

    Calculated =3 x (10 x 100.32) / (Pixel_Width)

    (if you saw a note about an extra factor of 10 here - I looked at the wrong spreadsheet!)

  • Since I can't make any sense of those steps in dPdu (if they're related to micropolygons I can't see it), I decided to change tack a bit, and spotted another simple mistake, this time in my dPdu tests earlier in previous posts here with the square rotated.

    Regarding the unexpected values I got when I did the yRot & dPdu and xRot & dPdv tests a couple of posts back, I just realized while doing a series of test Z rotating the square in 10 degree steps that when I plug dPdu into my shader it's converting a vector to a scalar.

    When the square is perpendicular to my line of sight with it's bottom horizontal the Y and Z components of dPdu are zero, and the dPdu vector has only an X component.

    But as soon as I rotate the square about any axis then the dPdu vector also has a non-zero Y and/or Z component as well.

    Since I was assuming that the rendered numeric value was just the X component...

    So I need to go away and redo thos rotation tests. In the meantime I posted the rendered numeric results of my 10 degree Z rotation step tests over in post #53 of the CGbytes thread - it's a nice 180 degree section of a horizontally offset sine curve.And the offset looks like -45 degrees ?

  • I've redone my rotation tests. With FrontCameraScale fixed at 200% I rotated my 1 PNU square in 10 degree steps around each axis. For the Z axis I did -90 to +90, and for the X and Y axes -180 to +180. I noted the X, Y and Z components of dPdu for each step and plotted graphs of the results. Details of the tests are on the CGbytes thread, posts #56 to #58. I'm posting the three graphs here too.

    (I've posted a zipped version of the PZ3 I'm using for these tests in post #56 of the CGbytes thread if anybody else wants to try)

    Rotating The Square About The Z Axis
    Perfect sin and cos curves.
    0_1466577822418_dPdu XYZ with Z rot.jpg

    Rotating The Square About The Y Axis
    Clearly -sin and cos curves, but some points are off. That could be my shader, my reading of the values, or something else.
    0_1466577519532_dPdu XYZ with Y rot.jpg

    Rotating The Square About The X Axis
    I expected fixed values, zero for Y and Z, non-zero for X. Not steps. And the steps are almost doubling each time, 36.28 -> 68.53 -> 133.03. That's similar to the large steps I saw as I increased camera scale here.
    0_1466577462797_dPdu XYZ with X rot.jpg

  • Rotating The Square About The Y Axis (More Detail For -20 to +20)
    Concentrating on the more ragged red cosine curve in the previous post with the misplaced zero rotation value. Going in steps of 1 degree revealed not just a step down to the mid-thirties, but multiple steps up and down between the sixties and eighties! I Slightly more words in post #59 of the CGbytes thread.

  • Nudge
    I'm still hoping that somebody can come up with some sort of explanation for the out-of-place points in the graphs in the last few posts on this thread...