Cross posting from the Allegorithmic forums.
Alright, so I’ve been messing around a lot with different compression settings and mip maps vs no mip maps on Substance materials recently. Developing for Vive VR means that the player can get right up on objects in a way that’s very different from non-VR games, and quality differences are way more noticeable than normal. Getting the settings down so quality is high but doesn’t impact performance when you have a whole scene using procedural Substances.
I’ve also got some questions about specific settings that I’ll get to later on, as well as some potential bugs.
This is all using a single Substance that I got off Substance Source (maybe Share? it was a while ago, apologies to the author for forgetting). Documentation at least explain the very basics of what things are ideally supposed to do, but… I need to know a little more than that.
This is mip maps vs no mip maps between the different format settings. Main thing I’ve noticed (at least with this material) is the different between no alpha and alpha is that the no alpha version is a bit lighter. Obviously up close no mip maps is higher quality, but there’s an issue with this I’ll get to later.
With mip maps it seems like the highest quality version of the textures ends up blurred, even if you’re very close to it. If there’s a way to mess around with mip map distancing, I haven’t found it. Best I can do is, when making LODs, add different variations of a material to each LOD. Mip maps on distance LODs, no mip map on the very closest LOD on very specific objects, but it’s not always great and I’d rather not have each LOD for an object require its own material if I can get away with it, you know?
Between Raw and Compressed there’s some difference that can be seen, but it doesn’t seem to be big enough to matter all that much in relation to overall file size. To me at least it doesn’t even feel like Raw is higher resolution, just… different. If that makes sense.
Alright, the problem with no mip maps! An obvious problem. No mip maps means that you don’t get the resolution scaled down to blur and fade out nicely at a distance. That’s what mip maps are for. Now, the thing is, in VR especially unless you’re right up close on an object it becomes a noisy swimmy mess of fuzzy pixels that crawls like it’s covered in bugs. Not really what I want out of concrete! The less detail a Substance has in its textures, the less swimmy and noisy it gets. Checks out. More detail attempting to be seen, more crawling mess. This could be fixed with LODs, I suppose, but adding LODs for materials specifically and creating a bunch of high quality no mip maps and low quality plus mip map materials feels like it’s not the most effective way to go. Maybe it is, but it doesn’t feel efficient.
Alright, now we’ve got mip maps versus no mip maps at all resolution settings. Again, it mostly just shows that yeah, mip maps blur things. But the difference between the 2048 mip map vs no mip map is pretty big, and in VR it’s incredibly noticeable. Even if I have a custom shader I’ve created in Designer and lock the export to .sbar at 4k, it still feels fuzzy and pixilated with mip maps on. The number 1 critique I get at work on materials is “This looks too low res. Is this 512? Make it higher.” and it’s a 4k texture. I definitely don’t want to have every single material in the project have to be 2048 or larger. That’s… a huge waste of space and performance. We have over 100 Substances in our game. If each of them were 2k or more? Ridiculous.
Now. Settings. An unusual thing I’ve noticed is that on Substances that have specific outputs, even if you deselect those channels the maps still generate and still attach themselves to the material. This Substance generates an AO map, but it’s solid white. There’s no actual AO detail involved. If the AO isn’t doing anything, I don’t really want it because why do I need a solid white 2k bitmap hanging out in my project doing absolutely nothing? I can delete the connection, but the second I click off the material it reattaches. Boo. And since the material generates the bitmaps, I can’t individually delete them either because that’s not how Substances work. They aren’t like individual texture files, they rely on the Substance material that generates them to exist, and if the material is set to output those bitmaps it’s going to always output those bitmaps. Since a lot of these are materials I got off of Substance Share and Substance Source, they’re .sbar and not .sbs so I can’t easily edit them within Designer unless I bring the Substance into a new graph, set up all the parameters again, and replug in only the outputs I want then export them for every single material.
Does checking and unchecked channels not actually do anything? I’m curious.
Enable Instancing straight-up just doesn’t work on Substances. Maybe it’s a procedural material thing, I’m not sure. But it’s like deleting the connection to unwanted maps. The second I click off the material, that box unchecks itself.
Something I’ve noticed is that when bringing in a Substance material, by default it checks Emission on even if the material doesn’t have an emissive output. Which is odd. It sets the color to black because there’s no emissive, but since I don’t know if it adds anything more to the material, I have to go in and check it off. Weird that a material with zero emissive wants emissive checked on.
The biggest thing I’m a little confused on is Load Behavior. I’ve found a few different explanations on what each does and Unity’s documentation lists out very briefly what they all are. The names are confusing, since for example Bake and Discard Substance is the setting you want if you’d like your Substance to bake out its generated maps and then discard the ability to edit procedural data during play. Now, the descriptions for what each is supposed to do checks out, however it doesn’t appear that Unity actually respects these settings. Often on play even if a material is set to Bake and Discard or Bake and Keep, or sometimes even Bake on Level Load and Cache, the scene will play and those materials are missing. Going back to the Substance in question shows that it never generated the outputs even if I had just been editing that exact material previously and it had generated.
Sometimes the material generates when you click the object, sometimes it’ll generate on level load, sometimes it only generates if you make a change to the Substance and it has to re-generate its outputs. It’s rarely ever the same materials and sometimes this behavior persists through a build bake.
I’ve also noticed that since our team uses Perforce and a cache server, the baked cache for Substances doesn’t always upload with the material. If on one machine I add some materials and make edits to them, apply to prefabs, and save and submit, I can go to another machine and the material won’t have generated but a third machine will. There doesn’t seem to be any consistency.
I definitely don’t want to set everything to bake on level load, since it increases load times by a ridiculous amount and if each time it loaded it baked 100+ Substances? It would take a half hour or more to load our game. Impossible. And I don’t want to have to set all of them to Build on Level Load and Cache so I have all the materials cached, load a level so they build, then set them all back to something else so they don’t build every single time. They definitely don’t appear to be caching properly, though.
There’s no instance in which we have a Substance that is edited during runtime and are not using any Substances with animating textures or parameters.
Now, I know that there’s the option of writing an API to call, build, cache, and do whatever else that I need them to do, but how can I be sure that the API will be respected if the built in settings are not? I personally don’t quite have the experience to write that on my own (I could figure it out eventually but it would take a while and a lot of research) but if it’s the only way, then it’s the only way. I’d rather not have to run a script every time I edit materials, or make anyone else need to either, and I don’t want to add anything that will increase loading times. If there’s a way to build and cache specific things per level and throw out old cache when you move on, that might be a good solution, but it’s also way above my abilities to enact. However, I can pass the info along to our engineers if that’s the best case solution.
Has anyone else dealt with this before? Is this an issue on the Substance side of things, or the Unity integration side? It’s becoming a pretty huge problem for us.
Any other tips or settings that are ideal for Substances would be greatly appreciated. This is the first project I’ve worked on where we’re integrating Substances almost exclusively, so it’s the first time I’ve run into such issues and unknowns.
Using Unity 5.6.1p3, PerForce, a cache server, and a combination of community created and custom Substances. Including Editor Log.
Attached to Bug Report Case 930426
3142267–238467–Editor.txt (111 KB)





