ZBrushCentral

Displacement map values

Hi,
We’ve been doing some tests with zbrush-generated displacement maps
for PS3 development. We’ve found a very interesting, if not disturbing,
behaviour when rendering displacement maps. I’d be very grateful for
any feedback from anyone on this…this takes a bit to explain, so I’ll
try to be brief…

  1. New ZB session

  2. We imported a default Maya sphere into ZB (res 10x10, 100 polys)

  3. subdivided 3 times (~6000 poly ct) then return to subdivision level 0

  4. In Tool->Displacements, Adaptive off, Mode On, rendered a 1024 map

  5. Exported as 8bit BMP

    So, a displacement map where no displacement had been applied.
    One would think that with zero displacement, the levels would range
    from 0 to 127, right?..or more accurately, given the subdivision, should
    range from 127 to just a bit below…(there’s no negative displacements,
    so no black (0) etc…)
    But, lo and behold, the values actually range from 127 to 213…Hmmmm?

Okay, so far?..

So, an interesting test we think is to repeat the steps, except adding a
small STD bump/protrustion…We do that, exporting a 2nd BMP.

Analyzing these two BMPs was a bit of a ohmagod revelation to us…
Areas in each that corresponded to areas that contained no displacement
should be the same grey value, right?..Wrong, they were now different
values…In the first image, that pixel (representing no displacement)
as 201, and the same pixel in the 2nd image (again representing no displacement was 153.

The 2nd image containing the small bump displacement had pushed all the
non-displaced greyscale values down…Now, the 201 pixel, (to me) should
have registered closer to 128, so I can’t explain that either…but in any
case, pixel that are not displaced should always be the same value.

This not being the case, I don’t see how one can achieve any kind
of consistency in a pipeline that utilizes these maps.

Can someone, anyone, please tell me I’m doing something stupid here,
or that this will be fixed in 3.0…'cause this could cause us some real headaches…

Thank you,
Flintstone.

example.jpg

First off, before you create your displacement map you need to restore the original subdivision level 1. You see, when you divide your model, it is smoothed. With primitives, this typically causes the models to become smaller in size. When you return to subdivision level 1, it is affected by the higher levels, which means that it is also changed. So when you create your displacement map, there are going to be errors unless you restore the original geometry at level 1. You can do this in your example by importing the model again right before you generate the displacement map.

Second, is Photoshop’s color management turned on? If so, then the values you’re reading in Photoshop are NOT the values that ZBrush is generating. Photoshop has a nasty habit of shifting the color values, which in turn would give results like what you’re describing.

Thanks for the reply, Aurick,

I forgot to add in the initial post, that I did return the subdivision level to 0.

Photoshop’s color management is not on.

Any other thoughts?

Thank you,
Flintstone.

Returning it to lowest level is not enuf…you need to replace that level with the original mesh because as Aurick stated the original has now been smoothed as have the rest of the levels which means it has changed and so would the displacement.

replace the lowest level after adding the bump with either a stored morph target or the original unaffected model then try the test again and see if you get the same results.

I apologize if I misread your message and you did do that, but was kinda unsure by your statement.

Hi again,

Yes,…I always store a morph target and did return to it before
rendering any displacement and/or normal maps…

Any other thoughts?..

I believe this is not a user problem, but a problem with bug that
needs to be dealt with at the programmer level…

Thank you for your response…
Flintstone.

.

I may be miss informed but, i was under the impression that zbrush creates an ideal amount of contrast with any displacement map it generates. They u tweak and control the amplitude of that displacment in the exteral render u use.

I was also under the impression this is why ppl a few months back were asking for zbrush to be abe to create FLOAT displacemnet maps so this “optimization” of displacement values wouldnt take place, and u could paint several displacement maps on one model.

Hi,
Flintstone: The behaviour that you are experiencing is what ZBrush was programmed to do, as spaz8 mentioned (thanks:)) , ZBrush is auto-adjusting the displacement values in order best use the range offered by the 16-bits map. I will post an example and more info about this later tonight.

spaz8: A floating point displacement-map format is planned to be included with the next free-update (or maybe earlier as a ZPlugin).

-Pixolator

That’s good to know Pixolator! I’m sure folks will be super excited to have that! HAHA

Here is a time-lapse image of a simple displacement example. In this example, I have generated two displacement maps and used the alpha-depth-factor (located in the Alpha palette, the alpha-depth-factor is automatically calculated when generating displacement maps) to compare the absolute displacement amount of the same point in both maps.

