Guest User

stepped terrain gradient shader

a guest
May 18th, 2024
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Custom/SteppedTerrainGradient" {
  2.     Properties {
  3.         _MainTex ("Base (RGB)", 2D) = "white" {}
  4.         _GradientTex ("Gradient (RGB)", 2D) = "white" {}
  5.         _StepSize ("Height Step Size", Float) = 1.0
  6.         _MaxHeight ("Maximum Terrain Height", Float) = 100.0
  7.         _SpecularColor ("Specular Color", Color) = (1,1,1,1)
  8.         _SpecularExponent ("Specular Exponent", Float) = 16.0
  9.         _TintColor ("Tint Color", Color) = (1, 1, 1, 1)
  10.         _SteepColor ("Steep Color", Color) = (1, 0, 0, 1)
  11.         _SteepThreshold ("Steep Threshold", Range(0, 1)) = 0.7
  12.     }
  13.    
  14.     SubShader {
  15.         Tags { "RenderType"="Opaque" "TerrainCompatible"="true" }
  16.         LOD 200
  17.        
  18.         Pass {
  19.             CGPROGRAM
  20.             #pragma vertex vert
  21.             #pragma fragment frag
  22.             #include "UnityCG.cginc"
  23.             #include "Lighting.cginc"
  24.            
  25.             struct appdata_t {
  26.                 float4 vertex : POSITION;
  27.                 float3 normal : NORMAL;
  28.                 float2 uv : TEXCOORD0;
  29.             };
  30.            
  31.             struct v2f {
  32.                 float2 uv : TEXCOORD0;
  33.                 float4 vertex : SV_POSITION;
  34.                 float3 worldPos : TEXCOORD1;
  35.                 float3 worldNormal : TEXCOORD2;
  36.                 float3 displacedWorldPos : TEXCOORD3;
  37.             };
  38.            
  39.             sampler2D _MainTex;
  40.             sampler2D _GradientTex;
  41.             float _StepSize;
  42.             float _MaxHeight;
  43.             fixed4 _SpecularColor;
  44.             float _SpecularExponent;
  45.             fixed4 _TintColor;
  46.             fixed4 _SteepColor;
  47.             float _SteepThreshold;
  48.            
  49.             v2f vert (appdata_t v) {
  50.                 v2f o;
  51.                
  52.                 // Modify the height to create a stepped effect
  53.                 float quantizedHeight = floor(v.vertex.y / _StepSize) * _StepSize;
  54.                
  55.                 // Apply the modified height to the vertex position
  56.                 float4 modifiedVertex = v.vertex;
  57.                 modifiedVertex.y = quantizedHeight;
  58.                
  59.                 o.vertex = UnityObjectToClipPos(modifiedVertex);
  60.                 o.uv = v.uv;
  61.                 o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  62.                 o.displacedWorldPos = mul(unity_ObjectToWorld, modifiedVertex).xyz;
  63.                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
  64.                
  65.                 return o;
  66.             }
  67.            
  68.             fixed4 frag (v2f i) : SV_Target {
  69.                 // Quantize height for coloring purposes
  70.                 float quantizedHeight = floor(i.displacedWorldPos.y / _StepSize) * _StepSize;
  71.                
  72.                 // Normalize quantized height to a 0-1 range based on MaxHeight
  73.                 float normalizedHeight = quantizedHeight / _MaxHeight;
  74.                
  75.                 // Sample the gradient texture
  76.                 fixed4 gradientColor = tex2D(_GradientTex, float2(normalizedHeight, 0.5));
  77.                
  78.                 // Combine with base texture
  79.                 fixed4 baseColor = tex2D(_MainTex, i.uv);
  80.                
  81.                 // Apply lighting
  82.                 fixed3 worldNormal = normalize(i.worldNormal);
  83.                 fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  84.                 fixed3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos);
  85.                
  86.                 // Calculate the lighting using the Lambertian reflection model
  87.                 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * baseColor.rgb;
  88.                 fixed3 diffuse = _LightColor0.rgb * baseColor.rgb * max(0, dot(worldNormal, lightDir));
  89.                
  90.                 // Specular lighting
  91.                 fixed3 halfDir = normalize(lightDir + viewDir);
  92.                 float specAngle = max(0, dot(halfDir, worldNormal));
  93.                 float specular = pow(specAngle, _SpecularExponent);
  94.                
  95.                 fixed3 finalColor = ambient + diffuse + _SpecularColor.rgb * specular;
  96.                
  97.                 // Apply tint color
  98.                 finalColor *= _TintColor.rgb;
  99.                
  100.                 // Calculate the displaced world normal using derivatives in the fragment shader
  101.                 float3 pos_dx = ddx(i.displacedWorldPos);
  102.                 float3 pos_dy = ddy(i.displacedWorldPos);
  103.                 float3 displacedWorldNormal = normalize(cross(pos_dy, pos_dx));
  104.                
  105.                 // Check if the surface is steep or vertical based on the displaced normal
  106.                 float steepness = abs(dot(displacedWorldNormal, float3(0, 1, 0)));
  107.                 if (steepness < _SteepThreshold) {
  108.                     finalColor = _SteepColor.rgb;
  109.                     //finalColor = lerp(finalColor, _SteepColor.rgb, _SteepColor.a);
  110.                 }
  111.                
  112.                 return fixed4(finalColor * gradientColor.rgb, baseColor.a);
  113.             }
  114.             ENDCG
  115.         }
  116.     }
  117.     FallBack "Diffuse"
  118. }
  119.  
Advertisement
Add Comment
Please, Sign In to add comment