x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How does Unreal store height information of a Landscape?

I have difficulties in accessing the height information (per vertex) of a landscape in C++.

There is literally zero documentation for the Landscape classes (ALandscape, ULandscapeComponent etc.) within the engine code. Which makes things really really hard. I have following issues and questions:

  • How does unreal store height information? What is the main source of this data and where is it kept?

  • Is it kept inside HeightMapTexture variable of type UTexture2D within ULandscapeComponent? Is it always filled?

  • If HeightMapTexture is the main source this data, when is it filled? Can I access heightmap information from C++ code at editor time (not at run-time)?.

  • Why doesnt UTexture2D have some friendly interface methods to read/access pixels directly? (Just like Unity3d) why does it have to be this hard?

  • I've read in the below link that the pixel values of the UTexture2D is kept in the PlatformData variable. But accessing this data the way below gives me a nullpointer mip map data so it does not work.

link text

  • I've read somewhere else (dont remember the link) that the PlatformData variable is only initialized at run-time and is not set during editor time. There was another variable called Source within the UTexture2D which is supposed to keep this data at Editor time. I tried reading this with the following code:

            FTextureSource & hmap_texture = (*i)->HeightmapTexture->Source;
             check(hmap_texture.IsValid());
     
             FColor * hmap_data = (FColor*)hmap_texture.LockMip(0);
             for (int x = 0; x < hmap_size_x; x++) {
                 for (int y = 0; y < hmap_size_y; y++) {
                     FColor height = hmap_data[y*hmap_size_x + x];
                                     //TODO:Use height here...
                 }
             }
             hmap_texture.UnlockMip(0);
    
    

However this time all values written to height is gibberish. Visual Studio Debugger shows strange characters for the FColor channels instead of meaningful grayscale values.

  • What is the format of the height map. Unreal says it is TSF_BGRA8. But I suppose the height map is supposed to be grayscale image with a single 16 bit channel. How come the format becomes a 4 channel 32 bit image? Should I expect the height color (FColor in the code above) to have all channels equated to the same value (if I can successfully read it). Or am I suppose to convert the first two channels (or last two channels whatever) to 16 bit somehow to get the accurate data.

I would greatly appreaciate all help.

Product Version: UE 4.16 Preview
Tags:
more ▼

asked May 04 '17 at 03:09 PM in C++ Programming

avatar image

Matiati
154 17 20 39

avatar image Matiati May 04 '17 at 03:38 PM

Basically all I want is as simple as getting the height (either as16 bit uint or something else) at each vertex of the landscape.

This problem (although it is very trivial) kept me occupied for more than a week now.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

I had to dig deep into the UE code but I think I've found the answer.

The height map pixels use 32bit (4 channel) RGBA format. The first two channels represent the 16 bit height map. Therefore you need to bit shift the R channel by 8 bits and then use logical or operator to get the actual height. Se the code sample I've posted above and plug the below piece of code.

 ...........
 uint16 height_value = (height.R << 8) | height.G;
 ...........

The B and A channels encode the tangents of the height map.

The first mip map (0) gives the full resolution height map. Other mip maps are divided by 2 in order. Also terrain mipmaps are generated differently than other texture mipmaps and they consider the 16 bit height values in the first two channels. Therefore it is safe to use the higher index mip maps (with lower resolution) if you desire.

Unreal height maps range from -256 to 256 meters within the scene. Therefore the height map having uint16:max would correspond to 256 meters. Of course you also need to take the Landscape actors scale into account. The z axis scale can effect this value in the game.

Another issue is that I think that the ULandscapeComponent's HeightMapTexture members all correspond to the same height map that is the landscape height map. When I see this member within the ULandscapeComponent I thought that all components of the landscape do keep their own vertex height data within a separate texture. But this was wrong. So you need to sample the one and the unique Landscape actor heightmap for each vertex within a component if you want to export this height data somewhere.

more ▼

answered May 12 '17 at 03:15 PM

avatar image

Matiati
154 17 20 39

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question