Loading height maps and textures? #72
-
This add-on is brilliant and most probably the best add-on I have ever seen for Godot! Well done! I am trying to build a terrain based on real world data, where I have a height map for the elevation, but also shape files for different types of terrain. For instance, one shape file for forest, one for fields and one for water. So, any idea how I can convert a red/black image to the resource file you are using for the zones? Best regards and thanks for the good work! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 9 replies
-
Hey @niklasking ! I'm so glad you enjoy what I've done! So, the whole system is based on heightmaps, as long as you have ImageTexture resource in Godot, you should be able to use it in the zones. I made a quick test here, I took a heightmap from new york (only the area with the squares) : and I made a script to convert the resulting image into 4 zones : Obviously my source image is not really precise but that gives you a picture of what could be done. This was just a quick test, but here's what I did to generate the zones images : public void Test() {
var heightmap = ResourceLoader.Load<Texture2D>("res://Tester/heightmap.png");
var image = heightmap.GetImage();
float factor = 10.0f; // Just a simple factor to increase height
// Generate 4 zones from the original image (the original image is 1080x1080 so each zones will be of 540)
/// The -1.3f is the minium height for this zone and the 106f is the maximum height for this zone
GenerateImageTextureForZone(image, 0, 0, 540, -1.3f, 106f, factor);
GenerateImageTextureForZone(image, 1, 0, 540, -1.3f, 106f, factor);
GenerateImageTextureForZone(image, 0, 1, 540, -1.3f, 106f, factor);
GenerateImageTextureForZone(image, 1, 1, 540, -1.3f, 106f, factor);
}
private void GenerateImageTextureForZone(Image image, int zoneX, int zoneY, int size, float min, float max, float factor) {
var newImage = Image.Create(size, size, false, Image.Format.Rf); // Create a RF image
var startingX = size * zoneX;
var startingY = size * zoneY;
for (var x = 0; x < size; x++) {
for (var y = 0; y < size; y++) {
var toX = x + startingX;
var toY = y + startingY;
var pixel = Colors.Black;
try {
pixel = image.GetPixel(toX, toY);
} catch {
// Throw an actual exception, this was just for testing
}
var heightValue = Mathf.Remap(pixel.R, 0f, 1f, min, max) * factor;
newImage.SetPixel(x, y, new Color(heightValue, 0, 0, 1f)); // Set the red channel value (we are on a RF image so only the red channel is relevant)
}
}
var imageTexture = ImageTexture.CreateFromImage(newImage);
ResourceSaver.Save(imageTexture, $"res://Tester/h_{zoneX}_{zoneY}.res"); // Save the image as a resource so we can use it in the zones.
} Does that make sense to you ? 🙂 |
Beta Was this translation helpful? Give feedback.
-
Hey @niklasking ! |
Beta Was this translation helpful? Give feedback.
Hey @niklasking !
I'm so glad you enjoy what I've done!
So, the whole system is based on heightmaps, as long as you have ImageTexture resource in Godot, you should be able to use it in the zones.
For the heightmap itself, I use the RF format (OpenGL texture format GL_R32F where there's one component, a 32-bit floating-point value.) so I can have somewhat precise values that goes over 255.
I made a quick test here, I took a heightmap from new york (only the area with the squares) :
and I made a script to convert the resulting image into 4 zones :
Obviously my source image is not really precise but that gives you a picture of what could be done.
This was just a quick test, but here's wh…