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

Question Terrain Details Blurry

Discussion in 'General Graphics' started by DPunK, Mar 27, 2021.

  1. DPunK

    DPunK

    Joined:
    May 15, 2019
    Posts:
    25
    I am trying to go for a crisp pixelated look for textures but when it comes to terrain, the grass I add on the details layer is all blurry even though the texture is set to "on point" and looks fine if used anywhere else

    I've seen this question asked multiple times but never solved.
    In one thread it was suggested that the terrain component creates his own material under the hood for the details. If that's the case how can I address it to get the desired result?

    I'm using unity 2018.4.10f1 if that matters
     
  2. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,866
  3. DPunK

    DPunK

    Joined:
    May 15, 2019
    Posts:
    25
    Thanks for the response!

    I am not sure if I'm doing it correctly:
    I copied the FirstPass.shader to my project and created a new material from it and assigned to my terrain.
    Any change I make to lines 54,55,56 doesn't affect my grass on the detail layer at all. Even if I remove the lines nothing changes.

    I'm not that good with shaders so I would appreciate if you could elaborate on what I should do with these lines
     
  4. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,866
    This is a simple solution:
    Create a shader with the below name in your project:
    Code (CSharp):
    1. Shader "Hidden/TerrainEngine/Details/WavingDoublePass"
    Now your grass shader is this created shader

    you must control grass shader properties using script

    Example shader:
    Code (CSharp):
    1. Shader "Hidden/TerrainEngine/Details/WavingDoublePass"
    2. {
    3.     Properties
    4.     {
    5.         _Cutoff( "Mask Clip Value", Float ) = 0.5
    6.         [Header(Translucency)]
    7.         _Grass_Translucency("Strength", Range( 0 , 50)) = 1
    8.         _TransNormalDistortion("Normal Distortion", Range( 0 , 1)) = 0.1
    9.         _TransScattering("Scaterring Falloff", Range( 1 , 50)) = 2
    10.         _TransDirect("Direct", Range( 0 , 1)) = 1
    11.     //    _Grass_TransAmbient("Ambient", Range( 0 , 1)) = 0.2
    12.         //_Grass_TransShadow("Shadow", Range( 0 , 1)) = 0.9
    13.         _MainTex("MainTex", 2D) = "white" {}
    14.         _Grass_Translucency_10_x_multiplier("Translucency_10_x_multiplier", Float) = 10
    15.                 [Header(Wind Settings)]
    16.         // Wave mode leave
    17.         _MinY("Minimum Y Value", Range(-5,0)) = -1
    18.  
    19.         _xScale ("X Amount", Range(-0.2,0.2)) = 0.5
    20.         _yScale ("Z Amount", Range(-0.2,0.2)) = 0.5
    21.         [HideInInspector] _texcoord( "", 2D ) = "white" {}
    22.         [HideInInspector] __dirty( "", Int ) = 1
    23.     }
    24.  
    25.     SubShader
    26.     {
    27.         Tags{ "RenderType" = "TransparentCutout"  "Queue" = "AlphaTest+0" }
    28.         Cull Off
    29.         CGPROGRAM
    30.         #include "UnityPBSLighting.cginc"
    31.         #pragma target 3.0
    32.         #pragma surface surf StandardSpecularCustom keepalpha addshadow fullforwardshadows exclude_path:deferred  vertex:vert
    33.         struct Input
    34.         {
    35.             float2 uv_texcoord;
    36.         };
    37.  
    38.         struct SurfaceOutputStandardSpecularCustom
    39.         {
    40.             fixed3 Albedo;
    41.             fixed3 Normal;
    42.             half3 Emission;
    43.             fixed3 Specular;
    44.             half Smoothness;
    45.             half Occlusion;
    46.             fixed Alpha;
    47.             fixed3 Translucency;
    48.         };
    49.  
    50.         uniform float4 _Grass_Color;
    51.         uniform sampler2D _MainTex;
    52.         uniform float4 _MainTex_ST;
    53.         uniform float4 Grass_Specular_Color;
    54.         uniform float _Grass_Smoothness;
    55.         uniform half _Grass_Translucency;
    56.         uniform half _TransNormalDistortion;
    57.         uniform half _TransScattering;
    58.         uniform half _TransDirect;
    59.         uniform half _Grass_TransAmbient;
    60.         uniform half _Grass_TransShadow;
    61.         uniform float _Grass_Translucency_Intensity;
    62.         uniform float _Grass_Translucency_10_x_multiplier;
    63.         uniform float4 _Grass_Translucency_Color;
    64.         uniform float _Cutoff = 0.5;
    65.         float _MinY;
    66.         float _xScale;
    67.         float _yScale;
    68.         float _Grass_Wind_Scale;
    69.         float _Grass_Wind_Speed;
    70.         float _Grass_World_Scale;
    71.         float _Amount;
    72.  
    73.         void vert (inout appdata_full v)
    74.         {
    75.             float num = v.vertex.z;
    76.  
    77.             if ((num-_MinY) > 0.0) {
    78.                 float3 worldPos = mul (unity_ObjectToWorld, v.vertex).xyz;
    79.                 float x = sin(worldPos.x/_Grass_World_Scale + (_Time.y*_Grass_Wind_Speed)) * (num-_MinY) * _Grass_Wind_Scale * 0.01;
    80.                 float y = sin(worldPos.y/_Grass_World_Scale + (_Time.y*_Grass_Wind_Speed)) * (num-_MinY) * _Grass_Wind_Scale * 0.01;
    81.  
    82.                 v.vertex.x += x * _xScale;
    83.                 v.vertex.y += y * _yScale;
    84.             }
    85.         }
    86.  
    87.  
    88.         inline half4 LightingStandardSpecularCustom(SurfaceOutputStandardSpecularCustom s, half3 viewDir, UnityGI gi )
    89.         {
    90.             #if !DIRECTIONAL
    91.             float3 lightAtten = gi.light.color;
    92.             #else
    93.             float3 lightAtten = lerp( _LightColor0.rgb, gi.light.color, _Grass_TransShadow );
    94.             #endif
    95.             half3 lightDir = gi.light.dir + s.Normal * _TransNormalDistortion;
    96.             half transVdotL = pow( saturate( dot( viewDir, -lightDir ) ), _TransScattering );
    97.             half3 translucency = lightAtten * (transVdotL * _TransDirect + gi.indirect.diffuse * _Grass_TransAmbient) * s.Translucency;
    98.             half4 c = half4( s.Albedo * translucency * _Grass_Translucency, 0 );
    99.  
    100.             SurfaceOutputStandardSpecular r;
    101.             r.Albedo = s.Albedo;
    102.             r.Normal = s.Normal;
    103.             r.Emission = s.Emission;
    104.             r.Specular = s.Specular;
    105.             r.Smoothness = s.Smoothness;
    106.             r.Occlusion = s.Occlusion;
    107.             r.Alpha = s.Alpha;
    108.             return LightingStandardSpecular (r, viewDir, gi) + c;
    109.         }
    110.  
    111.         inline void LightingStandardSpecularCustom_GI(SurfaceOutputStandardSpecularCustom s, UnityGIInput data, inout UnityGI gi )
    112.         {
    113.             UNITY_GI(gi, s, data);
    114.         }
    115.  
    116.         void surf( Input i , inout SurfaceOutputStandardSpecularCustom o )
    117.         {
    118.             float2 uv_MainTex = i.uv_texcoord * _MainTex_ST.xy + _MainTex_ST.zw;
    119.             float4 tex2DNode1 = tex2D( _MainTex, uv_MainTex );
    120.             o.Albedo = ( _Grass_Color * tex2DNode1 ).rgb;
    121.             o.Specular = Grass_Specular_Color.rgb;
    122.             o.Smoothness = _Grass_Smoothness;
    123.             o.Translucency = ( tex2DNode1 * ( ( _Grass_Translucency_Intensity * _Grass_Translucency_10_x_multiplier ) * _Grass_Translucency_Color ) ).rgb;
    124.             o.Alpha = 1;
    125.             clip( tex2DNode1.a - _Cutoff );
    126.         }
    127.  
    128.         ENDCG
    129.     }
    130.     Fallback "Diffuse"
    131. }
    Grass properties in this shader is global, so you can update settings using below way:
    Code (CSharp):
    1.         Shader.SetGlobalColor ("_Grass_Color", grassColor);
    2.  
    Shader has been created using Amplify Shader Editor

    If your terrain has grass in billboard mode, you must use below shader name:
    Code (CSharp):
    1. "Hidden/TerrainEngine/Details/BillboardWavingDoublePass"
     
    Last edited: Mar 27, 2021
  5. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,866
  6. DPunK

    DPunK

    Joined:
    May 15, 2019
    Posts:
    25
    Thanks for the detailed explanation! It helps me with something else I needed to do later in the project to control grass color based on seasons

    However at the moment still no change I make to the details shader seems to make a difference.

    I have terrain material that uses a copied FirstPass.shader I named Nature/Terrain/Diffuse2
    Inside it I have a reference to the copy of WavingDoublePass.shader that I named WavingDoublePass2:

    Code (CSharp):
    1. Dependency "Details0"         = "Hidden/TerrainEngine/Details/Vertexlit"
    2.     Dependency "Details1"         = "Hidden/TerrainEngine/Details/WavingDoublePass2"
    3.     Dependency "Details2"         = "Hidden/TerrainEngine/Details/BillboardWavingDoublePass"
    I do not use billboard for the grass.
    If I comment out the dependency lines or delete everything inside WavingDoublePass2 nothing happens like I would expect to see some problem. I tried to refresh and re-add the grass brush but still nothing.

    I will try this in the latest version of Unity and see if that helps

    Also when I'll manage to make any change affect it, what do you suppose makes the texture appear blurry?
     
  7. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,866
    You don't need to add terrain shaders into your project
    Only drag your WavingDoublePass shader into your project to have access to the grass shader

    Every shader with this name (Hidden/TerrainEngine/Details/BillboardWavingDoublePass) will be replaced with the terrain default grass shader

    Create your desired shader and rename it to the Hidden/TerrainEngine/Details/WavingDoublePass to use it as grass shader
     
  8. DPunK

    DPunK

    Joined:
    May 15, 2019
    Posts:
    25
    Hi UnityLighting, I still had no success.
    Nothing I do inside Hidden/TerrainEngine/Details/WavingDoublePass seems to affect the terrain texture.

    Do you maybe have a sample project you can share where this works for you?
     
  9. UnityLighting

    UnityLighting

    Joined:
    Mar 31, 2015
    Posts:
    3,866
    In the video, as you can see when i drag my own Hidden/TerrainEngine/Details/WavingDoublePass shader, the terrain details has been rendered using my detail shader