Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Shader "Custom/SteppedTerrainGradient" {
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
- _GradientTex ("Gradient (RGB)", 2D) = "white" {}
- _StepSize ("Height Step Size", Float) = 1.0
- _MaxHeight ("Maximum Terrain Height", Float) = 100.0
- _SpecularColor ("Specular Color", Color) = (1,1,1,1)
- _SpecularExponent ("Specular Exponent", Float) = 16.0
- _TintColor ("Tint Color", Color) = (1, 1, 1, 1)
- _SteepColor ("Steep Color", Color) = (1, 0, 0, 1)
- _SteepThreshold ("Steep Threshold", Range(0, 1)) = 0.7
- }
- SubShader {
- Tags { "RenderType"="Opaque" "TerrainCompatible"="true" }
- LOD 200
- Pass {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- #include "Lighting.cginc"
- struct appdata_t {
- float4 vertex : POSITION;
- float3 normal : NORMAL;
- float2 uv : TEXCOORD0;
- };
- struct v2f {
- float2 uv : TEXCOORD0;
- float4 vertex : SV_POSITION;
- float3 worldPos : TEXCOORD1;
- float3 worldNormal : TEXCOORD2;
- float3 displacedWorldPos : TEXCOORD3;
- };
- sampler2D _MainTex;
- sampler2D _GradientTex;
- float _StepSize;
- float _MaxHeight;
- fixed4 _SpecularColor;
- float _SpecularExponent;
- fixed4 _TintColor;
- fixed4 _SteepColor;
- float _SteepThreshold;
- v2f vert (appdata_t v) {
- v2f o;
- // Modify the height to create a stepped effect
- float quantizedHeight = floor(v.vertex.y / _StepSize) * _StepSize;
- // Apply the modified height to the vertex position
- float4 modifiedVertex = v.vertex;
- modifiedVertex.y = quantizedHeight;
- o.vertex = UnityObjectToClipPos(modifiedVertex);
- o.uv = v.uv;
- o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
- o.displacedWorldPos = mul(unity_ObjectToWorld, modifiedVertex).xyz;
- o.worldNormal = UnityObjectToWorldNormal(v.normal);
- return o;
- }
- fixed4 frag (v2f i) : SV_Target {
- // Quantize height for coloring purposes
- float quantizedHeight = floor(i.displacedWorldPos.y / _StepSize) * _StepSize;
- // Normalize quantized height to a 0-1 range based on MaxHeight
- float normalizedHeight = quantizedHeight / _MaxHeight;
- // Sample the gradient texture
- fixed4 gradientColor = tex2D(_GradientTex, float2(normalizedHeight, 0.5));
- // Combine with base texture
- fixed4 baseColor = tex2D(_MainTex, i.uv);
- // Apply lighting
- fixed3 worldNormal = normalize(i.worldNormal);
- fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
- fixed3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos);
- // Calculate the lighting using the Lambertian reflection model
- fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * baseColor.rgb;
- fixed3 diffuse = _LightColor0.rgb * baseColor.rgb * max(0, dot(worldNormal, lightDir));
- // Specular lighting
- fixed3 halfDir = normalize(lightDir + viewDir);
- float specAngle = max(0, dot(halfDir, worldNormal));
- float specular = pow(specAngle, _SpecularExponent);
- fixed3 finalColor = ambient + diffuse + _SpecularColor.rgb * specular;
- // Apply tint color
- finalColor *= _TintColor.rgb;
- // Calculate the displaced world normal using derivatives in the fragment shader
- float3 pos_dx = ddx(i.displacedWorldPos);
- float3 pos_dy = ddy(i.displacedWorldPos);
- float3 displacedWorldNormal = normalize(cross(pos_dy, pos_dx));
- // Check if the surface is steep or vertical based on the displaced normal
- float steepness = abs(dot(displacedWorldNormal, float3(0, 1, 0)));
- if (steepness < _SteepThreshold) {
- finalColor = _SteepColor.rgb;
- //finalColor = lerp(finalColor, _SteepColor.rgb, _SteepColor.a);
- }
- return fixed4(finalColor * gradientColor.rgb, baseColor.a);
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
Advertisement
Add Comment
Please, Sign In to add comment