Skip to content

Instantly share code, notes, and snippets.

@jcarcangiu
Created January 16, 2020 07:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcarcangiu/8e248e15ac623654bada1629a090f8ee to your computer and use it in GitHub Desktop.
Save jcarcangiu/8e248e15ac623654bada1629a090f8ee to your computer and use it in GitHub Desktop.
Terrain Painter Shader
Shader "Custom/ShowHeight"
{
Properties
{
_IsBlendingColor ("Blend Colours? (0 = No, 1 = Yes)", Range (0, 1)) = 1
_BlendSharpness ("Blend Sharpness", Range(0.01, 4)) = 0.75
_ColorWater ("Color Water", Color) = (1, 1, 1, 1)
_TextureWater ("Texture Water", 2D) = "white" {}
_BumpMapWater ("Normal Map Water", 2D) = "bump" {}
_HeightWater ("Height Water Level", Float) = 0
[Space(20)]
_ColorLowest ("Color Lowest", Color) = (1, 1, 1, 1)
_TextureLowest ("Texture Lowest", 2D) = "white" {}
_BumpMapLowest ("Normal Map Lowest", 2D) = "bump" {}
_HeightLowest ("Height Lowest", Float) = 5
[Space(20)]
_ColorLow ("Color Low", Color) = (1, 1, 1, 1)
_TextureLow ("Texture Low", 2D) = "white" {}
_BumpMapLow ("Normal Map Low", 2D) = "bump" {}
_HeightLow ("Height Low", Float) = 10
[Space(20)]
_ColorMid ("Color Mid", Color) = (1, 1, 1, 1)
_TextureMid ("Texture Mid", 2D) = "white" {}
_BumpMapMid ("Normal Map Mid", 2D) = "bump" {}
_HeightMid ("Height Mid", Float) = 15
[Space(20)]
_ColorHigh ("Color High", Color) = (1, 1, 1, 1)
_TextureHigh ("Texture High", 2D) = "white" {}
_BumpMapHigh ("Normal Map High", 2D) = "bump" {}
_HeightHigh ("Height High", Float) = 25
[Space(20)]
_ColorHighest ("Color Highest", Color) = (1, 1, 1, 1)
_TextureHighest ("Texture Highest", 2D) = "white" {}
_BumpMapHighest ("Normal Map Highest", 2D) = "bump" {}
_HeightHighest ("Height Highest", Float) = 30
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 5.0
#pragma debug
#include "UnityCG.cginc"
fixed4 _ColorWater;
fixed4 _ColorLowest;
fixed4 _ColorLow;
fixed4 _ColorMid;
fixed4 _ColorHigh;
fixed4 _ColorHighest;
UNITY_DECLARE_TEX2D(_TextureWater);
UNITY_DECLARE_TEX2D(_BumpMapWater);
float _HeightWater;
float _BlendSharpness;
UNITY_DECLARE_TEX2D(_TextureLowest);
UNITY_DECLARE_TEX2D(_BumpMapLowest);
float _HeightLowest;
UNITY_DECLARE_TEX2D(_TextureLow);
UNITY_DECLARE_TEX2D(_BumpMapLow);
float _HeightLow;
UNITY_DECLARE_TEX2D(_TextureMid);
UNITY_DECLARE_TEX2D(_BumpMapMid);
float _HeightMid;
UNITY_DECLARE_TEX2D(_TextureHigh);
UNITY_DECLARE_TEX2D(_BumpMapHigh);
float _HeightHigh;
UNITY_DECLARE_TEX2D(_TextureHighest);
UNITY_DECLARE_TEX2D(_BumpMapHighest);
float _HeightHighest;
int _IsBlendingColor;
struct Input
{
float2 uv_TextureWater;
float2 uv_BumpMapWater;
float2 uv_TextureLowest;
float2 uv_BumpMapLowest;
float2 uv_TextureLow;
float2 uv_BumpMapLow;
float2 uv_TextureMid;
float2 uv_BumpMapMid;
float2 uv_TextureHigh;
float2 uv_BumpMapHigh;
float2 uv_TextureHighest;
float2 uv_BumpMapHighest;
float3 worldPos;
};
struct blendingData
{
float height;
float4 result;
};
blendingData BlendLayer(float4 layer, float layerHeight, blendingData bd)
{
//Remove this layer's height from the total height so our next layer buids from it, but don't let it go below 0
bd.height = max(0, bd.height - layerHeight);
//Clamp our height to 1 or less and drive the lerp by it. If the height was already below 1, then our contribution will be less
//giving a smoother blend the closer it is to 0.
float t = min(1, bd.height * _BlendSharpness);
//Blend (lerp) from our previous layer result using the previous value
bd.result = lerp(bd.result, layer, t);
return bd; //Return our blendingData struct that contains the result and newly adjusted height, so we can use it again
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
blendingData bdata;
bdata.height = IN.worldPos.y - _HeightWater;
bdata.result = UNITY_SAMPLE_TEX2D(_TextureWater, IN.uv_TextureWater);
blendingData bdataNorm;
bdataNorm.height = IN.worldPos.y - _HeightWater;
bdataNorm.result = UNITY_SAMPLE_TEX2D(_BumpMapWater, IN.uv_BumpMapWater);
float4 lowest = UNITY_SAMPLE_TEX2D(_TextureLowest, IN.uv_TextureLowest);
float4 lowestNorm = UNITY_SAMPLE_TEX2D(_BumpMapLowest, IN.uv_BumpMapLowest);
float4 low = UNITY_SAMPLE_TEX2D(_TextureLow, IN.uv_TextureLow);
float4 lowNorm = UNITY_SAMPLE_TEX2D(_BumpMapLow, IN.uv_BumpMapLow);
float4 mid = UNITY_SAMPLE_TEX2D(_TextureMid, IN.uv_TextureMid);
float4 midNorm = UNITY_SAMPLE_TEX2D(_BumpMapMid, IN.uv_BumpMapMid);
float4 high = UNITY_SAMPLE_TEX2D(_TextureHigh, IN.uv_TextureHigh);
float4 highNorm = UNITY_SAMPLE_TEX2D(_BumpMapHigh, IN.uv_BumpMapHigh);
float4 highest = UNITY_SAMPLE_TEX2D(_TextureHighest, IN.uv_TextureHighest);
float4 highestNorm = UNITY_SAMPLE_TEX2D(_BumpMapHighest, IN.uv_BumpMapHighest);
bdata = BlendLayer(lowest, _HeightLowest, bdata);
bdataNorm = BlendLayer(lowestNorm, _HeightLowest, bdataNorm);
bdata = BlendLayer(low, _HeightLow, bdata);
bdataNorm = BlendLayer(lowNorm, _HeightLow, bdataNorm);
bdata = BlendLayer(mid, _HeightMid, bdata);
bdataNorm = BlendLayer(midNorm, _HeightMid, bdataNorm);
bdata = BlendLayer(high, _HeightHigh, bdata);
bdataNorm = BlendLayer(highNorm, _HeightHigh, bdataNorm);
bdata = BlendLayer(highest, _HeightHighest, bdata);
bdataNorm = BlendLayer(highestNorm, _HeightHighest, bdataNorm);
float h;
fixed4 tintColor;
if (IN.worldPos.y <= _HeightWater) { tintColor = _ColorWater; }
if (IN.worldPos.y > _HeightWater && IN.worldPos.y <= _HeightLowest)
{
if (_IsBlendingColor == 0) { h = (_HeightLowest - IN.worldPos.y) / (_HeightHighest - _HeightWater); } // Not Blending.
else if(_IsBlendingColor == 1) { h = (_HeightLowest - IN.worldPos.y) / (_HeightLowest - _HeightWater); } // Blending.
tintColor = lerp(_ColorLowest.rgba, _ColorWater.rgba, h);
}
if (IN.worldPos.y > _HeightLowest && IN.worldPos.y <= _HeightLow)
{
if (_IsBlendingColor == 0) { h = (_HeightLow - IN.worldPos.y) / (_HeightHighest - _HeightWater); }
else if (_IsBlendingColor == 1) { h = (_HeightLow - IN.worldPos.y) / (_HeightLow - _HeightLowest); }
tintColor = lerp(_ColorLow.rgba, _ColorLowest.rgba, h);
}
if (IN.worldPos.y > _HeightLow && IN.worldPos.y <= _HeightMid)
{
if (_IsBlendingColor == 0) { h = (_HeightMid - IN.worldPos.y) / (_HeightHighest - _HeightWater); }
else if (_IsBlendingColor == 1) { h = (_HeightMid - IN.worldPos.y) / (_HeightMid - _HeightLow); }
tintColor = lerp(_ColorMid.rgba, _ColorLow.rgba, h);
}
if (IN.worldPos.y > _HeightMid && IN.worldPos.y <= _HeightHigh)
{
if (_IsBlendingColor == 0) { h = (_HeightHigh - IN.worldPos.y) / (_HeightHighest - _HeightWater); }
else if (_IsBlendingColor == 1) { h = (_HeightHigh - IN.worldPos.y) / (_HeightHigh - _HeightMid); }
tintColor = lerp(_ColorHigh.rgba, _ColorMid.rgba, h);
}
if (IN.worldPos.y > _HeightHigh && IN.worldPos.y <= _HeightHighest)
{
if (_IsBlendingColor == 0) { h = (_HeightHighest - IN.worldPos.y) / (_HeightHighest - _HeightWater); }
else if (_IsBlendingColor == 1) { h = (_HeightHighest - IN.worldPos.y) / (_HeightHighest - _HeightHigh); }
tintColor = lerp(_ColorHighest.rgba, _ColorHigh.rgba, h);
}
if (IN.worldPos.y > _HeightHighest)
{
tintColor = _ColorHighest;
}
o.Albedo = bdata.result * tintColor.rgb;
o.Alpha = bdata.result * tintColor.a;
o.Normal = UnpackNormal(bdataNorm.result);
}
ENDCG
}
FallBack "Diffuse"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment