skip to Main Content

Mapbox provides Global elevation data with height data encoded in PNG image. Height is decoded by height = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1). Details are in https://www.mapbox.com/blog/terrain-rgb/.

I want to import the height data to generate terrains in Unity3D.

Texture2D dem = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/dem/12/12_3417_1536.png", typeof(Texture2D));
    for (int i = 0; i < width; i++)
        for (int j = 0; j < height; j++)
        {
            Color c = dem.GetPixel(i, j);

            float R = c.r*255;
            float G = c.g*255;
            float B = c.b*255;
            array[i, j] = -10000 + ((R * 256 * 256 + G * 256 + B) * 0.1f);
        }

Here I set a break point and the rgba value of the first pixel is RGBA(0.000, 0.592, 0.718, 1.000). c.r is 0. The height is incorrect as this point represent the height of somewhere on a mountain.

Then I open the image in Photoshop and get RGB of the first pixel: R=1,G=152,B=179.

I write a test program in C#.

System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap("12_3417_1536.png");
Color a = bitmap.GetPixel(0, 0);

It shows Color a is (R,G,B,A)=(1,147,249,255)

Here is the image I test:
https://api.mapbox.com/v4/mapbox.terrain-rgb/12/3417/1536.pngraw?access_token=pk.eyJ1Ijoib2xlb3RpZ2VyIiwiYSI6ImZ2cllZQ3cifQ.2yDE9wUcfO_BLiinccfOKg

Why I got different RGBA value with different method? Which one is correct?
According to the comments below, different read order and compressed data in unity may result in different value of the rgba of pixel at (0,0).

Now I want to focus on—-How to convert the rgba(0~1) to RGBA(0~255)?
r_ps=r_unity*255? But how can I explain r=0 in unity and r=1 in PS of pixel at (0,0)
?

2

Answers


  1. I will assume you are using the same picture and that there aren’t two 12_3417_1536.png files in separate folders.

    Each of these functions has a different concept of which pixel is at (0,0). Not sure what you mean by “first” pixel when you tested with photoshop, but Texture coordinates in unity start at lower left corner.

    When I tested the lower left corner pixel using paint, I got the same value as you did with photoshop. However, if you test the upper left corner, you get (1,147,249,255) which is the result bitmap.GetPixel returns.

    The unity values that you’re getting seem to be way off. Try calling dem.GetPixel(0,0) so that you’re sure you’re analyzing the simplest case.

    Login or Signup to reply.
  2. Try disabling compression from the texture’s import settings in Unity (No compression). Alternatively, if you fetch the data at runtime, you can use Texture.LoadBytes() to avoid compression artifacts.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search