Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

[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,716
    Right now contrast is applied before brightness, which might be causing the issue. If you go into microsplat_terrain_body.txt around line 420 and swap this:

    Code (CSharp):
    1. #if _PERTEXBRIGHTNESS || _PERTEXCONTRAST || _PERTEXPOROSITY || _PERTEXFOAM
    2.             SAMPLE_PER_TEX(ptBC, 3.5, config, half4(1, 1, 1, 1));
    3.             #if _PERTEXCONTRAST
    4.                samples.albedo0.rgb = saturate(((samples.albedo0.rgb - 0.5) * ptBC0.g) + 0.5);
    5.                samples.albedo1.rgb = saturate(((samples.albedo1.rgb - 0.5) * ptBC1.g) + 0.5);
    6.                #if !_MAX2LAYER
    7.                  samples.albedo2.rgb = saturate(((samples.albedo2.rgb - 0.5) * ptBC2.g) + 0.5);
    8.                #endif
    9.                #if !_MAX3LAYER || !_MAX2LAYER
    10.                   samples.albedo3.rgb = saturate(((samples.albedo3.rgb - 0.5) * ptBC3.g) + 0.5);
    11.                #endif
    12.             #endif
    13.             #if _PERTEXBRIGHTNESS
    14.                samples.albedo0.rgb = saturate(samples.albedo0.rgb + ptBC0.rrr);
    15.                samples.albedo1.rgb = saturate(samples.albedo1.rgb + ptBC1.rrr);
    16.                #if !_MAX2LAYER
    17.                   samples.albedo2.rgb = saturate(samples.albedo2.rgb + ptBC2.rrr);
    18.                #endif
    19.                #if !_MAX3LAYER || !_MAX2LAYER
    20.                   samples.albedo3.rgb = saturate(samples.albedo3.rgb + ptBC3.rrr);
    21.                #endif
    22.             #endif
    23.             #if _PERTEXPOROSITY
    24.             porosity = BlendWeights(ptBC0.b, ptBC1.b, ptBC2.b, ptBC3.b, heightWeights);
    25.             #endif
    26.  
    27.             #if _PERTEXFOAM
    28.             streamFoam = BlendWeights(ptBC0.a, ptBC1.a, ptBC2.a, ptBC3.a, heightWeights);
    29.             #endif
    30.  
    31.          #endif
    for this:

    Code (CSharp):
    1. #if _PERTEXBRIGHTNESS || _PERTEXCONTRAST || _PERTEXPOROSITY || _PERTEXFOAM
    2.             SAMPLE_PER_TEX(ptBC, 3.5, config, half4(1, 1, 1, 1));
    3.          
    4.             #if _PERTEXBRIGHTNESS
    5.                samples.albedo0.rgb = saturate(samples.albedo0.rgb + ptBC0.rrr);
    6.                samples.albedo1.rgb = saturate(samples.albedo1.rgb + ptBC1.rrr);
    7.                #if !_MAX2LAYER
    8.                   samples.albedo2.rgb = saturate(samples.albedo2.rgb + ptBC2.rrr);
    9.                #endif
    10.                #if !_MAX3LAYER || !_MAX2LAYER
    11.                   samples.albedo3.rgb = saturate(samples.albedo3.rgb + ptBC3.rrr);
    12.                #endif
    13.             #endif
    14. #if _PERTEXCONTRAST
    15.                samples.albedo0.rgb = saturate(((samples.albedo0.rgb - 0.5) * ptBC0.g) + 0.5);
    16.                samples.albedo1.rgb = saturate(((samples.albedo1.rgb - 0.5) * ptBC1.g) + 0.5);
    17.                #if !_MAX2LAYER
    18.                  samples.albedo2.rgb = saturate(((samples.albedo2.rgb - 0.5) * ptBC2.g) + 0.5);
    19.                #endif
    20.                #if !_MAX3LAYER || !_MAX2LAYER
    21.                   samples.albedo3.rgb = saturate(((samples.albedo3.rgb - 0.5) * ptBC3.g) + 0.5);
    22.                #endif
    23.             #endif
    24.             #if _PERTEXPOROSITY
    25.             porosity = BlendWeights(ptBC0.b, ptBC1.b, ptBC2.b, ptBC3.b, heightWeights);
    26.             #endif
    27.  
    28.             #if _PERTEXFOAM
    29.             streamFoam = BlendWeights(ptBC0.a, ptBC1.a, ptBC2.a, ptBC3.a, heightWeights);
    30.             #endif
    31.  
    32.          #endif
    then regenerate the shader by changing some option on it, let me know if this works. If it does, then I expect that's the order we want- however, I wonder if I'd mess some peoples settings up by changing it?
     
  2. Ivoryjw

    Ivoryjw

    Joined:
    May 20, 2018
    Posts:
    31
    Hello again Mr.Booth.

    I was wondering if I could enable or disable certain microsplat features at runtime.

    For example if someone just wanted more performance, a script would turn off certain features (or modules) in exchange for performance. Or if someone wanted to have the best look possible, then all the features will be turned on.

    Is that possible with microsplat?
     
  3. kepesh

    kepesh

    Joined:
    Dec 29, 2017
    Posts:
    85
    Purchased the texture clusters addon and it said that I had to update Micro Splat. Which I did. And now I get this error:
    I'm using Unity 2017.4.3

    Shader error in 'Hidden/MicroSplat/Terrain TC2_x0_y0_Base-363043497': Surface shader Input structure needs INTERNAL_DATA for this WorldNormalVector or WorldReflectionVector usage at line 1505 (on d3d11)

    Compiling Vertex program with DIRECTIONAL
    Platform defines: UNITY_ENABLE_REFLECTION_BUFFERS UNITY_USE_DITHER_MASK_FOR_ALPHABLENDED_SHADOWS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING UNITY_ENABLE_DETAIL_NORMALMAP SHADER_API_DESKTOP UNITY_LIGHT_PROBE_PROXY_VOLUME UNITY_LIGHTMAP_RGBM_ENCODING
     
  4. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You pre-compile several variations of shaders with the features you want and set the one you want to use at runtime.
     
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Strange - do you get this when enabling a certain feature? You might try reinstalling..
     
  6. kepesh

    kepesh

    Joined:
    Dec 29, 2017
    Posts:
    85
    I copied the shader text from the example file in to my terrain shader file, which got rid of the error. But all the tint colors turned to shades of purple / pink. So I went back to a backup and copied the hex codes for all the colors. So now everything is fine again.

    Another question:
    Would it be possible to steal the terrain shader/material for other objects based on the vertex colors of those objects? Like the mesh blend but it's only based on vertex colors?

    Thanks!
     
  7. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    MicroSplat uses a texture to store it's splat map data, not vertex colors..
     
  8. Ivoryjw

    Ivoryjw

    Joined:
    May 20, 2018
    Posts:
    31
    Got it. Thanks.
     
  9. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    hi, I think there's an error in the latest package, file: MicroSplatShaderGUI.cs, line 57.
    I think it should be:
    string s = keywords.keywords;

    Regards
     
  10. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Yes, a patch was submitted this morning but hasn’t made it through the store yet. I also posted fixed script files in the discord room. But yeah, that will fix it.
     
  11. TEllard

    TEllard

    Joined:
    Nov 3, 2017
    Posts:
    1
    Hi there. I'm getting this in the latest package, with Unity 2018.3.7f1 Windows 10.

    Assets/MicroSplat/Core/Scripts/Editor/MicroSplatShaderGUI.cs(57,30): error CS0029: Cannot implicitly convert type `System.Collections.Generic.List<string>' to `string'

    Thanks for any advice!
     
  12. Ivoryjw

    Ivoryjw

    Joined:
    May 20, 2018
    Posts:
    31
    Hello again, I'm also getting an error after updating:
    Assets\MicroSplat\Core\Scripts\VegetationStudio\Editor\MicroSplatVegetationStudio.cs(129,28): error CS0115: 'MicroSplatVegetationStudio.DrawPerTextureGUI(int, Material, MicroSplatPropData)': no suitable method found to override

    Edit: I did section of some of the code such as the drawpertexturegui method (which is empty) and this in microsplatshadergui:

    if (renderLoopNames == null || renderLoopNames.Length != availableRenderLoops.Count)
    {
    var rln = new List<GUIContent>();
    for (int i = 0; i < availableRenderLoops.Count; ++i)
    {
    rln.Add(new GUIContent(availableRenderLoops.GetDisplayName()));
    }
    renderLoopNames = rln.ToArray();
    }

    if (renderLoopNames.Length == 1)
    {
    return false;
    }

    int curRenderLoopIndex = 0;
    for (int i = 0; i < keywords.keywords.Count; ++i)
    {
    //string s = keywords;
    for (int j = 0; j < availableRenderLoops.Count; ++j)
    {
    if (s == availableRenderLoops[j].GetRenderLoopKeyword())
    {
    curRenderLoopIndex = j;
    compiler.renderLoop = availableRenderLoops[j];
    break;
    }
    }
    }

    int oldIdx = curRenderLoopIndex;
    curRenderLoopIndex = EditorGUILayout.Popup(CRenderLoop, curRenderLoopIndex, renderLoopNames);
    if (oldIdx != curRenderLoopIndex && curRenderLoopIndex >= 0 && curRenderLoopIndex < availableRenderLoops.Count)
    {
    if (compiler.renderLoop != null)
    {
    keywords.DisableKeyword(compiler.renderLoop.GetRenderLoopKeyword());
    }
    compiler.renderLoop = availableRenderLoops[curRenderLoopIndex];
    keywords.EnableKeyword(compiler.renderLoop.GetRenderLoopKeyword());
    return true;
    }

    This fixed the errors and don't really notice a difference in terms of quality.
    Hope this helps.
     
  13. iddqd

    iddqd

    Joined:
    Apr 14, 2012
    Posts:
    402

    Thanks for this. It works different, perhaps better - but somehow I still can not get the desired results. Not quite sure what the issue could be.
     
  14. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    The patch to fix this was released on the store this morning..
     
    TEllard and camta005 like this.
  15. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,033
    We want to play some particle effects under the player's feet when the Snow Amount is above a certain amount -- but only under the player's feet (not global value from the material, since snow accumulation is affected by elevation). Is there an good performant way to do that?
     
  16. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You'd have to recreate the shader on the CPU - because snow is affected by the height of the textures, normals, etc. So it really depends on how accurate you need it.

    The other alternative would be to bake out a mask for the snow and sample that - if your snow is static. It would be fairly easy for me to write a debug mode to output this data to a texture- you could even render it to a buffer in real time if you had the perf to do it.
     
  17. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    Hi Jason, in terrain blending asset, I have a model with submeshes that I am not able to blend it properly. I know that the manual says it will only work on the first one, but as you can see, it is selecting the second material instead (wood):

    model.png

    Is this how Unity work or an issue in the shader?
    Thanks
     
  18. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    It's just how unity draws things, nothing I can do to control it. If you break this into two meshes, and put the component on both, then it will work..
     
  19. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    no worries, thanks, do you happen to know any hacks to change the order of materials in the mesh renderer field?
     
  20. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You'd have to write a script to change the order of the submeshes in the mesh data, essentially. Unity doesn't expect it to matter, and just outputs them in whatever order it encounters them I'd bet..
     
  21. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,033
    Darn it. And our snow isn't static. We can mostly use the global Snow Amount, but we use elevation to have it accumulate more slowly at lower elevations....do you think it'd be possible to recreate that logic/timing in our code so we can estimate where snow would be appearing at any given moment/?
     
  22. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Sure, depending on how accurate you need it, you can simplify the code. For instance, you can likely get a decent approximation if you just take the world position and vertex normal of the terrain into account- but for perfect you would actually have to sample the height maps of the textures and blend them all to get the surface height and normal, which would be a lot of work. If you look at the code in the microsplat_func_snow.txt to see how it's done.
     
    gecko likes this.
  23. Hallur90

    Hallur90

    Joined:
    Dec 4, 2017
    Posts:
    32
    I'm getting these errors after importing terrain blending.

    error.png

    I see the update button on some of the other modules I have installed, but knowing from experience updating may mess everything up.

    Could it be that this is version incompatibility?

    If not.. any remedies?
     
    Last edited: Mar 7, 2019
  24. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You can't mix versions with MicroSplat modules- if you update to a version, you need to update all of them to that version- otherwise the APIs may have changed between the modules, etc..
     
  25. Hallur90

    Hallur90

    Joined:
    Dec 4, 2017
    Posts:
    32

    Thanks, yeah guess that was bit of a brainfart on my part.
    I updated and imported all the modules and it works fine.

    Out of curiosity can I see the current version of each module somewhere in my project?
     
  26. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    No, but it will show a warning if any module is out of sync in the material (and it still compiles, which isn’t always the case) - and the main version is displayed on the top.
     
  27. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    hi, the advanced details module seems to be broken with the latest microsplat version. is this the right forum to report it?
    Thanks
     
  28. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    That's @wmpunk 's module, so he will have to update it. I actually already updated the code, but I don't have a way to push it to the store since it's his asset.
     
  29. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    I see. is it something complex or you can point me how to fix it? I know it has to do with the MicroSplatKeywords stuff, right?
     
  30. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Yes, a few of the module APIs changed, and the keywords are looked up from the scriptable object instead of the material. Should be straightforward to fix; I’d share the code, but I don’t own it.
     
  31. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,033
  32. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    I can confirm the asset is working fine after the update. Thanks
     
  33. camta005

    camta005

    Joined:
    Dec 16, 2016
    Posts:
    224
    Does Microsplat work with the terrain draw instanced feature in 2018.3? When I try it the terrain disappears and I'm just wondering if there is a way to get it working, or if it's not possible.
     
  34. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Yes, you need to run the latest and regenerate the shader (by changing an option) once in 2018.3. Note that unity does not compile tessellation for instancing right now, so that feature must be off.
     
  35. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    Hi Jason, Activating Tesselation when AdvancedDetails are active will produce a NULL reference error in the line indicated below (AdvancedDetails.cs):

    Code (CSharp):
    1. public override void OnPostGeneration(StringBuilder sb, string[] features, string name, string baseName = null, bool blendable = false)
    2.       {
    3.          if (isEnabled)
    4.          {
    5.             var txt = sb.ToString();
    6.  
    7.             var sampleInsertIndex = txt.IndexOf("// ADVANCEDTERRAIN_ENTRYPOINT");
    8.             txt = txt.Insert(sampleInsertIndex, sampleInsert.text + "\n\n");
    9.  
    10.             var tessInsertIndex = txt.IndexOf("// ADVANCEDTERRAIN_TESS_ENTRYPOINT");
    11.             if (tessInsertIndex > 0)
    12.             {
    13.                txt = txt.Insert(tessInsertIndex, tessInsert.text + "\n\n"); <=== ERROR
    14.             }
    15.  
    16.             sb.Remove(0, sb.Length);
    17.             sb.Append(txt);
    18.          }
    19.       }
    Apparently tessInsert is a Microsplat asset that is not being properly assigned before this function is called.

    I'm not sure if this is related to AdvancedDetails or Tesselation module?
    Thanks
     
  36. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    @wmpunk
     
  37. niallmc

    niallmc

    Joined:
    Sep 3, 2015
    Posts:
    10
    Hey, I'm searching for how to edit a per texture property at runtime. I can't find anything on the matter online.
    Essentially I want to edit the 'Tint' property of the 3rd Texture within my microsplat material

    So normally I would use: material.SetColor("MyColor",Color.blue);

    Do you know how I could do this for a pertexture property? e.g: material.SetColor("PerTextureProperty3",Color.blue);


    Many thanks for your help.
     
  38. m506

    m506

    Joined:
    Dec 21, 2015
    Posts:
    42
    Hi, thanks for redirecting the error accordingly. I've managed to get the tesselation working fine by commenting that block, but I don't know the impact it would have.
    The library looks amazing as I expected but of course it comes with a cost. If I want to expose an option to the player to disable tesselation from the terrain, what would be the best way of achieving that during runtime? disabling the feature from the microsplat material or messing around with the tesselation parameters (ie min/max distance)?
    Thanks
     
  39. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Create two versions of the shader and swap them. You can change the option at runtime, because no shader compiler is available in the Unity runtime.
     
  40. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Two possible ways:

    Slow
    - Call SetValue on the PropData object with the index and value you want
    - Call MicroSplatTerrain.SyncAll();

    Fast
    - Get the prop data texture from the material and use SetPixel to set the correct value.

    All pertexture properties in MicroSplat are stored in a lookup table, as this is much more efficient than having thousands of material properties. If you look at the MicroSplatPropData.cs file, there's an index describing what pixel holds which values.
     
  41. niallmc

    niallmc

    Joined:
    Sep 3, 2015
    Posts:
    10
    Thank you for your time, I hate to be a bother but It would be amazing if you could explain the fast method in more detail as I don't think I can figure it out.

    So would I go:

    microSplatMaterial.propData.SetPixel(3,1,Color.Red)

    The microsplatMaterial does not appear to have a PropData Method

    Sorry for being a bother and thanks for such an amazing asset!
     
  42. camta005

    camta005

    Joined:
    Dec 16, 2016
    Posts:
    224
    Thanks, yeah I had tessellation on so that was the issue.
     
  43. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You'd grab the texture from the material, and set the pixel on it. Something like:

    Code (CSharp):
    1. Texture2D propData = templateMaterial.GetTexture("_PerTexProps") as Texture2D;
    2.  
    3. int textureIndex = 3; // on 4th texture in the array
    4. int propertyIndex = 1; // tint and interpolation contrast
    5.  
    6. propData.SetPixel(textureIndex, propertyIndex, tintColorAndInterpContrast);
    7.  
     
  44. HiWill

    HiWill

    Joined:
    Jun 2, 2013
    Posts:
    14
    can we set Stochastic sampling per texture?
     
  45. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Not right now- is your reason esthetic or performance? Because of the way shaders work, it would actually be just as expensive to do this per texture as it is to do it all the time. The same is true with triplanar, so when you turn that off per-texture, it still runs the whole triplanar effect and just selects the top projection.
     
  46. niallmc

    niallmc

    Joined:
    Sep 3, 2015
    Posts:
    10
    So hopefully this is my last question.

    When I use:
    propData = microSplatMat.GetTexture("_PerTexProps") as Texture2D;

    propData results in 'null'
    It doesn't seem to recognise a "_PerTexProps" texture on the microsplat material, any ideas on that one?


    Again thanks for your time!
     
  47. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    You could alternatively grab it from the propdata object on the MicroSplatTerrain component instead.
     
  48. niallmc

    niallmc

    Joined:
    Sep 3, 2015
    Posts:
    10
    I have ended up with the following code:

    Color grassAliveColor = new Color.green;

    propData = microSplatTerrain.propData.GetTexture();
    int textureIndex = 1; // on 1st texture in the array
    int propertyIndex = 1; // tint and interpolation contrast
    propData.SetPixel(textureIndex, propertyIndex, grassAliveColor);

    it doesn't throw any error's but it does nothing at all, the microsplat material is not updated. Am I missing something?

    ]
    ]
     
  49. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    3,716
    Well, texture index 1 would be the second texture in the array, not the 1st.. Also, tint has to be enabled on your material.
     
  50. niallmc

    niallmc

    Joined:
    Sep 3, 2015
    Posts:
    10
    yes sorry that's the texture I want to access, the second one, no texture at all is being changed in any way with this. I know this is taking a lot of your time, but thanks for taking a look anyway

    Tint is also enabled
     
    Last edited: Mar 12, 2019