Topic: Markers Render Order

Hello,
I would like to ask about the following problem:

I have different types of markers. Each type has its own texture. Because of this, different material is instantiated for each texture.

I am using TilesetControl for map rendering.

When markers are rendered, I have to be able to control the sort order when rendering.

Sorting with custom "markerComparer" or through "OnGetFlatMarkerOffsetY" is working as intended only when markers are using the same material.

When markers with different materials overlap, I can not control their order through any of these methods.

I'd like to ask is there any way to control the sort order of markers with different materials, built in your plugin?

Also, I looked through the TilesetControl code and found out there is no way to manipulate the markers mesh generation process. That's why I would like to ask if there is any way to manipulate the mesh, without manually figuring out the mesh properties for every marker, that is not culled.

If I could access the UVs for every marker or add colors for markers' vertices, I can work out a way to render different markers with one material only.

Thank you!

Re: Markers Render Order

Hello.

In general, how can you manipulate the display order of GameObjects:
1. Distance to the camera.
2. renderQueue of the material or shader.

Right now you can not use renderQueue for each marker separately, because they are grouped by texture into single mesh (for performance reasons).

What can we do to help you work around this problem:
Add the ability to generate markers in separate GameObjects, and add an action for postprocessing this object (mesh and material).
In this case, you will be able to accurately manipulate the display order of markers using renderQueue.

This way is suitable to solve your problem?
If you have other suggestions how to work around this, we can discuss it.

Kind Regards,
Infinity Code Team.

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

Re: Markers Render Order

Hello.

In our case, we have to be able to click on a marker and render this marker on top of every other. Separating this single marker to a different gameObject with separate material will solve the problem.

The things I could think of are:

I played aroung with your TilesetControl and implemented very simple atlasing. When generating the markers mesh I manipulated
the UVs for each marker that was to be added to the mesh so that they map properly to the atlas. However, doing this requires
scaling the marker width/height separately based on the atlas mapping.

Using atlasing does not allow controlling the order of markers with different materials as well. However it should allow quite many different variants of marker textures, baked together, to be used in a single mesh.

Without modifying your code, I can access generated mesh only through the game object.This way I am not aware what mesh properties to which marker correspond.

Possible solutions are:
- To be able to access a collection of markers, involved in the current marker mesh generation. The order of the collection will correspond to the order of UVs/Colors/Vertices array in the mesh. This way I can modify modify/add mesh properties after it is generated.
- To be able to supply UVs externally.
- To be able to supply vertex colors for each marker. For simple cases, I can use this to blend different textures in the shader. I can even use it to animate the markers on the GPU. Right now, vertex colors are unused.

Thank you!

Re: Markers Render Order

Using atlases is an interesting idea.

This way is suitable for your needs?

using System.Collections.Generic;
using UnityEngine;

public class ModifyMarkerUV:MonoBehaviour
{
    private Color[] typeColors = {Color.red, Color.blue, Color.green, Color.yellow};
    private List<Color> colors;
    private List<Vector2> uv;
    private Texture2D markersAtlas;

    private void OnGenerateMarkerVertices(OnlineMapsMarker marker, List<Vector3> vertices, int index)
    {
        int type = ((CData)marker.customData).type;

        float sx = type % 2 / 2f;
        float sy = type / 2 / 2f;
        float ex = sx + 0.5f;
        float ey = sy + 0.5f;

        Vector2 uvp1 = new Vector2(sx, ey);
        Vector2 uvp2 = new Vector2(ex, ey);
        Vector2 uvp3 = new Vector2(ex, sy);
        Vector2 uvp4 = new Vector2(sx, sy);

        uv.Add(uvp1);
        uv.Add(uvp2);
        uv.Add(uvp3);
        uv.Add(uvp4);

        Color typeColor = typeColors[type];
        colors.Add(typeColor);
        colors.Add(typeColor);
        colors.Add(typeColor);
        colors.Add(typeColor);
    }

    private void OnSetMarkersMesh(Mesh mesh, Renderer renderer)
    {
        mesh.colors = colors.ToArray();
        mesh.uv = uv.ToArray();

        colors.Clear();
        uv.Clear();
    }

    private void Start()
    {
        colors = new List<Color>();
        uv = new List<Vector2>();

        OnlineMapsTileSetControl.instance.OnGenerateMarkerVertices += OnGenerateMarkerVertices;
        OnlineMapsTileSetControl.instance.OnSetMarkersMesh += OnSetMarkersMesh;

        OnlineMaps map = OnlineMaps.instance;

        double tlx, tly, brx, bry;
        map.GetTileCorners(out tlx, out tly, out brx, out bry);

        for (int i = 0; i < 20; i++)
        {
            double tx = (brx - tlx) * Random.Range(0f, 1f) + tlx;
            double ty = (bry - tly) * Random.Range(0f, 1f) + tly;
            map.projection.TileToCoordinates(tx, ty, map.zoom, out tx, out ty);

            OnlineMapsMarker marker = map.AddMarker(tx, ty, markersAtlas, "Marker " + (i + 1));
            marker.customData = new CData
            {
                type = Random.Range(0, 4)
            };
        }
    }

    internal struct CData
    {
        public int type;
    }
}

Of course, this code will only work in a new (not yet published) version Online Maps.
I need to know that this is exactly what you need before we publish it.

Post's attachments

Attachment icon img1.png 827.99 kb, 64 downloads since 2017-08-23 

Kind Regards,
Infinity Code Team.

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

Re: Markers Render Order

Yup,
This will do the job.

One thing though: Have you thought of adding the ability to control width and height of the marker separately?

With this and the implementation you presented, atlas mapping, independent of atlas' aspect ratio, will be easy to do.

At the moment, only UV maps with the same aspect ratio as the atlas texture look fine, as the marker uses the texture size for reference and the "scale" property scales both width and height proportionately.

Thank you!

Re: Markers Render Order

Yes, I missed it.

OnlineMapsMarker marker = map.AddMarker(tx, ty, markersAtlas, "Marker " + (i + 1));
marker.Init(512, 256); // Custom width, height

The new version is already available.

Kind Regards,
Infinity Code Team.

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

Re: Markers Render Order

Great! Thank you.