Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Improved Terrain Texture Tiling

Discussion in 'Made With Unity' started by larsbertram1, Dec 22, 2011.

  1. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    Whenever working with highly detailed terrain textures like rock textures on the terrain, i have to face the problem of highly visible tiling.
    Just approving the texture often doesn’t help at all:

    $origshader.jpg


    Multi-UV Mixing
    So i looked for other solutions and found an article about advanced terrain texturing on udn, where multi-uv mixing is shown as one very cheap method of reducing tiling just using a modified shader which mixes one texture at two different UV sizes.

    Hacking the original shader and mixing the rock texture with a copy of itself at a scale of 4x reduces the tiling.

    $modifiedshader.jpg


    This even gives you nice results on near camera distances.

    $modifiedshaderdetail.jpg


    Modified shader
    Edit the built in shader [or the TerrainReplacement.shader when using "UnityTerrainBump" like in the example above] and find the col-definition of the texture slot you want to use multi uv-mixing with:

    Code (csharp):
    1. // original shader
    2. col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2).rgb;
    3.  
    Change it to:

    Code (csharp):
    1.  
    2. // improved shader
    3. col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2).rgb * tex2D (_Splat2, IN.uv_Splat2 * -0.25).rgb * 4;
    4.  
    Where "*-0.25" adds a 4x size with flip to the scaled texture and "*4" just brightens the color as multiplying 2 texture samples results in a darker color. Just play around with those two parameters to find the best solution.
    You may also want to desaturate the result which would end up in some more instructions on the col-definitions.

    I hope this will help some people to reduce tiling on the terrain and keeping highly detailed textures at the same time.

    lars


    Make sure you read:
    http://udn.epicgames.com/Three/TerrainAdvancedTextures.html
     
    ModLunar, Marrt and nxtboyIII like this.
  2. megmaltese

    megmaltese

    Joined:
    Mar 19, 2009
    Posts:
    2,153
    Cool:) thank you!
     
  3. elias_t

    elias_t

    Joined:
    Sep 17, 2010
    Posts:
    1,152
    Excelent!

    Thank you.
     
  4. Demostenes

    Demostenes

    Joined:
    Sep 10, 2010
    Posts:
    1,106
  5. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    thanks go to epic....
     
  6. Demostenes

    Demostenes

    Joined:
    Sep 10, 2010
    Posts:
    1,106
    Only drawback I see is that you cant use textures with regular shapes (bricks, mozaic, roads....). It would need more complicated implementation done on per material bases (impossible on unity, because terrain engine is not material based), or only for some channels of ARGB splat maps (probably possible).
     
  7. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    @Demostenes: probably you are right as far as bricks and mozaics are concerned, but i guess that you won’t need better tiling on such textures.
    and in fact you can excactly specify which channel uses Multi-UV Mixing and which one doesn’t as each splatmap has its own col-definition in the shader. just have a look at the second picture: the rock textures uses Multi-UV Mixing, the brown ground texture doesn’t.
    lars
     
    Last edited: Dec 23, 2011
  8. chadchat

    chadchat

    Joined:
    Apr 5, 2008
    Posts:
    154
    Nice find Lars.
     
  9. Mingo

    Mingo

    Joined:
    Nov 14, 2010
    Posts:
    39
    This doesn't play well with the "base map" texture that Unity falls back to for distant terrain, but is an otherwise useful technique that also works well on large wall or cliff meshes, etc. I'm not sure if we have access to that terrain base map, but if not then it will never match the tiling, saturation, or luminosity of the rest of the terrain in Unity using this method.

    edit: you'll probably want to make sure that your normal map is still normalised after tiling it over itself like this.
     
    Last edited: Jan 3, 2012
  10. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    you are absolutely right mingo – unfortunately: it doesn’t work well with the automatically created basemap. and as far as i know there is no possibility to get access to the basemap in order to change it in any way.
    for this reason i tend to hide the basemapped distant terrain in the fog…
     
  11. Jibidiah

    Jibidiah

    Joined:
    Oct 17, 2011
    Posts:
    76
    Are you a wizard?
     
  12. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
  13. Syanyde

    Syanyde

    Joined:
    Jan 4, 2011
    Posts:
    57
    Tiling of textures on cliffs was irritating me too, spolied some nice landscapes i'd made and although larger rock textures looked good at a distance, up close they were bad.

    This is an ideal solution, exactly what I needed to get rid of that problem... thank you. :)
     
  14. fallingbrickwork

    fallingbrickwork

    Joined:
    Mar 16, 2009
    Posts:
    1,072
    This is really great. I will have to hop over and give it a test.

    Regards,
    Matt.
     
  15. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
  16. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,618
    very nice
     
  17. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    indeed ;-)
    and it offers much more possibilities if you have just some more texture memory left: think of missapplying the alpha channel to add low frequency disturbance!
    [right now it is only a greyscaled/ low contrast/ upscaled version of the the original rgb terrain texture ]

    lars
     
    Last edited: Jan 25, 2012
  18. sleglik

    sleglik

    Joined:
    Jun 29, 2011
    Posts:
    682
    More than perfect these shaders...

    I know that it is not fair but you are saying that is more possibilites how to improve it. Can you prepare better shaders? For the best quality. For me shaders are too hard :(.

    But perfect job anyway!
     
  19. cod

    cod

    Joined:
    Nov 26, 2011
    Posts:
    267
    it's really awesome!
    However, how can I make textures which tile correctly?
     
  20. Team TSA

    Team TSA

    Joined:
    Oct 19, 2011
    Posts:
    164
    99,999th comment! Woohoo!
     
  21. Syanyde

    Syanyde

    Joined:
    Jan 4, 2011
    Posts:
    57
    After playing with the shaders, I noticed something...

    Instead of:

    Splat * Tex1 * Tex2 * 4

    you can use:

    Splat * 0.5 * (Tex1 + Tex2)

    This should give exact average between the two textures rather than the unpredictable contrast-distortion caused by the multiply operator - you can then ditch the arbitrary multiplier on the end. ;)
     
  22. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    you are absolutely right. but using Splat * 0.5 * (Tex1 + Tex2) usually does not produce such a lively mixture. so it is up to anybody just to test different operators to get the best result for a given texture.

    lars
     
  23. TouchSoft

    TouchSoft

    Joined:
    Oct 18, 2008
    Posts:
    218
    I don't understand how to add other texture slots. it's only using the first.
     
  24. Syanyde

    Syanyde

    Joined:
    Jan 4, 2011
    Posts:
    57
    Very true, I agree with you there that the contrast boost does actually look good with the right textures and numbers applied and stops the dulling caused by a true average mix.

    On the subject of the basemap problems some people have had - do you think it would help doing the big version of the texture first and doing UV*-4 rather than UV*-0.25) - so the big version is first (and the basemap would then be based on that I assume?!?) and the smaller version would still be mixed in the same when viewed close (when the splatmap is used instead of the basemap)?

    I've not tried yet, so it's just a theory... but it seems logical to me :)
     
    Last edited: Jan 28, 2012
  25. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    4,487
    I posted a version in the other thread that lets you use all 4 slots, and control how much they mix, if you want to try that one:

    Modified Terrain shaders

    It's probably a little bit heaver than the current version, but it's better than using 8 texture slots just to mix up the tiling.
     
  26. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    i guess the modified shader is completely ignored when generating the basemap – so this would not help i think.
    but using Splat * 0.5 * (Tex1 + Tex2) should already give you a fitting basemap doesn’t it?
    using Splat * Tex1 * Tex2 * 4 will probably never end up in a correct basemap for it would not contain the contrast strech produced by the multiplication.

    lars
     
  27. Syanyde

    Syanyde

    Joined:
    Jan 4, 2011
    Posts:
    57
    Well, I tested it (what better way to find out?!) :)

    If you put the larger version first the basemap will use the features that are visible at a further distance... so it does help... however, it drops out the 2nd texture - so... it also has a side-effect...

    The two options are:
    1) Large texture used primarily and have shader scale tiling up (so 2nd texture is smaller) = basemap appears to retain the texture featires visible at the furthest distance - but it appears to sharpen those features up as the "noise" of the 2nd texture is omitted.



    2) Small texture used primarily and have shader scale tiling down (so 2nd texture is larger) = basemap appears to retain the texture features visible close-up - so majority of texture perceivable at that distance is dropped and what would be the normal tightly-tiled texture is what is used on the basemap.



    Although you're using the multiply method which will give different results - I think the basemap issue will be the same sort of thing.
     
    Last edited: Jan 29, 2012
  28. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    4,639
    @Syanyde: well, that sounds pretty good!
    well done!

    lars
     
  29. vegenarie

    vegenarie

    Joined:
    Jan 5, 2011
    Posts:
    287
    How do you change the builtin terrain shader? Also tried with the atsV2 and tiling is clearly visible in the demo.
     
  30. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
    Just give a shader the same name as a Unity built in shader.
     
  31. Breakmachine

    Breakmachine

    Joined:
    Sep 19, 2009
    Posts:
    39
    I can't get this to work when switching to Android platform. I've tried maxing the settings in both quality and player settings (Android 4, ARMv7, OpenGL ES 2.0). But I still just get the basemap. Any ideas?
     
  32. Salem-Saberhagen

    Salem-Saberhagen

    Joined:
    Nov 6, 2012
    Posts:
    8
    Is there any chance someone could write a real manual for this? I am really struggling with tiling and this seems to be the solution to get good terrain texturing but no matter how often I follow the readme, nothing changes at all textures stay the same and no script value does anything for me. T.T
     
  33. Imillionaire

    Imillionaire

    Joined:
    Dec 14, 2012
    Posts:
    44
    How do i make it so more than just the first texture does the tile mixing?
     
  34. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
    Nice discovery.
     
  35. miksumortti

    miksumortti

    Joined:
    Apr 7, 2012
    Posts:
    204
    Thanks for this Lars (and Syanyde), really improves the terrain visual quality! :)
     
  36. ZeddZedd

    ZeddZedd

    Joined:
    Feb 16, 2015
    Posts:
    3
    To do this with unity 5 shaders, theres a function called SplatmapMix in the file CGIncludes/TerrainSplatmapCommon.cginc - you can make a copy of this function, modify it, and put it in your own shader file. Doing the Tex1 * Tex2 * 4 makes my textures very overexposed, same goes with the bump map. So the 0.5 * (Tex1 + Tex2) gives a useable end result
     
    b4nj0 likes this.
  37. EternalApps

    EternalApps

    Joined:
    Jun 16, 2015
    Posts:
    6
    ZeddZedd,

    I have located the mentioned file, and found the associated function, I must be doing something wrong though, because I am not seeing changes (even with restart). Can you post your edited code block please?
     
  38. ZeddZedd

    ZeddZedd

    Joined:
    Feb 16, 2015
    Posts:
    3
    @EternalApps ive made a copy of the original shader, and called it something custom, then created a material that uses that shader, and then created terrrain that uses that material. Im guessing the acutal assignment of materials/shader here is the problem since youre not seeing any changes at all

    The actual modified code is as follows
    Code (CSharp):
    1.  
    2.           #ifdef _TERRAIN_NORMAL_MAP
    3.                 fixed4 nrm = 0.0f;
    4.                 nrm += splat_control.r * .5 * (tex2D(_Normal0, IN.uv_Splat0) + tex2D(_Normal0, IN.uv_Splat0 * -.25));
    5.                 nrm += splat_control.g * .5 * (tex2D(_Normal1, IN.uv_Splat1) + tex2D(_Normal1, IN.uv_Splat1 * -.25));
    6.                 nrm += splat_control.b * .5 * (tex2D(_Normal2, IN.uv_Splat2) + tex2D(_Normal2, IN.uv_Splat2 * -.25));
    7.                 nrm += splat_control.a * .5 * (tex2D(_Normal3, IN.uv_Splat3) + tex2D(_Normal3, IN.uv_Splat3 * -.25));
    8.                 mixedNormal = UnpackNormal(nrm);
    9.             #endif
    10.            
    11.             mixedDiffuse = 0.0f;
    12.             mixedDiffuse += splat_control.r * .5 * (tex2D(_Splat0, IN.uv_Splat0) + tex2D(_Splat0, IN.uv_Splat0 * -.25));
    13.             mixedDiffuse += splat_control.g * .5 * (tex2D(_Splat1, IN.uv_Splat1) + tex2D(_Splat1, IN.uv_Splat1 * -.25));
    14.             mixedDiffuse += splat_control.b * .5 * (tex2D(_Splat2, IN.uv_Splat2) + tex2D(_Splat2, IN.uv_Splat2 * -.25));
    15.             mixedDiffuse += splat_control.a * .5 * (tex2D(_Splat3, IN.uv_Splat3) + tex2D(_Splat3, IN.uv_Splat3 * -.25));
     
  39. Speedy_Man1993

    Speedy_Man1993

    Joined:
    Apr 13, 2015
    Posts:
    1
    Yes, but for those kinds of textures, tiling looks more natural with much less effort if you can find decent textures to start with.
     
  40. I-am-Lawrence

    I-am-Lawrence

    Joined:
    Aug 4, 2015
    Posts:
    1
    Thanks! This technique drastically improved the look of my terrain. Thank you very much!
     
  41. Leoo

    Leoo

    Joined:
    May 13, 2013
    Posts:
    96
    This looks exactly to what am looking for,

    Has any1 tested this correctly on Unity5?
    if so, how?

    Can any devs put this into a proyect example?

    Thanks!
     
  42. kulesz

    kulesz

    Joined:
    Jul 1, 2012
    Posts:
    125
    Hi,

    I've created an asset that could help with the terrain tiling problem.
    You can check it here: UV Mixxer