Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Released] MegaSplat, a 256 texture splat mapping system..

Discussion in 'Assets and Asset Store' started by jbooth, Nov 16, 2016.

  1. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Color profiles have nothing to do with gamma curves. Basically, if your not rendering in linear space, then all color textures (macro, albedo arrays, albedo source textures) should be set to gamma and all non-color information (normals, etc) should be set to linear. In linear space, everything is linear.
     
  2. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    I'm getting an odd issue where my diffuse map and normal map at are different mipmap levels. Using Normal Smooth AO packing mode.

    http://imgur.com/fOLP9iI
     
  3. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Got any more information? Unity lets you bias the mip map via the mipbias setting on a texture, but I don't set those at all in MegaSplat. The only other thing I could think of that might affect something like this is the ddx/ddy not being updated in the shader, but then it would be for all images, not just normal.
     
  4. recon0303

    recon0303

    Joined:
    Apr 20, 2014
    Posts:
    1,634
    Hi jason, I imported the newest Mega Splats i'm using 5.5 and I keep getting 3 errors.. I tried in new project same issue. Tried a total of three times now.

    Assets/MegaSplat/VertexPaint/Editor/VertexPainterUtilities.cs(29,15): error CS0619: `UnityEngine.Mesh.Optimize()' is obsolete: `This method is no longer supported (UnityUpgradable)'

    Getting a few of these.
     
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Looks like you didn't let the Unity AutoUpdater run when you imported the asset. You can run it from the assets menu..
     
  6. recon0303

    recon0303

    Joined:
    Apr 20, 2014
    Posts:
    1,634
    eh? I do it from the same place I for many , many years.... and over 108 assets same place.. and yes I did let it.. been using Unity since Unity 3, lol... I tried as well....from the menu and even downloaded and used the package itself.. after wards to double check....same issue happens...


    Edit: Ugh.... hate mobile settings some days.. I set platform to Desktop, then back to mobile, and it is fine. Love how the updater don't always work, when I seen the errors , it looked like it was the updater.... But mobile, the last few years has gotten worse with stupid nonsense like this. Shaders get worse some days.. Ugh.. anyways fixed now.
     
    Last edited: Apr 23, 2017
  7. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    I've played with the mipmap biases to no effect. Further experimentation shows me something else strange though - check out the attached image here.

    http://imgur.com/bWaIhpi

    The smoothness map, which is in the blue channel of the normal map, is showing at the correct resolution. It's a bit hard to tell but I believe the occlusion is also showing correctly. Presumably if this was a mipmap issue, the smoothness and occlusion would also be affected, since they are part of the same map?

    If there's more specifics you need, I'll be happy to provide them.
     
  8. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Perhaps what your seeing is just DXT compression artifacts, since that compresses in 8x8 pixel blocks. These can be particularly bad on normals, since they often represent smooth gradients.
     
  9. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    I'll try using different compression then, and failing that, I'll try a different packing mode.
     
  10. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    It looks like compression artifacts was the correct answer. I recompressed the normal maps in ARGB 16 bit mode and the maps look fantastic now. Thank you for the help, I never would've thought to look into that particular parameter.
     
  11. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Your other option is to go for a different packing, like MSEO. When normal maps are compressed by themselves on PC, they get compressed into DXTnm format, which is better for normal maps that DXT5, which is what NormalSAO is going to use. The tradeoff, of course, is more samples. NormalSAO is great because it's just 2 textures, and often in terrain textures the textures are noisy enough that the loss of compression quality is a good tradeoff. But on things with subtle gradients, DXTnm is significantly higher quality than DXT5.

    ARGB16 is an interesting choice, because it gives you low quality normal accuracy (4 bits per channel), but the data is consistent, so it interpolates well. Using DXTnm is likely going to be higher quality in many cases though, if you don't mind the extra sample. In the end, it's hard to say if the extra sample hurts more than the extra bandwidth for ARGB16 - I would guess the DXTnm with an extra sample might be the better option, but without a lot of testing it's hard to say.
     
  12. Captaingerbear

    Captaingerbear

    Joined:
    Mar 6, 2013
    Posts:
    57
    You might've guessed due to my not thinking my issue might've been compression, but I don't know much about compression modes. I just chose something from the dropdown menu that I thought would have alpha support. I'm not very far into creating my textures yet, so I could use MSEO mode, if it's going to be better results. The game I'm doing now is top-down with a limited viewport, so I can get away with packing quite a bit into it.
     
  13. trilobyteme

    trilobyteme

    Joined:
    Nov 18, 2016
    Posts:
    309
    Do you know if Megasplat would be able to work with Multiple Terrain Brush?

    That and just to confirm, due to the Unity bug in 5.6 Megasplat will not work properly in that version but will work(and look amazing) in Unity 5.5 and then hopefully in 2017.1 when that is released?
     
  14. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I believe they will backport the fix from 2017.1 to 5.6 when it's done.

    I don't know anything about multiple terrain brush- but the brushing system in MegaSplat works across multiple terrains just fine..

    It's a complex topic with lots of tradeoffs, and ones most users don't understand (You'll also note the massive confusion on linear vs gamma textures and rendering modes which is present in this thread as well). It's also highly platform dependent, as there are many texture compression formats for different platforms. Unity does a decent job of abstracting this complexity with their "Automatic" settings, but I'd really love to have more control over the internals of how textures are compressed because you can do a lot of things to increase quality in these areas and it can have huge wins on every pixel.

    Which packing format makes sense for you is entirely dependent on your game's needs. I offer the multiple packing modes as a way for users to make these tradeoffs; NormalSAO being the most efficient with a reasonable quality tradeoff if you don't have metallic and smooth surfaces, MSEO if you need a full PBR spec and higher quality normals, Standard if you want something closer to the Unity model, etc. Most systems just choose something and force you into it (which makes them a bit easier to use since you have less choices).
     
  15. daviesjared

    daviesjared

    Joined:
    Dec 1, 2015
    Posts:
    6
    Pretty much exactly what I'm doing except w/o a macro texture. I've made some minor changes to VertexPainterWindow (e.g. making Init* methods static), made a Color2Brush bake function (using ColorToSplatConverter as a template), and a modified Process() mesh converter.
     
  16. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Minor clarification. Unity's DXTnm is DXT5, just with the red channel of the normal map packed in the DXT5's alpha, and the red and blue channels blanked out so the RGB only has to store the green channel of the normal map. The alpha of a DXT5 texture is significantly higher quality than a single of the RGB channels of either DXT5 or DXT1 (which both use the same RGB compression), and is compressed by itself, where as the RGB is compressed all together so something in the red in the texture can affect the accuracy of the green and blue channels.

    Other engines have used a texture format called "DXTnm" as well, some of which use a swizzled DXT5, but others use a format called BC5, which is two DXT5 like alpha channels and is almost indistinguishable from uncompressed normals. This is supported as of Unity 5.5, but not enabled by default, and none of Unity's built in shaders support it since all of their shaders assume the swizzled normals on desktop & console. This format has been around since the Xbox 360 and on desktop for DX10 and OpenGL 2.0, but the PS3 infamously never had support for it, and Unity only just dropped support of that platform recently.

    If anyone is curious about DXTC/BCn texture formats:
    http://reedbeta.com/blog/understanding-bcn-texture-compression-formats/

    Also, DXT5 (aka BC3) is a 4x4 block compression format. The only format I know that uses 8x8 is ASTC, but it supports a wide range of block sizes for different compression ratios all the way up to 12x12.


    Which brings me to my final thought here. It might be nice to support BC5 normals when using MSEO, as well as maybe a packed format that uses the same DXTnm style swizzle, ie:
    R: Smoothness
    G: Normal Y
    B: Ambient Occlusion
    A: Normal X

    That would get you very close to the DXT5 based DXTnm normal map quality while still letting you pack your textures efficiently. Valve uses a very similar format already for their normal maps for the Source engine (with anisotropic smoothness packed into the R&B channels rather than smoothness and AO).
     
    one_one and Tethys like this.
  17. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Ugh, for some reason I had it in my head that Unity used BC5 on some platforms. It's an interesting thought to add the new packing format- but here's my question, since you're including information in the GB channels, your normal Y component is going to have to consider them as part of the RGB compression; so it's going to be squashed the same way it is now. Do you think adding another packing format so that just the X component can get a bit better is worth the complexity? (Packing tends to be a major issue for people new to shaders/megasplat, so in this specific case I'm assuming no, but more in general - will you notice the difference kind of way). I suspect on most surfaces the differences would be really minor.

    I could, however, add a BC5 decoding option for the normal map which would work in any non-packed normal mode (Standard, MSEO).

    What I'd really prefer for normals is a way to properly import them from 16bit per channel textures. Right now, everything in Unity gets quantized into 8bpc before being fed to the compressor. A lot of normal maps have a high degree of information around 0.5, and little in the extremities; additionally, information around 0.5 tends to be more important than information in the extremities. Thus, if you renormalize the range of your textures (while in 16bpc) and store those renormalization factors along with the texture, then downsample and feed it to the compressor, you can then rescale the normals in the shader and get a much more accurate normal map. It's a great tradeoff for one extra MULADD. You can take this further if you encode a non-linear representation, such that you get more information around the 0.5 point and less around the extremes.

    While less important on terrain textures, it makes a massive difference on smooth surfaces which have high amounts of specularity (cars, etc). But Unity's pipeline is a bit too closed to make this happen, which is a shame.
     
    Tethys likes this.
  18. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,329
    Curiously, in 5.4 a 16 bpc TIF and 8 bpc TGA of the same normal map produce different DXTnm and RGB24 normal maps, so it may no longer be doing this. I seem to remember 5.2 producing identical results. Also in 5.5 they have support for importing 16 bpc image formats directly to uncompressed RGBAHalf or BC6H, though BC6H is actually kind of terrible for normals, as is BC7 which they use when you select High Quality (though mildly better than DXTnm for some content). BC5 from a 16 bpc TIF is far away the best looking to me in 5.5.

    Strangely I would have expected the RGBAHalf to look better than it does, it actually looks wrong worse than the RGB24 from the same TIF... there might be something going wrong there on their side or mine.

    Here's a shader I wrote to play with different formats, and a zip file with the normal map textures I used. I made several copies of these and set them to import as various formats.

    Code (CSharp):
    1. Shader "Unlit/NormalMapFormatTester"
    2. {
    3.     Properties
    4.     {
    5.         [Header(Normal Map A)]
    6.         [Toggle] _UseReal_A ("Use Ground Truth Normal for 'A' (ignore texture)", Float) = 0
    7.         [Toggle] _UseSwizzle_A ("Swizzled (for DXTnm or native Unity normal maps)", Float) = 1
    8.         [Toggle] _CalcZ_A ("Force Derive Z (for RG formats like BC5)", Float) = 1
    9.         [NoScaleOffset] _Normal_A ("Normal Map", 2D) = "bump" {}
    10.  
    11.         [Space(15)]
    12.         [Header(Normal Map B)]
    13.         [Toggle] _UseReal_B ("Use Ground Truth Normal for 'B' (ignore texture)", Float) = 0
    14.         [Toggle] _UseSwizzle_B ("Swizzled (for DXTnm or native Unity normal maps)", Float) = 1
    15.         [Toggle] _CalcZ_B ("Force Derive Z (for RG formats like BC5)", Float) = 1
    16.         [NoScaleOffset] _Normal_B ("Normal Map", 2D) = "bump" {}
    17.  
    18.         [Space(15)]
    19.         [Header(Diff Normals A vs B or preview lighting on A)]
    20.         [Enum(Off (show lighting), 0, Normal Diff, 1, Lighting Diff, 2)] _Diff ("Diff To Show", Float) = 0
    21.         _DiffScale ("Diff Scale", Range(1, 50)) = 10.0
    22.     }
    23.     SubShader
    24.     {
    25.         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
    26.         LOD 100
    27.         Blend SrcAlpha OneMinusSrcAlpha
    28.  
    29.         Pass
    30.         {
    31.             Tags { "LightMode"="ForwardBase" }
    32.  
    33.             CGPROGRAM
    34.             #pragma vertex vert
    35.             #pragma fragment frag
    36.            
    37.             #include "UnityCG.cginc"
    38.  
    39.  
    40.             sampler2D _Normal_A;
    41.             bool _UseSwizzle_A;
    42.             bool _CalcZ_A;
    43.             bool _UseReal_A;
    44.  
    45.             sampler2D _Normal_B;
    46.             bool _UseSwizzle_B;
    47.             bool _CalcZ_B;
    48.             bool _UseReal_B;
    49.  
    50.             float _Diff;
    51.             float _DiffScale;
    52.  
    53.             struct appdata
    54.             {
    55.                 float4 vertex : POSITION;
    56.                 float2 uv : TEXCOORD0;
    57.                 float3 normal : NORMAL;
    58.                 float4 tangent : TANGENT;
    59.             };
    60.  
    61.             struct v2f
    62.             {
    63.                 float4 pos : SV_POSITION;
    64.                 float2 uv : TEXCOORD0;
    65.                 float3x3 tSpace : NORMAL;
    66.             };
    67.            
    68.             v2f vert (appdata v)
    69.             {
    70.                 v2f o;
    71.                 o.pos = UnityObjectToClipPos(v.vertex);
    72.                 o.uv = v.uv;
    73.  
    74.                 half3 worldNormal = UnityObjectToWorldNormal(v.normal);
    75.                 fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
    76.                 fixed tangentSign = v.tangent.w * unity_WorldTransformParams.w;
    77.                 fixed3 worldBinormal = cross(worldNormal, worldTangent) * tangentSign;
    78.  
    79.                 o.tSpace = float3x3(worldTangent, worldBinormal, worldNormal);
    80.                 return o;
    81.             }
    82.            
    83.             fixed4 frag (v2f i) : SV_Target
    84.             {
    85.                 // circle mask
    86.                 float2 circleUV = i.uv * 2 - 1;
    87.                 float circle = (1 - length(circleUV)) / fwidth(length(circleUV));
    88.  
    89.                 // normal A
    90.                 half4 texA = tex2D(_Normal_A, i.uv);
    91.                 float3 normalA = float3(_UseSwizzle_A ? texA.w : texA.x, texA.y, texA.z);
    92.                 normalA = normalA * 2 - 1;
    93.                 if (_CalcZ_A || _UseSwizzle_A)
    94.                     normalA.z = sqrt(1 - saturate(dot(normalA.xy, normalA.xy)));
    95.  
    96.                 // normal B
    97.                 half4 texB = tex2D(_Normal_B, i.uv);
    98.                 float3 normalB = float3(_UseSwizzle_B ? texB.w : texB.x, texB.y, texB.z);
    99.                 normalB = normalB * 2 - 1;
    100.                 if (_CalcZ_B || _UseSwizzle_B)
    101.                     normalB.z = sqrt(1 - saturate(dot(normalB.xy, normalB.xy)));
    102.  
    103.                 // calculate sphere normals from UVs
    104.                 half3 realNorm = 0;
    105.                 realNorm.xy = circleUV;
    106.                 if (length(realNorm.xy) > 1)
    107.                     realNorm.xy = normalize(realNorm.xy);
    108.                 realNorm.z = sqrt(1 - saturate(dot(realNorm.xy, realNorm.xy)));
    109.  
    110.                 // use calculated normals for normal A
    111.                 if (_UseReal_A)
    112.                     normalA = realNorm;
    113.  
    114.                 // use calculated normals for normal B
    115.                 if (_UseReal_B)
    116.                     normalB = realNorm;
    117.  
    118.                 // diff normals (just xy)
    119.                 if (_Diff == 1.0)
    120.                 {
    121.                     half2 diff = abs(normalB.xy - normalA.xy) * _DiffScale;
    122.                     return fixed4((diff.x+diff.y).xxx, circle);
    123.                 }
    124.  
    125.                 // diff lighting
    126.                 if (_Diff == 2.0)
    127.                 {
    128.                     half dotNorm = saturate(dot(normalize(mul(normalA, i.tSpace)), _WorldSpaceLightPos0.xyz));
    129.                     half dotReal = saturate(dot(normalize(mul(normalB, i.tSpace)), _WorldSpaceLightPos0.xyz));
    130.                     half diff = abs(dotNorm - dotReal) * _DiffScale;
    131.                     return fixed4(diff, diff, diff, circle);
    132.                 }
    133.  
    134.                 // lighting on A
    135.                 return fixed4(dot(normalize(mul(normalA, i.tSpace)), _WorldSpaceLightPos0.xyz).xxx, circle);
    136.             }
    137.             ENDCG
    138.         }
    139.     }
    140. }
    141.  
     

    Attached Files:

    Tethys likes this.
  19. BigBite

    BigBite

    Joined:
    Feb 20, 2013
    Posts:
    108
    So does all of the splat work you do come over to Mega Splat once it's converted?? Does it do it efficiently, IE: I don't have to do any tweaking once it's converted (unless I want to add more variation with hand painting)?

    On another note: would there be any benefit in adding some Terrain Composer integration? Or is that simply not possible (given that both plugins handle terrains differently)? What about a button in Terrain Composer that "sends" the data to Mega Splat for conversion?

    Anyway, this looks really useful and would like to integrated into my workflow as my current terrain has a couple of textures with noticeable tiling that I can't seem to get rid of without scaling the textures drastically, which in turns degrades the texture (a super large 512 texture just looks bad...). I really like using Terrain Composer for the broad strokes, using this for the fine details would be dope.

    Edit:
    So I found a video where you take terrain data from Map Magic and convert it to Mega Splat. There does seem to be a little more tweaking involved, it's not a whole lot... but still. I really like Terrain Composer's "non destructive" workflow, it feels like once I convert to Mega Splat I'm stuck doing the painting of textures and height (I can still paint height... right?) by hand, that would mean keeping Terrain Composer around for "broad stroke" exploratory work and converting to Mega Splat to see the pre-final look. Not to mention that when you re-convert the terrain from these other packages, you end up loosing any manual work you had done in Mega Splat(?). What say you?

    Also, the promo video says that it outperforms the vanilla Unity Terrain... what would cause it to underperform?
     
    Last edited: Apr 25, 2017
  20. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I'm currently working on direct integrations with Gaia and Map Magic, where you can use texture clusters directly in those tools without having to do the conversion step. I reached out to the author of TC2 a while back, but never heard anything. In any case, converting is limiting to some degree because those tools are designed around using just a few textures, and you can take it so much further with MegaSplat. As such, I have my own procedural texturing system now, which can take the types of techniques these programs do much further.

    MegaSplat supports a host of features that the Unity Terrain shaders do not - like hundreds of them. Things like tessellation, for instance, can be much slower. The main advantage that MegaSplat has over all other shaders on the asset store is that it has a consistent per pixel shader cost regardless of how many textures are used, where all other shaders get more expensive as you add more textures.
     
    Tethys likes this.
  21. BigBite

    BigBite

    Joined:
    Feb 20, 2013
    Posts:
    108
    I figured you were probably going to mention that you hadn't heard anything from the developer of Terrain Composer, when he is silent, he's really silent. I understand the power of Mega Splat, but creating terrains in unity can be a b**. That's where terrain tools come in and using them in tandem would be beneficial.

    Let me give you a work flow example:
    • Create and modify a terrain with your favorite terrain plugin (Terrain Composer for this example)
      • Run around on the terrain and get a sense for the scale and features desired
      • Tweak whatever you need; scale, noise values, multi or single terrains, etc.
      • Export terrain heightmap
    • Import heightmap into World Machine
      • Add some more noise if desired.
      • Add some more features (like terraces, rivers)
      • Erode the piss out of it (in a controlled way of course)
      • Generate some masks
      • Export all data back to Unity
    • Pipe that data into Terrain Composer
      • Modify WM masks if you need to (fade them out by noise, slope, height, etc.)
      • Do some quick texturing
        • Possibly start working with RTP if you don't have MS (tho RTP can be a pain to work with)
      • Modify terrain some more if need be
    • Take it to Mega Splat for even more textures and features (This would be new in my workflow)
      • Hand paint points of interest (paths, puddles, outcroppings, etc.)
    • Take stock of work so far
      • Walk around on the terrain again
      • Add some props for context and look over design doc
      • Oh wait, that mountain needs to be bigger, let me just...
    And that's where I'm not sure where to go. In Terrain Composer, you can just move/scale/rotate "the mountain", or modify your WM masks (with some noise and various other functions). Is there a workflow that involves all/any of these plugins where we are not losing data/tools between them?

    Like I said, I use Terrain Composer, so I can only speak to the workflow I'm currently using.
    BTW, I'm not saying that you don't want to support TC (you already do by default), I just want to point out the situation I'm in in my current workflow. I'm already jumping between a couple of tools. WM is very important to me because morphing the noisiness that comes with these tools into something that looks realistic is paramount, not to mention the masks you can get for texturing that erosion. The biggest pain point for me right now is RTP. Though I should probably ask, can we tile these textures independently? In RTP, the are all tiled the same, so my ground texture is 10 times as big (making the low resolution really noticeable) because the rock textures look better at that scale. See? Oh, and it also makes the snow in the environment look tiled AF due to the height blending in the low opacity areas of the snow. It causes it to blend that snow around the same height in the texture, so you see that particular snow feature repeat at a distance.
     
    Last edited: Apr 25, 2017
  22. BigBite

    BigBite

    Joined:
    Feb 20, 2013
    Posts:
    108
    Here is a shot of my current progress:

    upload_2017-4-25_7-15-38.png

    You can see the snow tiling, I got it to look better by increasing the tiling, which also scales all textures. The ground textures are so big that they make you feel like a hobbit, it's an optical illusion that I would like to break free of. And this is all after a lot of hours of tweaking (which is to be expected in all aspects of making games).
     
  23. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I'm well aware of these types of workflows, which is why I have done direct integrations with several tools out there- but I can't force someone to take my code.

    Every texture in MegaSplat can have it's own UV scale.
     
  24. daviesjared

    daviesjared

    Joined:
    Dec 1, 2015
    Posts:
    6
    @jbooth Where did I go wrong here? I've run the mesh converter (Process()) and applied the brushes (modified ColorToSplatConverter w/ separate List<Color> for per-vertex coloring). Then when I try vertex painter I get this behavior. whereDidIgoWrong.png
     
  25. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Switch to the paint tab on the vertex painter and turn on 'view vertex data' with the paint mode set to color; you should see your mesh colored with red/green/blue on each vertex. If you don't, then you either a) accidentally painted the mesh with color (which you can clear by pressing the RGB button) or b) haven't used the mesh output by the mesh converter (it will be next to the original with the _splat.asset extension).

    [Edit] just saw that your doing this via code- but same advice- look at the model and make sure the RGB colors are correct. Likely you're overwriting them in your code. Each face must have one red, one blue, and one green vertex.
     
    Last edited: Apr 25, 2017
  26. WileE

    WileE

    Joined:
    Apr 12, 2016
    Posts:
    21
    Thank you very much for the clarification. I have gone through and made sure that our overall colorspace is gamma, that all the source albedo textures for MS are set with sRGB on and normals linear, then rendered and assembled the macro texture, all with sRGB on in the albedo macro and off on the normal. I still get the darker rendering of the macro and an excessively bright blend zone at the edge (the fade is set to 1m right now). Screen Shot 2017-04-24 at 3.16.21 PM.png
     
  27. daviesjared

    daviesjared

    Joined:
    Dec 1, 2015
    Posts:
    6
    For some reason the Vertex data tools don't do anything for me except paint the mesh all white -- wireframe does nothing. (Unity 5.5.1f1)

    I cleared the color, rgb, and uv3 channels and still end up with the stepped-texture gradient. If you like I can PM/email you the tidbits of the code doing the mesh conversion/combine operations. Its basically like this though(pseudo mixed w/ actual code):

    function ProcessTerrainPage(...)
    ....
    List combineInstances
    foreach mesh in meshes
    fill mesh.colors with material.color
    create combine instance and add to combineInstances
    combinedMesh = combineMultipleMeshes(combineInstances)

    add combinedMesh to incremental scene
    save scene
    unload scene
    return​

    function combineMultipleMeshes(List combineInstances)
    List origVertexColors //used to guide our brush/texture selection
    Mesh mesh = new Mesh
    mesh.combineMeshes(combineInstances.ToArray(),true,true)

    remap uv0 to be [0,1] using min/max extents of x and z vertex components
    populate origVertexColors from mesh.colors

    //copy of MeshProcessorWindow which copies mesh.colors into origVertexColors and adds follows
    //same pattern to adding colors as vertices (i.e. copy color when vertex is copied)
    mesh = Process(mesh,origVertexColors)

    GameObject combinedObject = new GameObject()
    combinedObject.AddComponent<MeshFilter>().mesh = mesh;
    combinedObject.AddComponent<VertexInstanceStream>();
    combinedObject.AddComponent<MeshRenderer>().material = megaSplatMeshMaterial;
    combinedObject.SetActive(true);
    PaintJob job = new PaintJob(
    combinedObject.GetComponent<MeshFilter>(),
    combinedObject.GetComponent<Renderer>());
    // modified version of ColorToSplatConverter's Bake(), uses origVertexColors as the color for vertex
    // the colortosplat config has all of the color to texture configs set
    Bake(job, origVertexColors);

    // save out our mesh data
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
    return combinedObject;

     
  28. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    If you can send me a repro project I can take a look..
     
  29. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Not the wireframe setting, but the setting that allows you to visualize the vertex colors. If they are all white, you will get the texture smearing in your image.

    The preprocessor colors all the vertices correctly for MegaSplat, but you need to make sure you don't overwrite the RGB values of the original vertices when you set the color.a values. If you are filling the mesh.colors with values, you are most likely overwriting those RGB values. When you render the vertex colors, it should be that every vertex has a red, green, or blue value assigned to the RGB's. If not, then you are writing over those values at some point..
     
  30. StaffanEk

    StaffanEk

    Joined:
    Jul 13, 2012
    Posts:
    380
    If anyone else is having trouble getting runtime clustered painting working. Simply change the following lines:
    Code (csharp):
    1.  
    2. textureIndex = cluster.GetIndex(p, Vector3.up, 0.5f);
    3. ti = (float)textureIndex / 255.0f;
    4.  
    to
    Code (csharp):
    1.  
    2. //textureIndex = cluster.GetIndex(p, Vector3.up, 0.5f);
    3. //ti = (float)textureIndex / 255.0f;
    4. ti = (float)cluster.GetIndex(p, Vector3.up, 0.5f) / 255.0f;
    5.  
    The original script overwrites textureIndex that it uses to figure out the new textureIndex.
     
  31. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461

    Doh, good find. I'll fix this in the source as well. Thanks!
     
  32. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    BTW, I submitted 1.06 last night. I'll try to do the dev log tonight, but here's the change list:

    1.06

    Features:

    • New Texture Graph Node: Cavity. Enable cavity before processing your selection, and Cavity will output a 0-1 value representing the cavity of the given control point. This is similar to ambient occlusion, but can be used to place textures or blend in the convex parts of the model.
    • New Texture Graph Node: Texture Mask. Allows you to use a texture as a mask to output a float value. Can be used to control blending, texture selection, or any float parameter via a texture.
    • New Texture Graph Node: Low/High Pass filter. Allows you to low/high pass filter an float input. Note this could always be achieved with a curve, but this is a better interface than editing a curve if that’s all you want.
    • New Texture Graph Node: MultiBand Filter: A 1-4 channel band pass filter, which can be used to select the texture choice and layer blend based on a series of band pass filters and an input gradient. If this makes no sense to you- plugging height into the input will allow you to select 4 center points (with width and falloff) along the height range, each blending in a texture of your choice.
    • New Texture Graph Node: Comment
    • Added UpVector to NormalAngle node, so you can compare vs. other directions
    • Example added for texture graph
    • Texture Graph: Added cluster noise scale to texture cluster nodes
    • Added Cluster Noise Scale to runtime painting


    Fixes

    • Fixed another white text on white background issue in light skin mode
    • Fixed coloring on light skin in Texture Graph
    • Increased accuracy of CPU side displacement calculations
    • Fixed a bunch of stuff in the texture graph (save issue, texture index issue, etc)
    • Null ref error in texture graph when selecting the last cluster option
     
    trilobyteme and inoj like this.
  33. bmaricle

    bmaricle

    Joined:
    Apr 16, 2015
    Posts:
    3
    Does RTP and Mega Splats work together at all?
     
  34. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No, they are both shader systems, so they are more competitors than something that could integrate together..
     
  35. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
  36. Ascensi

    Ascensi

    Joined:
    Sep 7, 2013
    Posts:
    579
    @jbooth Hi Jason does the recent Unity patch 5.6.0p2 fix Megasplat in 5.6?
     
  37. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Nope, bug is still open according to Unity.
     
  38. Falagard

    Falagard

    Joined:
    Jan 8, 2014
    Posts:
    43
    jbooth - the node system looks great!

    I have an interesting idea but not sure how feasible it would be.

    I'd like to be able to use regions defined by closed splines or closed poly lines to define areas that should be "painted" with a particular splat.

    Why would I want to do that?

    This would allow me to do something add a road, or a patch of dirt around a building or under a tree, and as I move the house, I could move the poly region that says "paint dirt here" and it would update the terrain splats.

    I imagine that if the poly region (imagine a rectangle) could be rendered out to a grayscale texture, and include its local position, it could be fed into your texture graph and sampled as data that could auto generate the splat using the graph.

    This means that instead of generating a graph based terrain and manually painting it, I'd always be able to use the graph since my "manual painting" steps would be added with polygon/spline areas.

    This would allow me to make modifications to the terrain and keep my manually placed patches of splatted textures - awesome!

    Thoughts?
     
  39. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    If you can generate the textures to feed into the graph, then it would just work. The only thing you'd need to do is run the graph's update functions each time the data is changed.

    I'm actually looking to integrate with an upcoming road tool for this exact kind of thing, but doing it non-destructively with the graph is a cool idea (but obviously only applicable if you are using the graph)..
     
  40. Falagard

    Falagard

    Joined:
    Jan 8, 2014
    Posts:
    43
    Sounds great.

    I'm thinking maybe as a prototype I'll see if I can generate a texture by rendering some geometry from a top down perspective to a texture. Perhaps I'd be able to control the edge gradient by running a signed distance field generator over the texture using something like this:

    https://www.assetstore.unity3d.com/en/#!/content/50191
     
  41. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I think the one thing you'll likely need is a world space UV option so you can project UVs across the entire terrain rather than using the individual objects UVs. I was planning to add that anyway, so if you get something working I can send you an early version..
     
  42. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Come to think of it, the other option is likely easier. Apply procedural texturing, then raycast down along your spline and edit the vertex/texel accordingly..
     
  43. trilobyteme

    trilobyteme

    Joined:
    Nov 18, 2016
    Posts:
    309
    Looks like Unity 5.6.0p3 has been released. I don't know if they got the bug that affects Megasplat, but here's hoping...
     
  44. PiAnkh

    PiAnkh

    Joined:
    Apr 20, 2013
    Posts:
    126
    Jason

    could you say something about the role of UVs on a mesh when using MegaSplat?
    I am guessing that MegaSplat uses the UVs coordinates of the vertices when laying the materials.
    But can we still change the UVs after converting the mesh to MegaSPlat format?
    I am thinking for example of the case when using MegaSplat for texturing a building. IN some cases you need exact control over the UVs eg placement of a window or door texture.

    thanks
     
  45. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    MegaSplat can use the main or secondary UV channels, world or local space projection, or triplanar UVs. The MegaSplat mesh converter just splits out a mesh with some additional data in the vertex colors, so it's really no different than any other mesh in Unity.
     
  46. PiAnkh

    PiAnkh

    Joined:
    Apr 20, 2013
    Posts:
    126
    That's cool. Where can you specifiy main or secondary UVs?

    If I want to use megasplat in combination with Simplygon to made LODs as you explained in your Unite 2015 talk, including baking out the different textures before inputting to Splygon, I need to have non-overlapping UVs, right?
    Is there a way I can get this to work? If I use UVs for exact placement of textures there will be overlap as the verts will be moving in order to place textures rather than avoiding overlap
     
  47. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    The enumeration under the UV option has a UV or UV2 option (as well as projected and triplanar).

    The render baker in MegaSplat requires non-overlapping UVs in a 0-1 space to produce the correct result. This is because it simply renders the data into the UV space, so if you have overlapping UVs, it will render multiple things into the same texture space and only the last one will be correct.

    What we did in STT (as noted in the Unite talk) is render each triangle to it's own part of a texture page, then produce a new model which mapped to the triangles on that page. While this is not an efficient model, after you run this through simplygon, it stitches it all back together and returns on optimized mesh and tightly packed textures. This allowed us to have arbitrary topology and UV layouts, but it's a reasonable amount of work to get the rendering/conversion working.
     
  48. PiAnkh

    PiAnkh

    Joined:
    Apr 20, 2013
    Posts:
    126
    Thanks that's much clearer. Maybe the way to get the best of both worlds, path to simplygon and freedom to move textures around is to have all textures tile by a large number within the 0-1 space, as is the the case with a terrain, so you can have the polys on a building mesh not overlap and still have enough room to move verts to match the parts of the repeating textures you need
     
  49. SyGem

    SyGem

    Joined:
    Apr 8, 2017
    Posts:
    17
    Firstly, thanks for getting the procedural graph working on terrains - should simplify my workflow a lot. I am struggling a bit to get the results I would like though. My terrain is an island - as an initial pass at texturing I would like everything below a height of 55 to be sandy, above that to be grassy with just a small (5-10 meters) blend between them. I'm using your California Coast graph as a starting point, but I keep ending up with results like this:

    megasplat_1.png

    In this example I have turned the top layer off. I am not seeing the relationship between the texture selector mid point and the result on the terrain. If I set the mid point to 0.2 for example, I end up with no grass at all. Here is a view from a different angle and without the water, with the mid point at 0.05.

    megasplat_2.png

    Am I using the wrong type of node? Or configuring them incorrectly? Any help would be much appreciated, thanks.
     
  50. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,212
    Hi! Has there been any success using MapMagic runtime generated terrains with MegaSplat? IE: zero terrain data in the editor. I can setup the shader integration prior to runtime, specify the shader in MapMagic, and textures will apply on runtime generation, yes?