terrainData.heightmapTexture float value range

While rendering to terrainData.heightmapTexture I discovered that writing 1.0f to pixels doesn’t result in terrain of maximum height (as specified in “Terrain Height” inspector field) but 0.5 does (1.0 is twice that and not available for manual brush edits).
Seems odd/surprising but I expect there is sensible reason behind it. Can sb explain this behavior?

preview image
(image shows terrain after rendering a sine wave (0.0-1.0 range) to it. I was using a compute shader > Graphics.CopyTexture > terrainData.DirtyHeightmapRegion path)

i think it’s dueto they use an unsigned 16bit int => which has a range from -65535 to 65535. i came across this when i wanted to set/getheights and the output was a value between 0 and 0.65535(as the hughest point on terrain) not as unity says 0-1…

It is a bug

Correction: Not a bug. It’s a feature :

"The heightmap implementation itself is
signed but is treated as unsigned when
rendering so we only have half the
precision available to use for height
values. That’s why all of our Terrain
painting shaders clamp the returned
value between 0f and .5f so that we
don’t end up writing signed values
into the heightmap. If you were to put
in values greater than .5, you’ll see
the Terrain surface “wrap” to negative
height values. I can’t say why this
was done but it probably has stayed
this way because it would take a lot
of code changes to make either of them
signed or unsigned to match.

The values are normalized so that we
can get the most precision we can out
of the .5f for a given Terrain’s max
height. 0 being a world height offset
of 0 and .5f being
terrain.terrainData.size.y (the max
height)"

SOURCE