Topic: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Hey there,

I have a project where I have a 3072x3072 OnlineMaps Map tile which the user interacts with, and I'm trying to make it so that specific terrain textures generated with RealWorldTerrain will load in instead of the default OnlineMaps map when I zoom into a specific area.

I.e., if I zoom in to the area surrounding Mt. Fuji, say coordinates 35.365 / 138.641 TL, 35.295 / 138.7295 BR, how can I make it so that a RWT pre-generated texture is what is displayed to the user.

I had a quick search for any related posts and found this https://forum.infinity-code.com/viewtopic.php?id=1133, but the issue is I want the RWT texture to be loaded at a given zoom, or otherwise, just always displayed instead of the map at that location.

From the documentation for OnlineMaps, I added the connector component to the generated RealWorld Terrain object but wasn't able to figure out how to integrate it with the map.

Sorry for the long-winded question, and any and all help is appreciated. Thanks!

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Hello.

Theoretically, this is possible if you have programming experience.

To do this you have two ways:
1. Subscribe to OnlineMapsTileManager.OnStartDownloadTile.
Convert the terrain boundary coordinates and tile boundary coordinates to Mercator projection (OnlineMapsUtils.LatLongToMercat).
Create a new texture, get the required pixels from the terrain texture and set them to the new texture, and set the new texture to the tile.
https://infinity-code.com/atlas/online- … ample.html

2. Subscribe to OnlineMapsTileSetControl.OnDrawTile. When this event is fired, replace the material texture to terrain texture, calculate Tiling and Offset based on boundaries in the Mercator projection, and set that to the material.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

I appreciate the reply! I'll see if I can figure either of these out, although as you mentioned they sound pretty intensive. Will likely have some questions along the way.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Hey again,

I'm looking at the second method you gave and wondering how the tiling / offset should be calculated, as I can't wrap my head around their exact function.

Does tiling refer to the coordinates / bounds of the tile that I wish to alter?

Is offset the distance from the boundaries of said tile that I wish to display the new texture? (And if this is the case, could I keep the initial material of the tile and overlay the RWT terrain texture over the top, for a seamless transition between the two?)

Finally, with the tiling and offset calculated, would I use an OnDrawTile(targetTile, material) method, subscribed to the OnDrawTile event as you mentioned, to set the tile, or SetTileMaterials?

Appreciate any thoughts, and  thanks in advance.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Something like that:

using UnityEngine;

namespace InfinityCode.OnlineMapsSupport
{
    public class TextureFromRWT : MonoBehaviour
    {
        public double top;
        public double left;
        public double bottom;
        public double right;

        public Texture2D texture;
        public Texture2D emptyTexture;

        public OnlineMapsTileSetControl control;

        private double mx1, my1, mx2, my2;

        private void Start()
        {
            control.OnDrawTile += OnDrawTile;
            mx1 = left;
            my1 = top;
            mx2 = right;
            my2 = bottom;
            OnlineMapsUtils.LatLongToMercat(ref mx1, ref my1);
            OnlineMapsUtils.LatLongToMercat(ref mx2, ref my2);
        }

        private void OnDrawTile(OnlineMapsTile tile, Material material)
        {
            OnlineMapsVector2d topLeft = tile.topLeft;
            OnlineMapsVector2d bottomRight = tile.bottomRight;

            double tmx1 = topLeft.x;
            double tmy1 = topLeft.y;
            double tmx2 = bottomRight.x;
            double tmy2 = bottomRight.y;
            OnlineMapsUtils.LatLongToMercat(ref tmx1, ref tmy1);
            OnlineMapsUtils.LatLongToMercat(ref tmx2, ref tmy2);

            if (mx1 > tmx2 || mx2 < tmx1 || my1 > tmy1 || my2 < tmy1)
            {
                material.mainTexture = emptyTexture;
                material.mainTextureOffset = Vector2.zero;
                material.mainTextureScale = Vector2.one;
                return;
            }

            material.mainTexture = texture;
            double ox = (tmx1 - mx1) / (mx2 - mx1);
            double oy = (my2 - tmy2) / (my2 - my1);
            double sx = (tmx2 - tmx1) / (mx2 - mx1);
            double sy = (tmy2 - tmy1) / (my2 - my1);
            material.mainTextureOffset = new Vector2((float)ox, (float)oy);
            material.mainTextureScale = new Vector2((float)sx, (float)sy);
        }
    }
}

