[FREE]MicroSplat, a modular terrain shading system for Unity Terrains

2 Likes

Hi.

Has anyone tried MicroSplat on a (recent) android phone?
On my laptop MicroSplat performs just great. Whatever i throw at it, my framerate is about the same.
Even when compared to the legacy diffuse terrain shader. And it looks so much better.
But when i had my weekly Phone test session, my framerate dropped from 60 to 20 fps.
Phone specs :

Chipset Qualcomm MSM8953 Snapdragon 625
CPU Octa-core 2.0 GHz Cortex-A53
GPU Adreno 506

My MicroSplat settings are all basic and fastest, and i am so far using 6 textures (512)
I am totally hooked on how my terrain looks with MicroSplat, but obviously 40fps drop is weird.

I’ve done a fair bit of profiling on iOS using instrument’s GPU capture, but haven’t looked at it in an android GPU profiler yet (not sure there’s a good one out there?). An interesting test without GPU capture would be to see if you are memory or ALU bound. You can do this by simply moving the camera away from the terrain, such that everything uses a lower mip map. If this increases your framerate substantially, you know that you are bound by the amount of texture data it has to read. If not, then it is most likely bound by arithmetic instructions.

1 Like

I did a quick test and found that moving away from the terrain indeed get’s my framerate back up to 60.
As soon as i get closer…
So, memory bound it is.
I’ll try the k256 setting and report back to you :slight_smile:

Unfortunately the k256 setting didn’t help much. Maybe a fraction faster.
Is there anything else we can try or am i doomed to a crappy looking terrain?

You can set the blending mode to fastest, which will limit the number of sampled texture sets to 2 per pixel. This should make it faster than a Unity terrain shader in most cases, since (if it was on a 4 texture terrain) it would have to sample 4 sets of textures. You can also set the max texture setting down to how ever many textures your terrain actually uses- I don’t think this will be a big difference, but likely worth doing anyway. Other things to try are removing any features or per-texture properties to see if they are the bottleneck. PerTexture properties are stored in a very small texture, which means they are a dependent texture read, but since the texture is tiny the actual performance cost is very low, but on a mid-range mobile chipset this may have an effect.

The real thing to do is to get this under a GPU profiler on your chipset- good ones will show you what percentage of the time is spent on each part of the shader, allowing you to easily figure out where the bottleneck is. I’ll look into doing this on Android soon, but it will likely be after Unite, and the hardware on android varies so much that it’s unlikely we’ll see the exact same results. If you want to move forward on this yourself, I would suggest the following:

With everything off, there are two parts of the shader that potentially make it more expensive than the Unity shader. Both are pretty easy to hack out, so you can see if either of them is part of the performance bottleneck. The first is the Setup routine- this routine is a pre-optimization step the shader runs to determine the minimal set of samples it needs to make. Setup returns a set of weights and indexes, if you hack out this function to return a fixed set of weights and indexes (weights as 0.5, 0.5, 0, 0 and indexes as 0,1,2,3, for instance), then it would screw up the look of the shader, but remove the performance cost of doing this step. The other is the ComputeWeights function, which could just return the input weights, skipping the height based blending all together. Also, if you attempt this, make sure to either do it in the fragment files, or do it in BOTH shaders the system produces.

Thank you so much for your in depth answer. I’ll get into GPU profiling. Never done it before, but i’ll figure it out.
Need that skill anyway.
I will also try your suggested hacks and get back on that.

Please let me know what you find- so many android devices, if we can find the bottleneck, I’m sure we can come up with something…

I need to set up several terrain materials for different platforms/quality levels, but I’ve run into a weird problem: If (on the Terrain settings), I switch the terrain to the default terrain shader, then switch back to Custom and assign the Microsplat material, the terrain shows only the first splat. I have to go to that MS material and slide the Per Texture Properties slider righward, and then the other splats appear. Any ideas?

(Happens with your Demo scene too, at least the one in Core.)