1. Clear canvas.
2. Ring3D drawn in canvas.
3. Ring initialized to SDivide=8, LDivide=32.
4. PolyMesh3D created out of Ring3D object, Edit mode activated and Morph target stored.
5,6. Mesh rotated and zoomed for better visibility.
7-11. Mesh subdivided to one million polygons.
12. The Layer edit-mode selected and a ‘dot’ was drawn on the mesh.
13,14. Two similar dots added to the mesh.
15-19. Subdiv level reduced back to level 1.
20. Morph target switched in order to restore the initial unsubdivided mesh.
21. Displacement map generated and converted to a texture which was then applied to the mesh. Since the ‘dots’ are the points of the mesh which have been displaced the most, they have resulted in the lightest gray dots in the displacement map. The intensity was sampled (by hovering with the cursor over the area, pressing ‘G’ key and reading the intensity in the color palette ) as 212. The Alpha depth factor was 0.0234. Using this values, the absolute displacement values for the dots is (212-128)0.0234 =1.9656 units.
22. Texture removed, preparing to add new ‘dots’.
23. Before returning to the highest subdiv level, the Morph target is switched back.
24. Returning to the highest subdiv level.
25,26. Two smaller ‘dots’ drawn in the same location. This resulted in doubling the displacement amount of these dots while keeping the middle dot unchanged.
27-30. Switching to subdiv level 1.
31. Restoring the original Morph target.
32. Displacement map generated and converted to a texture which was then applied to the mesh. In this map, the two new dots are now the most-displaced points and are represented by the lightest gray values; the middle dot is now darker than it was in first displacement map.
The middle dot gray value is sampled to be 170 (instead of 212). The depth factor in the alpha palette was 0.0468 (twice the amount of the previous map). The absolute displacement calculated as (170-128)
.0468=1.9656 units.

As expected, the gray intensity has changed but its calculated absolute value was not.

Note 1: In the above example, the evaluation of the grayscale values was done on the texture map which is only 8-bits depth per channel. For more accurate calculations, the grayscale value should be evaluated in the 16-bits map.
Note 2: When generating displacement maps for multiple regions within the same mesh, use the Multi Displacement plugin (within the ZPlugin palette) to generate a consistent depth factor across the maps.

Hope this helps:)
-Pixolator

I will make an exercise with your sure guide and post it¡
Thanks a lot
Andreseloy

Thank you all for your feedback…I do most definitely appreciate it…

O Mighty Pixolater,…I doth humbly ask…
Doth thy knowest a way to turn off this “auto adjusting” feature when rendering displacement maps?..before I plucketh out mine hair?..:wink:
Or do we have to wait for ZB3?..

You see the condundrum, right?..no consistentcy when applying minor tweeks.
Must have drove the Weta guys nuts…Art Director says “can you make that
bump higher?”…you do that, but now your other displacements have been
pushed down…while you scramble to input a new “magic number”…our little
name for the AlphaDepthFactor…Perhaps I am all wrong,…Perhaps I am not
seeing some large nugget of knowledge and technique in handling such updates.

While I thank Spaz8 for his expertise,…it appears to me that if ZB was maximizing (my word) the color space in an image file, there should appear some total black and some total white, which doesn’t appear to be the case…

Anyways, all that aside,…a large measure of our development effort
now awaits ZB3…where I am lead to believe by your collective comments,
a “zero” displacement region will always yield a consistent numerical value.

Thank you very, very much!
Flintstone.

Hi,

The auto scaling is a desirable feature, a feature without which you will be forced to regenerate several displacement maps with varying scale-factors while attempting to achieve good utilization of the 16bits range.

Furthermore, the scaling factor will not change with every mesh tweak, it will only change when the most-displaced point has moved or when it is no longer the most-displaced point.

However, since this item has also been requested by others, I will look into the possibility of creating a ZPlugin which will allow you to achieve consistent results and diminish the need to “pluck hair”.:slight_smile:

-Pixolator

Hello Pixolator,
…have you had a chance to look at creating a ZPlugin that would
remap/adjust displacement values?..
Thank you,
Flintstone.

Yes, the work on this ZPlugin is in progress:)

Hello Pixolator,

I was just wondering if you have any ideas about that plugin release!?!

Thanks,

The ripper.

Hi. I, too, am still struggling with ZB displacement in max7/MR . Suddenly I remembered this very informative post, and I gotta ask: if the middle gray value varies, depending on the maximum displacement range, then don’t we have to compensate for this in the external renderer? The common hint is to offset the RGB value by -0.5, but this can’t work if the middle gray is NOT 127 (or the half of 2 exp 16), now can it?

The middle (zero displacement) value does NOT vary. It is always 50% gray. If you open the map in Photoshop and find that the middle value is not 50% gray, it’s because Photoshop’s color management feature is active and the map is being adjusted by Photoshop. ZBrush always calculates the map with a middle value of 50%.

Thanks for the quick answer. But what did Pixolator mean by “The middle dot gray value is sampled to be 170 (instead of 212)”?

Another question: is the Alpha Gain value of any relevance for external renderer? What is it supposed to be? Maybe you can shed some light on this?

Thx