I verified it is 16 bit. However the only way I could get it too work was to load a r16 file and put each byte into an image and assign to a usampler2D slot in GDScript.
I could kind of get it working by dragging the EXR image onto a samlper2D slot in the material, but the data wasn't quite complete. It looked like it was still only reading from one channel.
Anyway, this is the code I used to get it working (from the link I posted earlier)
func _createHeightMapTexture(sourceMap: TerrainMap):
var image = Image.new()
var data = PoolByteArray()
data.resize(1024 * 1024 * 2)
var mapX = 0
var mapZ = 0
var index = 0
for z in 1024:
for x in 1024:
data[index] = sourceMap.getByte(mapX + x, mapZ + z, 0)
data[index + 1] = sourceMap.getByte(mapX + x, mapZ + z, 1)
index += 2
image.create_from_data(1024, 1024, false, Image.FORMAT_RH, data)
#image.save_exr("res://Terrain//Data//Map.exr")
var texture = ImageTexture.new()
texture.create_from_image(image, 0)
material.set_shader_param("heightmap", texture)
And in the vertex shader;
uniform usampler2D heightmap;
uvec4 godot_hack_mix(uvec4 a, uvec4 b, bvec4 c) {
return uvec4(c.x ? b.x : a.x, c.y ? b.y : a.y, c.z ? b.z : a.z, c.w ? b.w : a.w);
}
uvec4 getExponent(uvec4 data) {
return godot_hack_mix(uvec4((uvec4((ivec4((data & uvec4(0x7F800000)) >> uvec4(23)) - ivec4(127)) + ivec4(15)) & uvec4(0x1F)) << uvec4(10)),
uvec4(ivec4(31 << 10)),
equal((data) & uvec4(0x7F800000), uvec4(0x7F800000)));
}
uvec4 getValue(uvec4 data) {
uvec4 exponent = getExponent(data);
return godot_hack_mix(((data & uvec4(0x007FFFFF)) >> uvec4(13)) | exponent | (((data >> uvec4(31)) & uvec4(1)) << uvec4(15)),
(((floatBitsToUint(uintBitsToFloat(data & uvec4(0x7FFFFFFF)) + 1.0/16384.0) & uvec4(0x007FFFFF)) >> uvec4(13))) | (((data >> uvec4(31)) & uvec4(1)) << uvec4(15)),
lessThanEqual((data) & uvec4(0x7F800000), uvec4(0x38000000)));
}
float getMapValue(int x, int z) {
uvec4 data = texelFetch(heightmap, ivec2(x, z),0);
data = getValue(data);
return float(data.r) / heightScale;
}