Search Unity

New to shaders,Custom Terrain Shader help

Discussion in 'Shaders' started by Zero_Xue, Feb 16, 2019.

  1. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    116
    Hi, am in the process of making a custom terrain generator and so far its all good, but i hit a bit of a wall when it comes to biome blending (changing from 1 material to the other smoothly), here the shader thus far

    Code (CSharp):
    1.     Shader "WorldBlendSharder"
    2.     {
    3.     Properties
    4.     {
    5.         _Metalness ("Metalness", Range(0, 1)) = 0.1
    6.         _Smoothness ("Smoothness", Range(0, 1)) = 0.1
    7.         _BlendSharpness ("Blend Sharpness", Range(0, 1)) = 0.75
    8.         [Space(30)]
    9.         _MainTex ("Ground Texture", 2D) = "white" {}
    10.         [Space(30)]
    11.             _Layer1 ("Layer 1", 2D) = "white" {}
    12.             _Layer1Height ("Layer 1 Height", Range(5, 64)) = 20
    13.         [Space(20)]
    14.             _Layer2 ("Layer 2", 2D) = "white" {}
    15.             _Layer2Height ("Layer 2 Height", Range(64, 128)) = 64
    16.         [Space(50)]
    17.             _CG ("Connector Ground", 2D) = "white" {}
    18.             _CL1 ("Connector Layer 1", 2D) = "white" {}
    19.             _CL2 ("Connector Layer 2", 2D) = "white" {}
    20.             _ConnectionBlend ("Connector Blend", Range(0, 1)) = 0
    21.             _MapScale("Map Scale", Float) = 1
    22.     }
    23.     SubShader
    24.     {
    25.         Tags { "RenderType" = "Opaque" }
    26.         LOD 200
    27.  
    28.         CGPROGRAM
    29.         #pragma target 4.0
    30.         #pragma surface surf Standard vertex:vert fullforwardshadows addshadow
    31.         #pragma shader_feature _NORMALMAP
    32.         #pragma shader_feature _OCCLUSIONMAP
    33.  
    34.         float _Metalness;
    35.         float _Smoothness;
    36.        
    37.         UNITY_DECLARE_TEX2D(_MainTex);
    38.         float _BlendSharpness;
    39.         UNITY_DECLARE_TEX2D(_Layer1);
    40.         float _Layer1Height;
    41.         UNITY_DECLARE_TEX2D(_Layer2);
    42.         float _Layer2Height;
    43.         UNITY_DECLARE_TEX2D(_CG);
    44.         UNITY_DECLARE_TEX2D(_CL1);
    45.         UNITY_DECLARE_TEX2D(_CL2);
    46.         float _ConnectionBlend;
    47.  
    48.         half _MapScale;
    49.         struct Input
    50.         {
    51.             float2 uv_MainTex;
    52.             float2 uv_Layer1;
    53.             float2 uv_Layer2;
    54.             float2 uv_CG;
    55.             float2 uv_CL1;
    56.             float2 uv_CL2;
    57.  
    58.             float3 worldPos;
    59.             float3 localCoord;
    60.             float3 localNormal;
    61.         };
    62.  
    63.         void vert(inout appdata_full v, out Input data)
    64.         {
    65.             UNITY_INITIALIZE_OUTPUT(Input, data);
    66.             data.localCoord = v.vertex.xyz;
    67.             data.localNormal = v.normal.xyz;
    68.         }
    69.  
    70.  
    71.         struct blendingData
    72.         {
    73.             float height;
    74.             float4 result;
    75.         };
    76.         blendingData BlendLayer(float4 layer, float layerHeight, blendingData bd)
    77.         {
    78.             bd.height = max(0, bd.height - layerHeight);
    79.             float t = min(1, bd.height * _BlendSharpness);
    80.             bd.result = lerp(bd.result, layer, t);
    81.             return bd;
    82.         }
    83.          blendingData BlendConnectionLayer(float4 layer, float layerHeight, blendingData bd)
    84.         {
    85.             bd.height = max(0, bd.height - layerHeight);
    86.             float t = min(1, bd.height * _ConnectionBlend);
    87.             bd.result = lerp(bd.result, layer, t);
    88.             return bd;
    89.         }
    90.  
    91.         void surf (Input i, inout SurfaceOutputStandard o)
    92.         {
    93.             blendingData bdata;
    94.                 bdata.height = i.worldPos.y - 0;
    95.                 bdata.result = UNITY_SAMPLE_TEX2D(_MainTex, i.uv_MainTex);
    96.                 float4 layer1 = UNITY_SAMPLE_TEX2D(_Layer1, i.uv_Layer1);
    97.                 float4 layer2 = UNITY_SAMPLE_TEX2D(_Layer2, i.uv_Layer2);
    98.                  float4 CGL = UNITY_SAMPLE_TEX2D(_CG, i.uv_CG);
    99.                 float4 CL1L = UNITY_SAMPLE_TEX2D(_CL1, i.uv_CL1);
    100.                 float4 CL2L = UNITY_SAMPLE_TEX2D(_CL2, i.uv_CL2);
    101.                 bdata = BlendConnectionLayer(CGL, 0, bdata);
    102.                 bdata = BlendLayer(layer1, _Layer1Height, bdata);
    103.                 bdata = BlendConnectionLayer(CL1L, _Layer1Height, bdata);
    104.                 bdata = BlendLayer(layer2, _Layer2Height, bdata);
    105.                 bdata = BlendConnectionLayer(CL2L, _Layer2Height, bdata);
    106.             o.Albedo = bdata.result;
    107.             o.Metallic = _Metalness;
    108.             o.Smoothness = _Smoothness;
    109.         }
    110.         ENDCG
    111.     }
    112.     FallBack "Diffuse"
    113. }
    The connector materials (_CG,_CL1, and CL2) are set to the textures of the next biome to create a blending transistion and this doesnt work since i pass the _ConnectionBlend the float value of the middle of the chunk, which i know is wrong.

    My guess would be that have to pass that function a float array with all the correct lerp values but i dont have a clue as to how to do that, so any help would be nice =)

    Sorry if that made no sence as, once again am not sure what am doing....
     
  2. Zero_Xue

    Zero_Xue

    Joined:
    Apr 18, 2012
    Posts:
    116
    Ok ive figured out how to pass a vector array to the shader but it doesnt work as i figured it might

    Ive changed the BlendConnectionLayer function to this
    Code (CSharp):
    1.          blendingData BlendConnectionLayer(float4 layer, float layerHeight, blendingData bd)
    2.         {
    3.             bd.height = max(0, bd.height.y - layerHeight);
    4.             float t = min(1, bd.height.y * _ConnectionBlend);
    5.             for (int i = 0; i < _blendpointsCount; i++)
    6.             {  
    7.                 if (_blendpoints[i].x == bd.height.x && _blendpoints[i].y == bd.height.z)
    8.                 {
    9.                 t = _blendpoints[i].z;
    10.                 }
    11.             }
    12.             bd.result = lerp(bd.result, layer, t);
    13.             return bd;
    14.         }
    15.  
    and am stocking the array as such from a script

    Code (CSharp):
    1.         List<Vector4> testvalues = new List<Vector4>();
    2.         for (int i = 0; i < 10; i++)
    3.         {
    4.             testvalues.Add(new Vector4(0,i,0.5f,0));
    5.         }
    6.         GetComponent<Renderer>().material.SetInt("_blendpointsCount", 10);
    7.         GetComponent<Renderer>().material.SetVectorArray("_blendpoints", testvalues);
    i was expecting it to change the values per UV or something like that so changing all UVs in 0,1 so and so forth to have a 0.5 blend but it just changes the entire material to have a 0.5 blend

    not sure what am doing, here are the results