For Online Maps v3.8+:
You should use control.OnUpdateMapSubMeshLate instead of control.OnDrawTile.

Important note: This will only work correctly when the tile is entirely inside the texture area. If the tile is partially behind a texture you will get a visual artifact.

Additionally, this script requires a small change to OnlineMapsTileSetControl.cs.
Remove line 993:
if (OnDrawTile != null) OnDrawTile(targetTile, material);
Add a line to the end of UpdateMapSubMesh method (line ~1239):
if (OnDrawTile != null) OnDrawTile(tile, material);

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

6 (edited by ramstairs 2022-06-08 13:56:10)

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

With that script I was able to get the RWT texture displaying at the right coordinates so thank you!

I'm having an issue where its the only texture that gets displayed, but I'm thinking this could be because every tile that gets drawn is going through TextureFromRWT, and if not in the bounds of my terrain texture they are set to empty. I should be able to fix this no problem with conditionals.

However, another thing I was wondering about which I'd hoped using RWT texture might fix, is with OnlineMaps, while up close there seems to be a gloss effect, or a sheen to the map's surface which can make things look odd (as pictured below). Maybe this is just a simple problem, but figured I'd ask.

Thanks again for all the help!

Post's attachments

Attachment icon Screenshot 2022-06-08 112558.png 595.35 kb, 39 downloads since 2022-06-08 

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

What shader do you have in Tileset / Materials & Shaders / Tileset Shader?
Try to use unlit shader.
If you are using Built-in RP, the shader is included.
If you are using URP or HDRP, TilesetPBRShader => Open Shader Graph => Material - Unlit => Save.

Post's attachments

Attachment icon Tileset Unlit.shader 1.64 kb, 61 downloads since 2022-06-09 

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Changing the material in the shader graph did the trick, much appreciated!

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

Wanted to say thanks for the help again, managed to get RWT textures loading  in at various locations across the OnlineMaps map asset.

Also with the visual artifacts you mentioned at the edges of the texture being loaded in, if anyone is trying to do the same thing, I managed to fix it by setting a variable to the initial texture of the tile when the OnDrawTile method is called, then if the tile lies outside on DIRECTLY on the boundary of the RWT texture's coordinates, reset it's texture to its initial texture. Otherwise, proceed with the:

material.mainTexture = texture;
            double ox = (tmx1 - mx1) / (mx2 - mx1);
            double oy = (my2 - tmy2) / (my2 - my1);
            double sx = (tmx2 - tmx1) / (mx2 - mx1);
            double sy = (tmy2 - tmy1) / (my2 - my1);
            material.mainTextureOffset = new Vector2((float)ox, (float)oy);
            material.mainTextureScale = new Vector2((float)sx, (float)sy);

- at the bottom of the TextureFromRWT script.
This might be obvious or useless information, but I figure if anyone else was trying to do the same thing, this could be of use.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

I, thank you for the discussion, i'm trying to do the same, I have a question if I can?
How did you transform the RealWordTerrain texture in tiles, I can create a big mesh with a big texture from RWT but to load into OnlineMaps i imagine that this texture has to be converted in tiles, I have to use a second software like MapTiler or there is a function integrated that I don't find?

Thank you

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

The way shown here works without converting to tiles.
If you want to convert to tiles, then you must load them using OnlineMapsTileManager.OnStartDownloadTile event.
Examples of how this should work are in the atlas of examples.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: Displaying RealWorldTerrain textures in place of the OnlineMaps Map

For Online Maps v3.8+:
You should use control.OnUpdateMapSubMeshLate instead of control.OnDrawTile.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.