Search Unity

Splat map gradient effect

Discussion in 'Shaders' started by Raider00321, Jun 18, 2017.

  1. Raider00321

    Raider00321

    Joined:
    Feb 19, 2016
    Posts:
    5
    Hey there,

    I'm coming in relatively new to shaders have managed to piece together a simple triplaner shader from some examples, but need some assistance/advice on how to create a gradient effect from multiple different textures.

    I have has some success when an image draws over another, but I'm a bit lost on how i would make this work in a gradient sense.

    Here is how it works currently..

    upload_2017-6-18_23-32-20.png


    Heres the current code:
    Code (c#):
    1.  
    2. Shader "Custom/Terrain" {
    3.     Properties {
    4.         _Color ("Color", Color) = (1,1,1,1)
    5.         _MainTex ("Terrain Texture Array", 2DArray) = "white" {}
    6.         _Glossiness ("Smoothness", Range(0,1)) = 0.5
    7.         _Metallic ("Metallic", Range(0,1)) = 0.0
    8.     }
    9.     SubShader {
    10.         Tags { "RenderType"="Opaque" }
    11.         LOD 200
    12.        
    13.         CGPROGRAM
    14.         #pragma surface surf Standard fullforwardshadows vertex:vert
    15.         #pragma target 3.5
    16.         #include "UnityCG.cginc"
    17.         UNITY_DECLARE_TEX2DARRAY(_MainTex);
    18.  
    19.         half _Glossiness;
    20.         half _Metallic;
    21.         fixed4 _Color;
    22.         uniform sampler2D _Control;
    23.         struct Input {
    24.             float4 color : COLOR;
    25.             float3 worldPos;
    26.             float3 terrain;
    27.             float3 worldNormal;
    28.         };
    29.  
    30.         void vert (inout appdata_full v, out Input data) {
    31.             UNITY_INITIALIZE_OUTPUT(Input, data);
    32.             data.terrain = v.texcoord2.xyz;
    33.         }
    34.  
    35.         float4 GetTerrainColor (Input IN, int index) {
    36.             float mult = 1;
    37.             float3 blend = abs(IN.worldNormal);
    38.             blend /= dot(blend, 1.0);
    39.             float3 ux = float3(IN.worldPos.zy * mult, IN.terrain[index]);
    40.             float3 uy = float3(IN.worldPos.xz * mult, IN.terrain[index]);
    41.             float3 uz = float3(IN.worldPos.xy * mult, IN.terrain[index]);
    42.            
    43.             fixed4 cx = UNITY_SAMPLE_TEX2DARRAY(_MainTex, ux);
    44.             fixed4 cy = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uy);
    45.             fixed4 cz = UNITY_SAMPLE_TEX2DARRAY(_MainTex, uz);
    46.  
    47.             fixed4 blended = cx * blend.x + cy * blend.y + cz * blend.z;
    48.             fixed3 c = IN.color[index] * blend;
    49.  
    50.             return blended * IN.color[index];
    51.         }
    52.  
    53.         void surf (Input IN, inout SurfaceOutputStandard o) {
    54.             fixed4 splat_control = tex2D(_Control, IN.worldPos);
    55.              
    56.             fixed4 c = splat_control * GetTerrainColor(IN, 0);
    57.             c += splat_control * GetTerrainColor(IN, 1);
    58.             c += splat_control.a * GetTerrainColor(IN, 2);
    59.  
    60.             o.Albedo = c.rgb * _Color;
    61.             o.Metallic = _Metallic;
    62.             o.Smoothness = _Glossiness;
    63.             o.Alpha = c.a;
    64.         }
    65.         ENDCG
    66.     }
    67.     FallBack "Diffuse"
    68. }
    69.  
    The furthest i hope to extend this is to also include normal maps and specular maps for some context on where i am going on this, so if you see any red flags for this, an early warning would also be greatly appreciated.

    But ultimately, for this question in particular. Does anyone have a suggestion on how i can get a more gradient effect between the textures?
     
  2. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Did you check out the Unity's built in terrain shader source? It shows exactly how it does its blending.