In this blog post we’ll talk about making Mapbox Unity SDK work with URP (Universal Rendering Pipeline). There’s a lot of confusion and discussion about URP/HDRP (and how Unity’s handling those) recently but afraid not, this’ll be a very basic fix for us. But first of all;
What’s the problem?
As you might already know, Unity introduced scriptable render pipelines a while ago, with two default sets, Universal Render Pipeline (used to be called Light Weight Render Pipeline) for performance/mobile apps and High Definition Render Pipeline for next-gen(ish) graphics.
Unfortunately, these new scriptable pipelines are not compatible with good old standard pipeline or its assets. Old materials and shaders simply doesn’t work with the new systems. Also some new unity tools, like Shader Graph, doesn’t even support old standard renderer at all and only work with URP or HDRP.
This is a big problem these days as thousands of assets created in standard pipeline are not working on new systems and require some updates or workaround.
It’s the same issue with Mapbox Unity SDK; it was created using Unity’s standard render pipeline and if you import the package in an URP project now, you’ll see all materials/shaders will be broken. And we’ll look into fixing it for URP today!
Fixing the materials
So let’s say you created a new URP project and imported Mapbox Unity SDK. You entered your api key in Mapbox setup window and want to check out some examples. You ran ZoomableMap demo scene aaaand;
If you switch to scene view and check it out, you’ll actually see a mesh is created, it even has the elevation but…. where are the textures?
Pink is the default color in Unity in case shader somehow malfunctions or simply doesn’t work, so it pretty much says; “there is a problem in the shader”.
And if you check Mapbox Unity SDK materials as well, you’ll see something looks really wrong ;
Luckily, URP comes with an easy auto-fix for this; Upgrade Project Materials to UniversalRP Materials
button under Edit>Render Pipeline>Universal Render Pipeline
menu.
This should update all materials to use URP supported shaders. Now all materials inside Mapbox folders should look fine, not pink at all.
And if you check the demo again, now you should see a grid texture layed upon the terrain mesh. No satellite imagery though so there’s still something slightly off.
Fixing the color map
If you select a tile object from the scene object hierarchy and check its material, you’ll notice that Base Map
field is still set to that black and white grid texture. Everything should be loaded by now, satellite imagery, elevation, everything. And actually if you check the UnityTile
on the very same object, you can see the satellite image in RasterData
field. So things are downloaded, processed but somehow they are not in the material.
The reason for this is how we normally set the material texture. Back in the standard renderer days, we generally used this line to set material textures;
MeshRenderer.sharedMaterial.mainTexture = _rasterData;
and that’s actually just a wrapper for the real thing, real method;
MeshRenderer.sharedMaterial.SetTexture("_MainTex", _rasterData);
But that “real” method is a little uglier and has a magic string in it, right? So most developers tended to use the first option as it often felt simpler. But that’s the problem. That shortened call sets “_MainTex” as you can see in the second call and “_MainTex” was the name of the color map in standard renderer default shaders. But it’s not anymore, not in the URP. (sad face).
Default URP shader uses name “_BaseMap” for color map.
Why? I have no idea really. But if we fix that, we’ll start seeing some colors!
Now if you check UnityTile.cs
file, line 305 (under SetRasterData
method), you’ll find the line we have to fix.
And we replace that with the following line;
If you run the ZoomableMap scene now, it should be working as expected;
About the fix
Even though it’s a relatively easy fix, it’s hard to push that into the SDK itself mainly because there are three common rendering pipelines with different shaders (and color map names) now. And as far as I know there isn’t a good way to detect which rendering pipeline is being used. If we fix it this way in SDK, all standard renderer and HDRP users will have the problem and vice versa. So we might have to wait at least until URP is the default renderer and that’s happening starting from Unity v2020 I believe.
Also I must add, this is only for the terrain material/imagery. You might run into similar issues on vector layer as well, depending on how to style it of course. But the underlying problem is same.
TLDR;
- Change materials to use URP shaders
- Change
UnityTile.cs
to set textures by URP shader field names, instead of usingMaterial.mainTexture.
Final Notes
One final small note; if you ever need to find out, ‘what that field is called”; you can switch to debug
mode in the inspector and check texture fields of your materials.
You will probably need to do this with HDRP as well for example because if I remember correct, HDRP is using a totally different name as well.
But other than that, debug mode is pretty helpful for a lot of other things anyway. I just didn’t want to mention it before to keep main section a little simpler.
I hope you like it! Please let me know if you have any questions. Also feel free to ping me on twitter! I share almost all my work there; @brnkhy
Ah and now that we have it working on URP, I’m thinking of something fancier, maybe like a mask shader for the next post!
See you next time!
MeshRenderer.material.SetTexture(“_BaseColorMap”, _rasterData);
that worked for me
This doesn’t work for me, since Mapbox uses custom shaders. so when I attempt to convert them to URP, I get the: “MapboxStylesFacades material was not upgraded. There’s no upgrader to convert Mapbox/MapboxStyles shader to selected pipeline”.
How do I handle that?
Thank you so much 🙂
Don’t know what happened to my previous comment, but I couldn’t get what you said to work, because I get the following:
“MapboxStylesFacades material was not upgraded. There’s no upgrader to convert Mapbox/MapboxStyles shader to selected pipeline
UnityEditor.Rendering.Universal.UniversalRenderPipelineMaterialUpgrader:UpgradeProjectMaterials()”
got any suggestions on how to get around that?
I’m sorry, blog doesn’t auto approve&publish comments so previous one was waiting for me to approve and I just saw the mail.
I’m not sure what’s wrong there. I can’t remember having issues with that but custom shaders not being updates sounds like a reasonable/possible issue. I wonder if something changed on Unity side and it just worked when I did it.
I don’t have a solution on top of my head and I’ll have to check it I’m afraid.
okay, thank you. I’d love to hear what you find out 🙂