Search Unity

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

Discussion in 'Assets and Asset Store' started by jbooth, Aug 9, 2017.

  1. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Yup
     
  2. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    Hey, loving the system so far! The only issue I have is that anti-tiling features seem to be corrupting the normals, making the shader write bent or maybe non-normalized normal vector to the gbuffer. Curiously enough, I'm unable to reproduce this reliably - I saw the issue when I enabled three normal noise maps and compared gbuffer state with the feature turned off, but when I switched the features on again, the lime-colored incorrect normals no longer returned. Not sure what's up - maybe there is some quirk with shader compilation and reloading.

    The issue manifest itself by occasionally making terrains reflect light at weird angles or at too high of an intensity, it's pretty easy to spot when that happens. I'll make a screenshot if I'll manage to catch this again. It's noticeable even in your anti-tiling demo video, where terrain becomes noticeably shinier when you turn on the different normal noise features.

    Update: While issue was most prominent with "Normal Noise" feature but disappeared after toggling it on and off, "Distance Noise" seems to have same issue which persists after toggling - it's more subtle, but definitely noticeable. The issue with distance noise is probably down to your implementation of normal strength scaling. No matter how normal map is scaled, it generally shouldn't affect average brightness or lighting reflection like this if the result is correctly normalized and remapped. There might be some unintentional bending or non-normalized vector at play; or maybe the shader just grabs incorrect channels (since Distance Noise normal is using a non-standard normal map):



    While I can't make a gif of an initial issue with "Normal Noise" feature, it looked exactly like negative strength scaling on this gif (added brightness and a long linear highlight rolling over the terrain).

    P.S.: Not sure if this is related, but I'm got this error in the log multiple times while I toggled and tweaked these normal/tiling related features:

    Code (csharp):
    1. Material doesn't have a color property '_DistanceNoiseScaleStrengthFade'
    2. UnityEditor.AssetDatabase:Refresh()
    3. MicroSplatCompiler:Compile(Material, String) (at Assets/Packages/MicroSplat/Core/Scripts/Editor/MicroSplatShaderGUI_Compiler.cs:423)
    4. MicroSplatShaderGUI:TriggerCompile() (at Assets/Packages/MicroSplat/Core/Scripts/Editor/MicroSplatShaderGUI.cs:247)
    5. UnityEditor.EditorApplication:Internal_CallDelayFunctions()
     
    Last edited: Mar 4, 2018
  3. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    One thing I'd like to suggest is swapping BlendMult2X for simplified Overlay blending to apply detail like albedo-altering Z component of distance noise map. Multiplication can darken the result and is a bit hard to control, since the jump in average brightness depends on both maps. Overlay blending method preserves average brightness of the base texture, darkening anything under detail which is darker than 0.5 gray and brightening anything under detail which is brighter than 0.5 gray - I'm using it pretty extensively for detail mapping. Makes authoring detail maps very easy and predictable - just start with 0.5 gray, then add a Multiply layer for dark parts, Screen layer for bright parts, slap a High Pass filter on top to be sure you're in the right range, etc.

    Here is the code for that blending approach:

    Code (csharp):
    1. float3 Overlay(float3 src, float3 dst)
    2. {
    3.     return lerp (1 - 2 * (1 - src) * (1 - dst), 2 * src * dst, step (src, 0.5));
    4. }
    P.S.: Whoops, I see you already have an overlay method in the utilities. It's a bit different from mine, but I imagine it would work just fine here too.
     
    Last edited: Mar 4, 2018
  4. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    Ah, I found the source of the issue with distance noise! Toying with Overlay and not seeing any difference in undesirable albedo darkening made me realize there is an issue with source texture data. I took a look at the Z channel of your distance noise map, and it was perfectly centered around 0.5 gray. Which left only one possible reason for darkening after blending - microsplat_def_detail_noise was sampled in sRGB mode. Fixing it's import settings immediately fixed albedo noise blending and completely fixed all issues with normal corruption to boot - even enormous strength factors no longer break normal mapping!

    Might be worth checking all composite maps and arrays for this sort of thing, just in case some other map slipped through and is using sRGB instead of proper linear sampling.



     
    Last edited: Mar 4, 2018
    boysenberry and camta005 like this.
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Strange - that texture is linear in my project. But I like the idea of a warning about it in the editor. I find that most people have no idea about linear vs gamma, and it can make a huge difference..
     
  6. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    That would be great and would match the Unity convention of warning about incorrectly imported normal maps! :)
     
  7. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    One possible area where checking sRGB might be worthwhile. The texture array generator allows you to grab PBR component data from channels of different textures. For example, you can set Smoothness slot to alpha and plug CTS-style albedo RGB + smoothness A maps into both Albedo and Smoothness slots of the MicroSplat array config. Some other texture libraries often pack height or AO into alpha of the albedo. One gotcha with reading the alpha channel in this case is the fact that all albedo maps are always sRGB, while smoothness/AO/height data must be linear. It's worth applying an sRGB to linear conversion to colors extracted from alphas like that (unless I'm misremembering how RGBA maps work and alpha is always linear no matter the texture mode).
     
  8. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Alpha channels are always linear. Only the RGB portion is gamma, because it's the only part that's a color. I considered forcing the data read from other channels to be linear when read, but decided against it because each time the packer ran it would have to adjust the texture settings, then put them back, which would require a reimport. On top of that, because people can write a custom importer, it could also get into an endless loop if the user has an import script that sets the texture back to sRGB..
     
  9. bac9-flcl

    bac9-flcl

    Joined:
    Dec 5, 2012
    Posts:
    778
    Gotcha, makes sense!

    By the way, it seems that Gradient sampling mode has no effect on per-texture scaling edge artifacts, though I'm not sure it's the same artifact you are mentioning in the overview video (I think you described individually popping black pixels, not aliased averaged color lines which are completely stable temporally). Here is how edge between differently scaled textures looks for me:


    The artifact only disappears when LOD sampling is used, but it's not exactly useful for scaling along the lines of 0.5x-2x due to large textures becoming blurry - as you mentioned in the overview video, LOD mode is mostly useful for slight side adjustments. Some details are probably relevant:

    • I'm using NVidia GTX1080 with latest drivers as of 04.03.18
    • My project is using linear lighting and deferred rendering
    • My OS is Windows 10 x64
    • I'm using shader model target 50
    • The artifact looks exactly the same no matter whether texture scale is 0.5 or 0.999
    • The artifact is very stable temporally and can't be temporally anti-aliased
     
    Last edited: Mar 4, 2018
  10. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Yes, I'm quite aware of the issue- it comes from an optimization GPU's make (they sample in 2x2 pixels) and an optimization I make (not sampling all 16 textures on a 16 texture terrain) not liking each other. Basically, along the boundary of textures 1,2,3,4 and texture 6,2,3,1, lets say, if 1 and 6 have different scalings, then the derivatives used for mip map selection of a 2x2 block get screwed up since they are not consistent for all four pixels, and product the artifact. You can make them consistent (choose mip maps in the shader, ala LOD sampler) or force the GPU not to make this optimization (This would be the gradient samplers, but I'd need to force it to branch somehow, so currently it ignores them), or disable my optimization (sample all 16 textures per terrain instead of 4). Both of those options would make the shader drastically slower though- forcing the branch about 2x slower from my tests.
     
  11. AyeLuie

    AyeLuie

    Joined:
    Jul 18, 2016
    Posts:
    9

    MicroSplat ignores these values, correct? If so how does one go about changing the texture size?
     
  12. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    There's a global UV Scale in the material, as well as a per-texture UV scale which you can enable..
     
  13. superkratos

    superkratos

    Joined:
    Sep 4, 2017
    Posts:
    86
    Hi, Mr Booth! I've tried to use Advanced Detail after I set up the texture clusters. But when I change the mode to Advanced Detail, Texture Cluster mode is not an option any more. Does this mean that we can't use two modes at the same time?
     
  14. superkratos

    superkratos

    Joined:
    Sep 4, 2017
    Posts:
    86
    Sorry, Mr Booth.. Seems I've misunderstood something.. This should not be a problem:rolleyes:
     
  15. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    How expensive is Parallax?

    (Currently I'm not using Tesselation, since it doesn't work on Mac Metal, but eventually I'll probably do a WIndows-only material with Parallax and Tess combined.)
     
  16. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    It's a resample of the height maps, so it depends on the other features you have enabled. For instance, it's 4 with best blending, but if you have triplanar, it's 12 because triplanar samples each texture 3 times.
     
  17. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    What if I have triplanar disabled on most textures -- that'll help, right?
     
  18. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    No, triplanar is all or nothing from a performance perspective. Doing a branch to determine which textures should be sampled as triplanar is actually slower than just sampling all the textures as triplanar. The option to turn it off is only for visual preference.
     
    boysenberry likes this.
  19. Ctuchik

    Ctuchik

    Joined:
    Dec 28, 2013
    Posts:
    2
    Hi,

    I've been using MicroSplat for a project, really liking it! Had a couple of questions, sorry if they've been discussed before.

    What is the performance hit of using more Textures per material? I'm choosing between dropping all my textures into one big material (8 textures) or using separate 4 texture materials for each terrain biome. Using a separate material for each does seems to add a lot to the file size of my build.

    I've also noticed that the per texture properties are assigned separately from the Material. Are there any issues with using multiple different propData files for the same Template Material?

    Thanks for a great tool!
     
  20. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    There’s no performance difference for having 4 or 16 textures. MicroSplat works very differently than other shaders, which usually multipass the terrain for every four textures, or just sample all 16.

    PropDats is expected to be assigned once for each MicroSplat system (terrains concerted together). But ultimately it’s just a texture assigned to the material instance.
     
  21. Ctuchik

    Ctuchik

    Joined:
    Dec 28, 2013
    Posts:
    2
    Interesting, thanks for the reply!
     
  22. Danua

    Danua

    Joined:
    Feb 20, 2015
    Posts:
    191
    Hello, I found that your shader, microsplat write nothing in specular channel of gbuffer, so that cause very shiny looks for terrain.
    Please add simple specular float controller, for changing output specularity per textures.

    below i show difference between your shader, and custom standart specular shader.
    upload_2018-3-12_20-57-9.png
    upload_2018-3-12_20-57-24.png
     
    Rowlan likes this.
  23. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    MicroSplat uses a metallic workflow and stores a per-pixel smoothness value for every texture. This will be automatically computed if you do not provide smoothness textures.

    [Edit] It could also be that you are refering to the lighting model- GGX, which matches the unity standard shader, there is an override for this so you can force it to blin phong, but to do this it has to render the terrain in forward rendering since Unity doesn't have a way to have multiple lighting models in it's deferred pass.
     
    Last edited: Mar 12, 2018
  24. Danua

    Danua

    Joined:
    Feb 20, 2015
    Posts:
    191
    I know that your shader use metallic workflow, but for terrain i'd prefer specular workflow.
    Please allow us to control specularity,
    create specular version of shader plz.

    Unity metallic won't correct cuz it doesn't have special IOR slot for maps, for example grass or, diamond, or ice, have different IOR IRL, and Unreal engine 4 allow to change his specularity, metallic is not full workflow for the nature textures.
     
  25. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    A specular workflow requires two more texture channels (metallic value is a single channel, vs RGB channels for specular); this is significantly more bandwidth, and would increase the complexity (and thus support cost) across the entire tool chain and shader code base. I currently have no plans to add a specular workflow.
     
  26. Danua

    Danua

    Joined:
    Feb 20, 2015
    Posts:
    191
    Nope for me specular float enough, just parameters, I just want kill stupid shiny of terrain grass.
     
  27. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Specular is an RGB, not a single value, and when using a metallic workflow there is no specular value to set. If you want things not to be shiny at all, set smoothness to 0 in your texture. This will have the exact same result as an RGB of 0 in the specular workflow.
     
    Last edited: Mar 13, 2018
    Rowlan likes this.
  28. errandfox

    errandfox

    Joined:
    Apr 22, 2015
    Posts:
    42
    Hi, I'm trying to track down a problem; i have a 4096x4096 terrain with 8 textures, and am getting a 51 second lag on scene load [async load]. almost 1 minute of non responsiveness.
    profiler is showing with Microsplat.Awake() > Loading.ReadObject as 96% of this. Not sure what do do with this. I have the diffuse textures 1024k and height/normal/ao as 512, compressed, mipmaps enabled. I also have the anti tiling array module on.
    Is there anything special I need to do for async scene loading?
     
  29. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Well, first Unity’s asynchronous loafing is broken from about 5.2 until 2017.2 or so. Second, I have seen one case where when set to force text in the serisluzation preferences unity writes the texture arrays to YAML and parses them as text. I have not seen this happen in an actual build though..
     
  30. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    341
    Hi, I'm writing a tool to use MapMagic's OnApplyCompleted event to set up MicroSplat automatically on generated terrains. I have two questions:

    1. Adding the MicroSplatTerrain component to the Unity Terrain is simple, but the StreamManager has problems recognising it's on a MicroSplatTerrain. The problem fixes itself after the next run, but there seems to be some kind of timing or init sequence issue.

    2. How do I trigger the generation of Terrain Descriptor Data programmatically?
     
    boysenberry likes this.
  31. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    You could port the stream descriptor code to runtime and call it easily enough, but the ideal way to output this data would be to have MapMagic output it as part of it's node output, since it already has the height and normal data which is stored in that texture - avoiding having to look it all up and generate it again. Most likely you need to add the MicroSplatTerrain component, call Sync on it, then add the stream manager.
     
    PeterB and boysenberry like this.
  32. PeterB

    PeterB

    Joined:
    Nov 3, 2010
    Posts:
    341
    Adding the MicroSplatTerrain component, then calling Sync on it makes it possible to add the StreamManager successfully.

    Having MapMagic output the terrain descriptor data wouldn't be accurate in this case, as the height map will have been updated by Sentieri, so in this case my option is to copy your code and call it. Any chance of you making it available as part of the API in order to avoid code duplication?
     
  33. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Runtime code gets included in the build and makes build sizes larger. This is stripped on IL2CPP platforms by the C++ compiler, but not on Mono based platforms, so until all platforms are going through a pathway with proper stripping, I try to add as little runtime code as possible.
     
  34. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    I've just noticed that the MicroSplat shader in my scene is causing unexpected GPU spikes. Gfx.WaitForPresent spikes to 10m or 25ms every second or two. I've deleted everything from the scene except for the camera, terrain, and dir light. If I switch to the built-in terrain shader, then those spikes disappear. But the spikes only occur when Metal Editor is enabled.

    So I switched to a clean project and tried one of the demo MS scenes, after enabling all the modules I've got in my main game project, and those spikes do not occur (even on Metal Editor). That terrain has fewer splats (4 vs 12) and lower heightmap resolution, but I didn't think that would make a difference with MS.

    I'm using:
    Distance Resample
    Anti Tile Array: Everything
    Global Snow
    Wetness
    Terrain Blending
    Parallax
    Triplanar: Height blended

    Any ideas/suggestions? I'm on Mac 10.12.6, Unity 2017.3.1.

    thx
    Dave
     
  35. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Gfx.WaitForPresent is the GPU waiting for the VSYNC to happen. Lets say you have VSYNC set 60fps and it takes slightly too long for a frame to render. When that happens, the graphics card stalls and waits for the next vsync to happen so it can display the frame. It can also happen if you are not taking enough time to render a frame, but then you'd see it every frame.

    So your choices are to disable VSYNC, which will display the frame as soon as it's ready instead of waiting for the next one, or decrease your frame cost on the frame before this happens (maybe a particle went off, or Unity did a GC collect, etc).

    MicroSplat has nothing to do with any of this, it's just general rendering and display issues of how graphics sync to monitors. You don't get it when you go to the regular terrain shader, for instance, because you have removed a crap ton of features and made every frame render faster.
     
  36. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    Hmmm, okay, I'd gotten confused about what Gfx.WaitForPresent means. (I thought it was how heavy GPU usage was represented in the CPU usage panel...which is helpful since the GPU profiler doesn't work on Metal)

    But....VSynch is already disabled. if I enable it, then the spikes are gone, and instead of those green spikes, the profiler shows mostly yellow: WaitForTargetFPS (which is how I thought VSynch appeared in the profiler). See screenshot.

    And there's nothing in the scene except light, camera and terrain.

    Screen Shot 2018-03-20 at 12.23.53 PM.png
     
  37. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Yeah, the whole thing is a bit confusing, and I've never had much confidence in it showing the right results. The best thing would be to get it under a profiler like instruments, and see what the call stack into the generated C++ code says. Most likely you'll find it spinning in a wait statement..
     
  38. greyforest

    greyforest

    Joined:
    Jun 25, 2015
    Posts:
    16
    Hi Jason,when i use triplar with normalmap,shadow of some vertical surfaces are very strange, directional light is on top,45 degrees,the top side of the stones are dark。some surfaces are just fine。
     
  39. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Got a screenshot?
     
  40. greyforest

    greyforest

    Joined:
    Jun 25, 2015
    Posts:
    16
    the right surface is ok.BTW,CTS treat this case right.
     

    Attached Files:

    • 1.png
      1.png
      File size:
      2 MB
      Views:
      307
  41. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    Question about the snow module: I'm setting up a map with 8x8 terrain tiles; the 9 tiles around the player will be Unity terrain with Microsplat, and the rest will be low-poly meshes (with textures rendered out from Microsplat). I really want to use the snow module, but I need snow coverage across all tiles, both terrain and mesh. I know I can set up meshes to receive snow using the terrain blending module, but that doesn't work on meshes that are away from the terrain. (And I don't know if that method is too costly, performance-wise, for a lot of meshes surrounding the terrains anyways.)

    So is there a way to make this work? My alternative, I guess, is to get one of those other snow coverage tools on the asset store and use them on the entire scene. (I don't think I could use MS snow on the terrain and the other tool on the rest of the scene, as the snow coverage and appearance has to match across terrains and tiles.)

    thanks
     
  42. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Any post-processing snow solution is going to be more expensive than just running the MS shader on those meshes, I would imagine. That said, what I would do if this is really the bottleneck (profile!) is write a simple surface shader that runs the snow code from MicroSplat. You can grab it from the fragment files and call it's function from your own surface shader easily enough..
     
  43. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,019
    Thanks as always for the quick reply. I haven't purchased any of those other tools so don't know what kind of performance impact they'd have in my scene. I can have one of my devs look into your suggestion, but since I'm a shader ignoramus: How much of the MS snow functionality would we get by doing that? Snow amount, Height clearing, Height range, Angle range, etc?
     
  44. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    Yeah, you'd basically just be running the same snow code, but on top of your regular shader. The only thing you might need to do is output the height map value as a texture from the terrain, and then it should match exactly.
     
  45. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    902
    Hi @jbooth ,
    just tried the Tessellation/Parallax shader in 2018.1 b13 and there are these white patches in the demo scene...
    Can you please check this in b13 and if i can get it fixed somehow !

    Thank You !

    P.S. I tried to reimport the package ( microsplat core and the tessellation modules only ) and i got this error, but other than the issue with white patches Microsplat is working wonderful :

    Shader error in 'MicroSplat/Example_Tessellation': 'tex2D': no matching 4 parameter intrinsic function; Possible intrinsic functions are: tex2D(sampler2D, float2|half2|min10float2|min16float2) tex2D(sampler2D, float2|half2|min10float2|min16float2, float2|half2|min10float2|min16float2, float2|half2|min10float2|min16float2) at line 504 (on d3d11)


    upload_2018-3-31_12-22-19.png
     
    Last edited: Mar 31, 2018
  46. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    I officially do not support beta versions of Unity. Most likely they broke something else in the compiler again..
     
  47. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    902
    Ok, thanks for the response : ) !
     
  48. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    902
    Another question about the AlphaHole add-on - does it support lightmapping - i.e. are the objects beneath the terrain where it is clipped going to be lightmapped correctly as well !

    Thank You !
     
  49. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,599
    I have not actually tried this, but it should. MicroSplat is surface shader based, so unity should generate the correct shadow caster pass which clips the terrain..
     
  50. Vagabond_

    Vagabond_

    Joined:
    Aug 26, 2014
    Posts:
    902
    It does not seem to work actually...

    upload_2018-4-2_19-40-27.png