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

ats Colormap terrain shader [RELEASED]

Discussion in 'Assets and Asset Store' started by larsbertram1, Aug 9, 2012.

  1. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    for some reason your 2nd screenshot still looks 1000 time better to me, as if it was the same texture but one is flat while the other is bumped.
    Are you sure i'm getting the correct result? Could you upload a demo with a fixed camera and take a screenshot so i can compare to what it would render like on my pc?
     
  2. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    nevermind, it's just the dark grass are detail dexture is looking much better , found it at the world edges, my bad!
     
  3. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    yepp, your screenshoot shows an area were sand and grass are mixed more or less somthing like 50:50, so contrast is pretty low. as far as bumpmapping is concerned: both textures are rather smooth and the sum is very high.
    so after all it is not a problem of the shader (puhhh) but of texturing…

    lars
     
  4. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi there,
    anybody any feedback on how it works for multiple terrains?

    thanks, lars
     
  5. SevenBits

    SevenBits

    Joined:
    Dec 26, 2011
    Posts:
    1,953
    I am continually impressed by your shaders, Lars. Keep up the good work.
     
  6. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    Bit late to reply to this but if you want just send me your world machine files, i have the pro edition and can simply send you back all outputs at whatever res you want.
     
  7. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    many thanks. i hope you will be able to make something beautiful out of it.

    lars
     
  8. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    thank you very much for your offer.
    but unless people do not ask for a better demo i do not think i need to spend more time on this.
    nevertheless i might come back to this offer in the future.

    meanwhile i would like you to post your own results using high resolution maps.
    just go for it: screenshots or even a webplayer. encourage people showing your work.

    lars
     
  9. ronan-thibaudau

    ronan-thibaudau

    Joined:
    Jun 29, 2012
    Posts:
    1,722
    I don't have much to show yet but if you're fine with me using your textures for Demos i can provide a web player with very high res terrain if you want, (3-5M poly when i'm running it from most angles), could be interesting to see how the shader copes with a large terrain
     
  10. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi ronan,

    i really have no problem with you using my textures. so just go ahead: i would like to see the webplayer!

    lars
     
  11. TerraSame1

    TerraSame1

    Joined:
    Nov 12, 2010
    Posts:
    151
    Hey Lars...
    I have been working with your new Multi Terrain Shader system...
    Here is an up-date....
    The new system is rather finicky... It seems everything must be perfectly laid out...
    But... It does work.... Two days to get it figured out, layed out and working properly...

    I made a new set of four terrains from my large project with World Machine...
    As you can see below.... The upper half of the top pic are pics of the files created in World Machine...
    The lower half has a pic from Unity on the right and a pic on the left from the running project....
    In the pic in the upper right (Color Map 3a) you can see a very small darker square... That is where the pics (below) from
    the actual project fit in where on the right is a Satellite pic at 2048 square and on the left the mating splatmap (will be Flipped Vert.) where green will be grass for tree areas, red will be roadways/parking lots and blue will be snow areas....
    I do wish there was a fourth splat color for cliff texture....
    Anyways..... To create a 200 Unity Terrain package will take quite some time....
    Any way to streamline this setup?
    I do like this concept..... (But, I do like your first setup better... way easier....)
    Another question.....
    Will I be able to code in where the spatmaps are interrogated by color to drop in trees etc... say at the green areas.... etc????
    Thanks for your efforts....



     
  12. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    unfortunately: yes – but you will always have to set up your terrains properly…

    there is the possibility to use a forth detail plus detail normal texture as i have written before, but you have to unlock this feature and to decide how to setup the fourth "average" color:

    but you can activate the support for four detail textures in the shader by just uncommenting the according lines (90, 96, 120, 121). the fourth detail textures could then be chosen individually for each terrain (yeah, at least a bit more variety!). it would go to texture slot 3 in the terrain inspector. it’s normal map would go to slot number 4.
    well, as far as the avarage color for these textures is concerned: you could pass just a whole array of colors (fitting the different 4th textures) to the shader and let it pick up the right one based on the worldposition in the vertex program (if, else if, else if…).
    or make sure that they share pretty much the same basecolor (hmmm, variety?) and just assign a global forth color in the script.


    note: make sure that r + g + b + a = 1.0!

    sorry, but i won’t make it easier –as i don’t know how.
    but may be a custom script will help you stting up your terrains.
    have you already checked terrain edge? just search for it on the forum: it will help to stitch the terrains and might also cover your terrains with trees.

    that is completely up to you. but terrain edge should do the job, i guess.

    lars



    btw: on the ingame screenshoot looks pretty blocky (green foreground). do you know, why?
     
    Last edited: Sep 9, 2012
  13. TerraSame1

    TerraSame1

    Joined:
    Nov 12, 2010
    Posts:
    151
    Hey Lars....
    Fast reply ! That is way awesome....

    I don't quite understand your last comment.... "Blocky?"

    Please remember.... I said that the basic layout was made with World Machine so there are no HQ Sat images... Yet...

    Maybe you are referring to the Normal map which has added lines that kinda look like topo lines...

    Here is a link to a full sized image...
    http://www.terrasame.com/Post1.jpg

    Yes I do know of "Terrain Edge" But I have only used it for stitching....

    Will keep experimenting....
    Thanks...
    :)
     
    Last edited: Sep 9, 2012
  14. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    i mean the areas marked in the picture below: they look a bit blocky or "terraced" –
    as if your heightmap is not very smooth.
    and don’t you use an overall terrain normal map?

    $blocky.jpg
     
  15. TerraSame1

    TerraSame1

    Joined:
    Nov 12, 2010
    Posts:
    151
    Hey Lars....
    Yes... that is not a terrace... it is from the normal map...
    It just looks terraced...
    Look at the Unity Software pic... You will see that there is a normal map.... (Second Slot)
    This is just an experiment...
    That will be no issue in a final 200 terrain setup....
    :)

    Also... Just wanted to let you know that I am working with your Shader...
    :)
     
    Last edited: Sep 9, 2012
  16. kishoreg

    kishoreg

    Joined:
    Sep 10, 2012
    Posts:
    1
    Great Shader Lars.. your shader made my day. Thanks a ton.
     
  17. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    you are welcome!
     
  18. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Lars, how does it handle detail texture tiling and specularity? Could you add those inspector controls back in from SixTimesNothing's original script?
     
  19. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi prime,

    texture tiling of the normal maps equals that of the detail maps – so there is nothing to set up.
    specularity is not supported at the moment – but you could add it copying the lines from sixtimesnothing’s shader to the ats color map shader and adding the setup lines to the .cs file.
    i am sorry but i will not do this as it is a very special feature: personally i prefer to use the alpha channel to store some kind of "disturbance" texture, other people might use it it in a completely different way.
    i hope you will manage to add this functionality –*otherwise pm me.

    lars

    lars
     
  20. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    So I have the pro version of WM2, and I have to say, with 2048x2048 normal maps and color maps, this shader is bonkers. Great job lars.



    This was really basic with no tweaking on the colormap, just a stock basic coverage macro. Can't wait to dig in with photoshop and make a badass one!
     
    Last edited: Sep 19, 2012
  21. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi prime,
    i am glad to read this!
    and thanks for the picture: your terrain looks damn good.

    lars
     
  22. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    Legend your terrain looks legendary:D Didnt know that there macros with such smooth stones, can you tell the name of such macro?

    Lars did you maybe tested this shader on mobile? How does it perform?
     
    Last edited: Sep 19, 2012
  23. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi janpec,

    this shader needs shader model 3.0 and was written to work with built in terrains.
    as usually you will not use unity’s built in terrains but rather solutions like t4m this shader will not help you on mobile devices.

    lars
     
  24. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    The macro was just for the coloring, its called basic coverage. You feed it your terrain and the flow map from your erosion node. As for the stones themselves, thats mostly just a combination of standard erosion and the expander filter with the hybrid setting.
     
  25. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    First let me say that I like this shader. I've been playing around with it some time now.
    I removed the if(IN.distance < _SplattingDistance) statement altogether as I think that it isn't absolutely necessary.
    Next I did a saturate(pow(IN.distance/_SplattingDistance), 4.0)) because this was giving me some weird colors in the distance. Maybe that's why you did the if-statement in the first place. Perhaps it would be nice to expose the exponent in the same way you exposed the _SplattingDistance so that one could tweak the shader more easily on a per-scene basis.
    Last but not least I changed the calculation of the color correction somewhat. Not sure if this is the "right" way to do it or any better than your initial approach. Just from reading the wolfire blog it seemed to be closer to their approach from my mind.

    Code (csharp):
    1.  
    2. //** first implementation
    3.             // apply colorcorrection to detail maps
    4.             // see: http://blog.wolfire.com/2009/12/Detail-texture-color-matching
    5.             // _ColTex0 ... _ColTexN should match the average detail map color so that: _ColTex0 = averageColor(_Splat0.rgb)
    6.             half3 averageColor = splat_control.r * _ColTex0 + splat_control.g * _ColTex1 + splat_control.b * _ColTex2 + splat_control.a * _ColTex3;
    7.             //finalCol = col * (colorMap/averageColor);
    8.            
    9.             // fade out detail maps
    10.             //finalCol = lerp(finalCol, colorMap, fadeout);
    11.             //** end of first implementation
    12.            
    13.             // test
    14.             col = lerp(col, colorMap, fadeout);
    15.             finalCol = col * (colorMap/averageColor);
    16.             // end of test
    17.  
    In the CustomMultiTerrainScriptColorMap.cs I removed the terrIndex variable - as the foreach loop already provides access to each individual terrain object (terr).

    To finally answer your question with a question (how to get the detail map colors):
    Is it possible to use the highest mipmap level to pick the average color of each detail texture from inside the shader?

    I am no shader programmer myself. Just an artist with some self-taught knowledge about this whole shader-business :)

    Edit:
    This might be what I was looking for when I wrote about getting the highest mipmap - http://http.developer.nvidia.com/Cg/tex2Dlod.html - let's see if it works.
     
    Last edited: Sep 25, 2012
  26. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    I think I might have had some minor success with the mipmap sampling. Though there are some pitfalls to this approach and still some errors to catch.
    First tex2Dlod() does not want to work without a #pragma glsl directive. At least that's what I had to use to prevent Unity from throwing a "not supported in this profile" error at me (read more).
    After getting tex2Dlod() accepted I introduced a new float4 _MipMapLevels to the shader and extended your CustomTerrainScript with lines that accept the detail textures as public variables and that get their respective mipmapcount (provided by Texture2D class).
    This count is then written to the shader's global _MipMapLevels variable.
    Within the shader itself I fetch the mipmap color like so inside the surf function (should probably be done inside the vert function though):
    float3 colTex0 = tex2Dlod(_Splat0, float4(IN.uv_Splat0, 0, _MipMapLevels.x - 1)).rgb;

    This is doing something that resembles your average color - but it is also producing some nasty artifacts (see picture). I only got so far with my humble shader knowledge. Way more to learn. Maybe you know a better method for getting the mipmap color values.

    $mipmap_sampling_surface_shader.jpg
     
  27. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Code (csharp):
    1.  
    2. /* Code provided by Chris Morris of Six Times Nothing (http://www.sixtimesnothing.com) */
    3. /* Free to use and modify */
    4.  
    5. using UnityEngine;
    6. using System.Collections;
    7.  
    8. public class CustomTerrainScriptColorMap : MonoBehaviour {
    9.     public float SplattingDistance = 1000;
    10.    
    11.     public Texture2D CustomColorMap;
    12.     public Texture2D TerrainNormalMap;
    13.    
    14.     public Texture2D SplatTex0;
    15.     public Texture2D SplatTex1;
    16.     public Texture2D SplatTex2;
    17.     public Texture2D SplatTex3;
    18.    
    19.     public float TilingTex0;
    20.     public float TilingTex1;
    21.     public float TilingTex2;
    22.     public float TilingTex3;
    23.    
    24.     public Texture2D Bump0;
    25.     public Texture2D Bump1;
    26.     public Texture2D Bump2;
    27.     public Texture2D Bump3;
    28.    
    29.     void Start()
    30.     {
    31.         Terrain[] terrains = (Terrain[])FindSceneObjectsOfType(typeof(Terrain));
    32.         // make sure that we will never see the basemap...
    33.        
    34.         foreach (Terrain terr in terrains)
    35.         {
    36.             terr.basemapDistance = 100000;
    37.         }
    38.        
    39.         Shader.SetGlobalFloat("_SplattingDistance", SplattingDistance);
    40.        
    41.         if(CustomColorMap)
    42.             Shader.SetGlobalTexture("_CustomColorMap", CustomColorMap);
    43.                
    44.         if(TerrainNormalMap)
    45.             Shader.SetGlobalTexture("_TerrainNormalMap", TerrainNormalMap);
    46.        
    47.         if(Bump0)
    48.             Shader.SetGlobalTexture("_BumpMap0", Bump0);
    49.        
    50.         if(Bump1)
    51.             Shader.SetGlobalTexture("_BumpMap1", Bump1);
    52.        
    53.         if(Bump2)
    54.             Shader.SetGlobalTexture("_BumpMap2", Bump2);
    55.        
    56.         if(Bump3)
    57.             Shader.SetGlobalTexture("_BumpMap3", Bump3);
    58.        
    59.         Vector4 mipMapLevels = Vector4.zero;
    60.        
    61.         if (SplatTex0)
    62.         {
    63.             Shader.SetGlobalTexture("_Splat0", SplatTex0);
    64.             mipMapLevels.x = SplatTex0.mipmapCount;
    65.         }
    66.        
    67.         if (SplatTex1)
    68.         {
    69.             Shader.SetGlobalTexture("_Splat1", SplatTex1);
    70.             mipMapLevels.y = SplatTex1.mipmapCount;
    71.         }
    72.        
    73.         if (SplatTex2)
    74.         {
    75.             Shader.SetGlobalTexture("_Splat2", SplatTex2);
    76.             mipMapLevels.x = SplatTex2.mipmapCount;
    77.         }
    78.        
    79.         if (SplatTex3)
    80.         {
    81.             Shader.SetGlobalTexture("_Splat3", SplatTex3);
    82.             mipMapLevels.x = SplatTex3.mipmapCount;
    83.         }
    84.        
    85.         Shader.SetGlobalVector("_MipMapLevels", mipMapLevels);
    86.        
    87.         // quick and dirty - we assume terrains to always be square
    88.         // so that size.x equals size.z
    89.         float terrainSize = terrains[0].terrainData.size.x;
    90.         // used for tiling inside the shader
    91.         Shader.SetGlobalVector("_Tiling", new Vector4(terrainSize / TilingTex0, terrainSize / TilingTex1, terrainSize / TilingTex2, terrainSize / TilingTex3));
    92.     }
    93. }
    94.  
    95.  
    Code (csharp):
    1.  
    2. /* Code provided by Chris Morris of Six Times Nothing (http://www.sixtimesnothing.com) */
    3. /* Free to use and modify  */
    4.  
    5.  
    6. Shader "Hidden/TerrainEngine/Splatmap/Lightmap-FirstPass"
    7. {
    8.  
    9.     Properties
    10.     {
    11.         _Control ("Control (RGBA)", 2D) = "red" {}
    12.         _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    13.         _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    14.         _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    15.         _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    16.         // used in fallback on old cards
    17.         _MainTex ("BaseMap (RGB)", 2D) = "white" {}
    18.         _Color ("Main Color", Color) = (1,1,1,1)
    19.         _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
    20.     }
    21.  
    22.     SubShader
    23.     {
    24.         Tags
    25.         {
    26.             "SplatCount" = "4"
    27.             "Queue" = "Geometry-100"
    28.             "RenderType" = "Opaque"
    29.         }
    30.    
    31.         CGPROGRAM
    32.         #pragma glsl
    33.         #pragma surface surf BlinnPhong vertex:vert
    34.         #pragma target 3.0
    35.         #include "UnityCG.cginc"
    36.        
    37.         sampler2D _Control;                                     // splatmap - controls the detail texture splatting
    38.         sampler2D _CustomColorMap, _TerrainNormalMap;           // colormap and normalmap of terrain
    39.         sampler2D _BumpMap0, _BumpMap1, _BumpMap2, _BumpMap3;   // detail texture bump
    40.         sampler2D _Splat0,_Splat1,_Splat2,_Splat3;              // detail texture diffuse
    41.         float4 _MipMapLevels;                                   // mipmap levels of detail textures
    42.         float4 _Tiling;                                         // tiling of detail textures
    43.         float _SplattingDistance;                               // distance at which detail textures fade out and colormap takes over entirely
    44.    
    45.         struct Input
    46.         {
    47.             float3 worldPos;
    48.             float2 uv_Control : TEXCOORD0;
    49.             float4 col0;
    50.             float4 col1;
    51.             float4 col2;
    52.             //float3 col3;
    53.             float distance;
    54.         };
    55.    
    56.         void vert (inout appdata_full v, out Input o)
    57.         {
    58.             // Supply the shader with tangents for the terrain
    59.             // A general tangent estimation
    60.             float3 T1 = float3(1, 0, 1);
    61.             float3 Bi = cross(T1, v.normal);
    62.             float3 newTangent = cross(v.normal, Bi);
    63.             normalize(newTangent);
    64.             v.tangent.xyz = newTangent.xyz;
    65.             if (dot(cross(v.normal,newTangent),Bi) < 0)
    66.                 v.tangent.w = -1.0f;
    67.             else
    68.                 v.tangent.w = 1.0f;
    69.            
    70.             float distanceVar = distance(_WorldSpaceCameraPos, mul(_Object2World, v.vertex));  
    71.             o.distance = distanceVar;
    72.             // let's do the mipmap look-up in here... hope that works
    73.             o.col0 = tex2Dlod(_Splat0, float4(v.texcoord.xy * _Tiling.x, 0, _MipMapLevels.x - 1));
    74.             o.col1 = tex2Dlod(_Splat1, float4(v.texcoord.xy * _Tiling.y, 0, _MipMapLevels.y - 1));
    75.             o.col2 = tex2Dlod(_Splat2, float4(v.texcoord.xy * _Tiling.z, 0, _MipMapLevels.z - 1));
    76.             float3 col3 = tex2Dlod(_Splat3, float4(v.texcoord.xy * _Tiling.w, 0, _MipMapLevels.w - 1)).rgb;
    77.             o.col0.w = col3.x;
    78.             o.col1.w = col3.y;
    79.             o.col2.w = col3.z;
    80.         }
    81.            
    82.         void surf (Input IN, inout SurfaceOutput o)
    83.         {
    84.             half3 col;
    85.             half3 finalCol;
    86.            
    87.             // do all texture fetches outside the if
    88.             half3 colorMap = tex2D(_CustomColorMap, IN.uv_Control).rgb;
    89.             half4 splat_control = tex2D(_Control, IN.uv_Control);
    90.             half3 splatcol0 = tex2D (_Splat0, IN.uv_Control * _Tiling.x).rgb;
    91.             half3 splatcol1 = tex2D (_Splat1, IN.uv_Control * _Tiling.y).rgb;
    92.             half3 splatcol2 = tex2D (_Splat2, IN.uv_Control * _Tiling.z).rgb;
    93.             half3 splatcol2_2nd = tex2D (_Splat2, IN.uv_Control * _Tiling.z * -0.5).rgb;
    94.             half3 splatcol3 = tex2D (_Splat3, IN.uv_Control * _Tiling.w).rgb;
    95.             float3 normalsplat0 = UnpackNormal(tex2D(_BumpMap0, IN.uv_Control * _Tiling.x));
    96.             float3 normalsplat1 = UnpackNormal(tex2D(_BumpMap1, IN.uv_Control * _Tiling.y));
    97.             float3 normalsplat2 = UnpackNormal(tex2D(_BumpMap2, IN.uv_Control * _Tiling.z));
    98.             float3 normalsplat2_2nd = UnpackNormal(tex2D(_BumpMap2, IN.uv_Control * _Tiling.y * -0.5));
    99.             float3 normalsplat3 = UnpackNormal(tex2D(_BumpMap3, IN.uv_Control * _Tiling.y));
    100.             float3 farnormal = UnpackNormal(tex2D(_TerrainNormalMap, IN.uv_Control));
    101.            
    102.             // fadeout for detail normal maps
    103.             float fadeoutFactor = IN.distance / _SplattingDistance;
    104.             float fadeout = saturate(pow(fadeoutFactor, 4.0));
    105.            
    106.             //// 4 splats, normals, and specular settings
    107.             // use the built in splat map --> make sure you have copied your custom made to the built in via script
    108.            
    109.             //// first detail texture: red = ground
    110.             col = splat_control.r * splatcol0;
    111.             o.Normal = splat_control.r * normalsplat0;
    112.    
    113.             //// second detail texture: green = grass
    114.             col += splat_control.g * splatcol1;
    115.             o.Normal += splat_control.g * normalsplat1;
    116.        
    117.             //// third detail texture rock: blue = rock
    118.             // uses uv mixing
    119.             col += splat_control.b * (splatcol2*.65 + splatcol2_2nd*.35);
    120.             o.Normal += splat_control.b * (normalsplat2*.5 + normalsplat2_2nd*.5);
    121.            
    122.             //// forth detail texture: alpha
    123.             col += splat_control.a * splatcol3;
    124.             o.Normal += splat_control.a * normalsplat3;
    125.            
    126.             /// final composition
    127.            
    128.             // fade out detail normal maps
    129.             o.Normal = lerp(normalize(o.Normal + farnormal), farnormal, fadeout);
    130.            
    131.             //** first implementation
    132.             // apply colorcorrection to detail maps
    133.             // see: http://blog.wolfire.com/2009/12/Detail-texture-color-matching
    134.             // _ColTex0 ... _ColTexN should match the average detail map color so that: _ColTex0 = averageColor(_Splat0.rgb)
    135.             float3 col3 = IN.col0.w;
    136.             col3.y = IN.col1.w;
    137.             col3.z = IN.col2.w;
    138.             half3 averageColor = splat_control.r * IN.col0.rgb + splat_control.g * IN.col1.rgb + splat_control.b * IN.col2.rgb + splat_control.a * col3;
    139.             finalCol = col * (colorMap/averageColor);
    140.            
    141.             // fade out detail maps
    142.             finalCol = lerp(finalCol, colorMap, fadeout);
    143.            
    144.             //col = lerp(col, colorMap, fadeout);
    145.             //finalCol = col * (colorMap/averageColor);
    146.                
    147.             o.Albedo = finalCol;
    148.             o.Alpha = 0.0;
    149.         }
    150.     ENDCG  
    151.     }
    152.    
    153.     // Fallback to Diffuse
    154.     Fallback "Diffuse"
    155. }
    156.  
    Not much time to explain. This seems to eliminate the white sparkles. But I would be grateful if you or someone else with superior shader knowledge would have a look at this approach of mine. Thx Lars for your dedication to this community!
     
  28. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi marco,

    i did not have the time to have a closer look at your changes but as far as i can say from a first glance using text2dlod might be a clever but also expensive solution as it needs four more textures lookups - although you perform them in the vertex program which might cause problems on some gpus i guess.

    anyway; if it works for you: well done!

    lars
     
    Last edited: Oct 1, 2012
  29. drift501

    drift501

    Joined:
    Apr 20, 2012
    Posts:
    76
    Hello Lars. Does this shade work alongside your other terrain shaders, for example can I run this shader and your triplanar shader at the same time on the same terrain? Thanks, Zac
     
  30. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    no, you can’t: there can always be just one shader for terrain of course. so either or.

    lars
     
  31. drift501

    drift501

    Joined:
    Apr 20, 2012
    Posts:
    76
    Ah, Ok then thanks. I have no idea how shaders work and I don't really plan to learn them anytime soon because I have access to any shader I need but it would be nice to have both combined into one shader along with you snow shader.
     
  32. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    in case you really need it there should be a way to combine the color map shader with the snow shader, or the color map shader with the triplanar shader - but those would be rather heavy and fully customized shaders.
    so if you really, really need it you will have to find someone writing this custom tailored shader.

    lars
     
  33. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    Hey Lars,

    thx for taking the time to answer me. I've changed the shader quite a bit over the last days and it is performing well on an NVIDIA GeForce 8800 GTS. But you are right the lookup is happening on every vertex - although it is returning the same 4 color values. If there's a way to do this once and save the values in a global shader variable I'd be grateful to know.
    As for the tex2Dlod() function not being supported on some graphics cards: I went to this site http://http.developer.nvidia.com/Cg/index_profiles.html and discovered that it should be supported by cards of the NVIDIA GeForce 6/7 series and newer (vp40).
    If there's still a graphics card out there that's not supporting vp40 I think we might just ignore it. Or we'll provide a much simpler fallback shader... haven't decided upon this yet.
    Also I made a little tool for a more artist friendly multi terrain setup. Maybe I can post it here later this week.
     
  34. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    That would be awesome, friendly multi terrain setup:D
     
  35. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    hi marco,

    i did not speak about text2dlod not beeing supported generally but eventually not beeing supported in vertex programms on some gpus.
    little but essential difference ;-)
    global shader vars unfortunately do not work as they will be the same fpor all terrians (when using multiple ones –*otherwise shadervars do eork of course like in the initial version).
    the only way i can think of to make global vars work with multiple terrains having different detail textures would be to have a whole array of variables and then let the shader decide which to take according to the vertex position (in order to find out which terrain is currently rendered). but i am not sure whether this would be faster than a tex2dlod lookup.
    anyway: having terrain materials in unity 4 will completely solve this problem anyway i guess.

    a little tool just woud be very helpful.

    lars

    p.s.: und wenn’s probleme oder fragen gibt, dann schreib mir einfach eine nachricht.
     
  36. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    Thank you very much for this Shader. Finally I am able to create my terrain how I imagined it for some time.
     

    Attached Files:

    Last edited: Oct 4, 2012
  37. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899
    @Pathelion:
    nice, just keep us updated!

    lars


    p.s.: may be a little more variety on the green?
     
  38. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    This looks simply stunning, will have to give it a try!
     
  39. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    I think that's because of the coastal terrain macro from World Machine and its generated Colormap. Like you can see I baked the AO and flowmap into the Colormap. As detail textures I used a rock texture, a grass texture, a sand texture for underwater and as fourth a dirt texture which blends with the grass.

    Right now I have no idea, what I could change to optimize the result except adding the buildings, the paths and tree/grass meshes.

    But the result now is so much better than before with Tom's Terrain Tools.
     
  40. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    Pathelion looks nice, maybe you could raise the value of shore effect in World Machine becouse there is no shore in your lake. Also you could extract mask of AO layer from coastal terrain macro and stronger the shadow lines of stone/ rock texture. Also if you change hue of grass texture to more yellowish it would look better, or at least more realistic.
     
  41. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    Yeah the shore line is really a problem in world machine. If I raise it a little higher, the whole grass mixes with the sand. It's really hard to adjust at the perfect level.
     
  42. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    Its actually not , you have to enter "curve editor" (i think its third icon in WM in main toolbar) you can specify there where you want your shore effect to be applied and where not, it takes little time to get it right but it is whorth it. If you are making Alpine style of lake i would suggest you to pick little darker sand texture and later use some little stones detail map becouse there actually is no sand in high mountain areas - in case if thats what you target.
     
  43. l0cke

    l0cke

    Joined:
    Apr 15, 2012
    Posts:
    438
    Practise more with WE. This is my result:

    http://www.dropmocks.com/mBlWpt

    Indeed no Unity, but I heard, that on Unity can be done everything as on other engines, so no problem for you too ;)
     
  44. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    Maybe also more practising in Mudbox ;-) because I sculpted the heightmap and I want to try to reach the right the landscape form that my buddy and me imagine.
    The coastal macro was for now the fastest way to see a result with larsbertrams shader. But yes l0cke your terrain looks stunning.
    The main atmosphere I want to reach after some practising is kind of scottish highlands like in Glencoe.
     
  45. sgoodrow

    sgoodrow

    Joined:
    Sep 28, 2012
    Posts:
    150
    Very nice shader lars, I'll have some screenshots of my implementation soon. I was wondering, is there any chance you could add specular lighting to the shader, or briefly explain how to modify the pipeline to include another shader? I am beginning to learn to write them myself, but am not really there yet.

    Also, how difficult is it to add a second splatmap, to add an additional 4 textures? I'd really like to have access to a few more, but I don't think I'll need any more than 8.

    If you're too busy to add either of these requests -- no problem, I can try to do it myself. If that's the case, some thoughts on what they would entail to get me on my way would be very helpful!

    Thanks. Again, great job, it looks and works great!

    P.S.: I am finding that in my version of Unity (3.5.X), the Colormap orientation is vertically opposite to the Normalmap, Heightmap and Splatmaps, as produced from a World Machine 2 pipeline. If anyone is having trouble aligning things, let me know.
     
  46. I am da bawss

    I am da bawss

    Joined:
    Jun 2, 2011
    Posts:
    2,574

    Wow that looks amazing. What's WE?
    Is that Unity?
     
  47. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    I am pretty sure he meant WM - World Machine.
     
  48. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,899

    hi sgoodrow,

    the shader is already prepared for specular lighting – as i did not delete/change the original lines from the bumped spec terrain shader properly ;-)
    so it is quite easy to add it.

    as far as the support for more than 4 detail maps is concerned: i will not work in this unless unity 4 gets public, because the next version of unity should make this much easier.

    i am looking forward to see some screenshoots from your implementation.

    lars




    color map terrain shader – specular lighting

    please note:
    * the glossmap is stored in the alpha channel of the detail maps.
    * shader supports multi uv mixing for the 3rd detail texture (rock) – even for specularity
    * specular lighting will be calculated for the whole terrain – it is not faded out over distance unlike the detail textures.
    * _Spec0 – _Spec3 should be set within a range from 0.3 – 1.0

    shader:
    Code (csharp):
    1.  
    2. /* Original Code provided by Chris Morris of Six Times Nothing (http://www.sixtimesnothing.com) */
    3. /* Free to use and modify  */
    4.  
    5.  
    6. Shader "Hidden/TerrainEngine/Splatmap/Lightmap-FirstPass" {
    7. Properties {
    8.     _Control ("Control (RGBA)", 2D) = "red" {}
    9.     _Splat3 ("Layer 3 (A)", 2D) = "white" {}
    10.     _Splat2 ("Layer 2 (B)", 2D) = "white" {}
    11.     _Splat1 ("Layer 1 (G)", 2D) = "white" {}
    12.     _Splat0 ("Layer 0 (R)", 2D) = "white" {}
    13.    
    14.     // used in fallback on old cards
    15.     _MainTex ("BaseMap (RGB)", 2D) = "white" {}
    16.     _Color ("Main Color", Color) = (1,1,1,1)
    17. }
    18.  
    19. SubShader {
    20.     Tags {
    21.         "SplatCount" = "4"
    22.         "Queue" = "Geometry-100"
    23.         "RenderType" = "Opaque"
    24.     }
    25. CGPROGRAM
    26. #pragma surface surf BlinnPhong vertex:vert
    27. #pragma target 3.0
    28. #include "UnityCG.cginc"
    29.  
    30. struct Input {
    31.     float3 worldPos;
    32.     float2 uv_Control : TEXCOORD0;
    33.     float2 uv_Splat0 : TEXCOORD1;
    34.     float2 uv_Splat1 : TEXCOORD2;
    35.     float2 uv_Splat2 : TEXCOORD3;
    36.     float2 uv_Splat3 : TEXCOORD4;
    37.    
    38.     ///
    39.    
    40.     float distance;
    41.    
    42.    
    43. };
    44.  
    45. void vert (inout appdata_full v, out Input o) {
    46.     // Supply the shader with tangents for the terrain
    47.     // A general tangent estimation
    48.     float3 T1 = float3(1, 0, 1);
    49.     float3 Bi = cross(T1, v.normal);
    50.     float3 newTangent = cross(v.normal, Bi);
    51.     normalize(newTangent);
    52.     v.tangent.xyz = newTangent.xyz;
    53.     if (dot(cross(v.normal,newTangent),Bi) < 0)
    54.         v.tangent.w = -1.0f;
    55.     else
    56.         v.tangent.w = 1.0f;
    57.    
    58.     float distanceVar = distance(_WorldSpaceCameraPos, mul(_Object2World, v.vertex));  
    59.     o.distance = distanceVar;
    60.    
    61. }
    62. sampler2D _Control;
    63. sampler2D _CustomColorMap, _TerrainNormalMap;
    64. sampler2D _BumpMap0, _BumpMap1, _BumpMap2, _BumpMap3;
    65. sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
    66. float _Spec0, _Spec1, _Spec2, _Spec3;
    67. float3 _ColTex0, _ColTex1, _ColTex2, _ColTex3;
    68. float4 _v4CameraPos, _SpecularColor;
    69. float _SplattingDistance;
    70.  
    71. void surf (Input IN, inout SurfaceOutput o) {
    72.    
    73.     half3 col;
    74.     half3 finalCol;
    75.    
    76.     // do all texture fetches outside the if
    77.     half3 colorMap = tex2D(_CustomColorMap, IN.uv_Control);
    78.     half4 splat_control = tex2D(_Control, IN.uv_Control);
    79.     half4 splatcol0 = tex2D (_Splat0, IN.uv_Splat0);
    80.     half4 splatcol1 = tex2D (_Splat1, IN.uv_Splat1);
    81.     half4 splatcol2 = tex2D (_Splat2, IN.uv_Splat2);
    82.     // use a positive factor to enhance the normal map
    83.     half4 splatcol2_2nd = tex2D (_Splat2, IN.uv_Splat2* .5);
    84.     half4 splatcol3 = tex2D (_Splat3, IN.uv_Splat3);
    85.     float3 normalsplat0 = UnpackNormal(tex2D(_BumpMap0, IN.uv_Splat0));
    86.     float3 normalsplat1 = UnpackNormal(tex2D(_BumpMap1, IN.uv_Splat1));
    87.     float3 normalsplat2 = UnpackNormal(tex2D(_BumpMap2, IN.uv_Splat2));
    88.     // use a positive factor to enhance the normal map
    89.     float3 normalsplat2_2nd = UnpackNormal(tex2D(_BumpMap2, IN.uv_Splat2* .5));
    90.     float3 normalsplat3 = UnpackNormal(tex2D(_BumpMap3, IN.uv_Splat3));
    91.     float3 farnormal = UnpackNormal(tex2D(_TerrainNormalMap, IN.uv_Control));
    92.    
    93.     if (IN.distance < _SplattingDistance)
    94.     {
    95.        
    96.         //// 4 splats, normals, and specular settings
    97.         // use the built in splat map --> make sure you have copied your custom made to the built in via script
    98.        
    99.         //// first detail texture: red = ground
    100.         col = splat_control.r * splatcol0.rgb;
    101.         o.Normal = splat_control.r * normalsplat0;
    102.        
    103.  
    104.         //// second detail texture: green = grass
    105.         col += splat_control.g * splatcol1.rgb;
    106.         o.Normal += splat_control.g * normalsplat1;
    107.        
    108.    
    109.         //// third detail texture rock: blue = rock
    110.         // uses uv mixing
    111.         col += splat_control.b * (splatcol2.rgb*.85 + splatcol2_2nd.rgb*.15);
    112.         o.Normal += splat_control.b * (normalsplat2*.5 + normalsplat2_2nd*.5);
    113.        
    114.        
    115.         //// forth detail texture: alpha
    116.         col += splat_control.a * splatcol3.rgb;
    117.         o.Normal += splat_control.a * normalsplat3;
    118.        
    119.        
    120.         /// final composition
    121.        
    122.         // fade out detail normal maps
    123.         float fadeout = pow(IN.distance/_SplattingDistance, 4.0);
    124.         o.Normal = lerp(normalize(o.Normal + farnormal), farnormal, fadeout);
    125.        
    126.         // apply colorcorrection to detail maps
    127.         // see: http://blog.wolfire.com/2009/12/Detail-texture-color-matching
    128.         half3 color_correction = splat_control.r*_ColTex0 + splat_control.g*_ColTex1 + splat_control.b*_ColTex2 + splat_control.a*_ColTex3;
    129.         finalCol = col * (colorMap/color_correction);
    130.        
    131.         // fade out detail maps
    132.         finalCol = lerp(finalCol, colorMap, fadeout);
    133.     }
    134.     else {
    135.         finalCol = colorMap;
    136.         o.Normal = farnormal;
    137.     }
    138.    
    139.     _SpecColor = _SpecularColor;
    140.    
    141.     o.Gloss = splatcol0.a * splat_control.r;
    142.     o.Specular = _Spec0 * splat_control.r;
    143.     o.Gloss += splatcol1.a * splat_control.g;
    144.     o.Specular += _Spec1 * splat_control.g;
    145.     // here you will find multi uv mixing even for the glossmap
    146.     o.Gloss += splatcol2.a * splat_control.b *.85;
    147.     o.Gloss += splatcol2_2nd.a * splat_control.b *.15;
    148.     o.Specular += _Spec2 * splat_control.b;
    149.    
    150.     o.Gloss += splatcol3.a * splat_control.a;
    151.     o.Specular += _Spec3 * splat_control.a;
    152.        
    153.     o.Albedo = finalCol;
    154.     o.Alpha = 0.0;
    155. }
    156. ENDCG  
    157. }
    158.  
    159. // Fallback to Diffuse
    160. Fallback "Diffuse"
    161. }
    162.  
    and the modified terrainscript:

    Code (csharp):
    1.  
    2. /* Original Code provided by Chris Morris of Six Times Nothing (http://www.sixtimesnothing.com) */
    3. /* Free to use and modify */
    4.  
    5. using UnityEngine;
    6. using System.Collections;
    7.  
    8. public class CustomTerrainScriptColorMap : MonoBehaviour {
    9.     public float SplattingDistance = 600;
    10.    
    11.     public Texture2D CustomColorMap;
    12.     public Texture2D TerrainNormalMap;
    13.    
    14.     public Color ColTex0;
    15.     public Color ColTex1;
    16.     public Color ColTex2;
    17.     public Color ColTex3;
    18.    
    19.     public Color SpecularColor;
    20.    
    21.     public float Spec0 = 0.078125f;
    22.     public float Spec1 = 0.078125f;
    23.     public float Spec2 = 0.078125f;
    24.     public float Spec3 = 0.078125f;
    25.  
    26.     public Texture2D Bump0;
    27.     public Texture2D Bump1;
    28.     public Texture2D Bump2;
    29.     public Texture2D Bump3;
    30.    
    31.    
    32.     void Start () {
    33.        
    34.         Application.targetFrameRate = 300;
    35.        
    36.         // make sure that we will never see the basemap...
    37.         Terrain.activeTerrain.basemapDistance = 100000;
    38.        
    39.         Shader.SetGlobalFloat("_SplattingDistance", SplattingDistance);
    40.        
    41.         Shader.SetGlobalColor("_ColTex0", ColTex0);
    42.         Shader.SetGlobalColor("_ColTex1", ColTex1);
    43.         Shader.SetGlobalColor("_ColTex2", ColTex2);
    44.         Shader.SetGlobalColor("_ColTex3", ColTex3);
    45.        
    46.         Shader.SetGlobalColor("_SpecularColor", SpecularColor);
    47.        
    48.         Shader.SetGlobalFloat("_Spec0", Spec0);
    49.         Shader.SetGlobalFloat("_Spec1", Spec1);
    50.         Shader.SetGlobalFloat("_Spec2", Spec2);
    51.         Shader.SetGlobalFloat("_Spec3", Spec3);
    52.        
    53.        
    54.         if(CustomColorMap)
    55.             Shader.SetGlobalTexture("_CustomColorMap", CustomColorMap);
    56.                
    57.         if(TerrainNormalMap)
    58.             Shader.SetGlobalTexture("_TerrainNormalMap", TerrainNormalMap);
    59.        
    60.         if(Bump0)
    61.             Shader.SetGlobalTexture("_BumpMap0", Bump0);
    62.        
    63.         if(Bump1)
    64.             Shader.SetGlobalTexture("_BumpMap1", Bump1);
    65.        
    66.         if(Bump2)
    67.             Shader.SetGlobalTexture("_BumpMap2", Bump2);
    68.        
    69.         if(Bump3)
    70.             Shader.SetGlobalTexture("_BumpMap3", Bump3);   
    71.     }
    72. }
    73.  
     
    Last edited: Oct 6, 2012
  49. I am da bawss

    I am da bawss

    Joined:
    Jun 2, 2011
    Posts:
    2,574
    You sure? That doesn't look like World Machine interface.
     
  50. Knightmore

    Knightmore

    Joined:
    May 11, 2012
    Posts:
    227
    He meant World Machine, but he used his results in some other engine.