I’m on MBP with AMD 560, happens with both Metal and OpenGL editor.

thx
Dave

Each terrain has it’s own copy of the material- it doesn’t actually use the template material directly. Whenever you change the template material in the editor, it automatically syncs the changes across all the terrain’s internal materials. So if you change the settings via code or outside of the editor, you need to sync those changes across these internal materials- that’s what the Sync All button does- but when you change a property on the material, it effectively calls this for you.

So if you are going to setup multiple LODs, you need to call MicroSplatTerrain.SyncAll() after the change is made to propagate those changes from the template material to all the internal materials the terrain uses.

Got it, thanks!

I encountered the same problem with one of my terrains. The problem turned out to be caused by varying values for the per texture UV scale. If only the global UV scale is used, or if per texture UV scale is used but all values are the same, there is no issue. Varying the UV scale for different textures causes the problem.

Most likely it’s something with the texture derivatives being computed differently for neighboring pixels of different texture indexes. I had coded a fix for this a while back, but then couldn’t seem to get it to happen without the fix, so backed out of it. I’ll see if I can get it happening again and figure out what my fix was…

1 Like

Streams/Lava, and the alpha hole module are finally out - after 24 days of waiting in line:

3 Likes

MicroSplat 1.1 submitted for review, with all modules updated. Please note that this is an internal version changing upgrade, which means that all modules need to be updated together, so please check the asset store version numbers before upgrading. Here’s the change list:

MicroSplat 1.1

  • Global Texturing Changes

  • Added distance mode to global normal/tint textures

  • Added opacity at near/far distance to global normal/tint textures

  • Added ability to warp Geo texture with an animation curve

  • Terrain Blending module

  • can now blend terrain on the tops of objects with a separate slope filter slider

  • You can now paint terrain blending strength in the color.a channel of your mesh, so you can blend a flat piece of geometry with the terrain, then paint 0 into the areas you was to show the original texture instead of the terrain.

  • Streams/Lava Module

  • ā€œHeightWetnessā€ added to the streams module, allowing you to specify a wetness level based on height which can be animated up and down for shorelines

  • Core Module

  • Modules you already own removed from ad carousel

  • Added lighting mode option that allows you to force a particular BDRF for Unity’s lighting. When doing so, the terrain will be forced to render in forward rendering mode.

  • You can now disable height based blending for a speed boost on low end platforms

  • Fixed issue with lighting being too dark on terrain blended objects in deferred when in shadow

  • Hash id added to fallback name to prevent naming conflicts causing the fallback to find the wrong shader

  • Fixed issue with Undo on PerTexture properties

  • AntiTiling Module

  • Fixed issue with 2nd and 3rd normal noise not being applied when per texture properties are enabled

2 Likes

Cool! I’ll definately try the Streams/Lava module~Was the triplannar module submitted after these two and still needs waiting, Mr Booth?

These fixes would be very helpful! Looking forward~

Submitted at the same time - it was rejected for a trivial issue, so I resubmitted it with the 1.1 update tonight. Hopefully it’ll all come out at the same time reasonably soon. Updates have only been a few days for me lately, it’s just new assets that seem to be taking a while.

Eventually will definitely own all microsplat module. Using them one by one.

Any chance you can create a texture streaming module. Much like granite Unity Asset Store - The Best Assets for Game Making . But with all the beautiful features of microsplat.

For the most part they are two ways to solve the same issue - splat maps are a form of compression- low res control data used to paint blends between highly tiled textures to produce a highly detailed terrain. Where as virtual texturing systems are about having a really, really large and highly detailed texture that you load/decompress for the areas around you. Each has an advantage, but they don’t really work together.

Regular old loading techniques should be good enough to load in any non-splat map data in use, such as tint textures, control textures, etc. The compression used in streaming systems is also not a good fit for this kind of data, since it is usually based around lossy jpg compression, which is designed around perceptual colors- not data.

1 Like