-
Notifications
You must be signed in to change notification settings - Fork 0
/
ProcedualLandscape.shader
151 lines (118 loc) · 5.66 KB
/
ProcedualLandscape.shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Shader "Custom/ProcedualLandscape"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Multiplier("Multiplier", Range(1, 100)) = 1.0
_Power("Power", Range(0.1, 2)) = 1.0
_Resolution1("Resolution 1", Range(2, 128)) = 4.0
_OctaveFactor1("Octave Factor 1", Range(0, 1)) = 0.5
_Resolution2("Resolution 2", Range(2, 128)) = 8.0
_OctaveFactor2("Octave Factor 2", Range(0, 1)) = 0.25
_Resolution3("Resolution 3", Range(2, 128)) = 32.0
_OctaveFactor3("Octave Factor 3", Range(0, 1)) = 0.125
_Resolution4("Resolution 4", Range(2, 128)) = 64.0
_OctaveFactor4("Octave Factor 4", Range(0, 1)) = 0.125
}
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 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
fixed4 _Color;
float _Multiplier;
float _Power;
float _Resolution1;
float _Resolution2;
float _Resolution3;
float _Resolution4;
float _OctaveFactor1;
float _OctaveFactor2;
float _OctaveFactor3;
float _OctaveFactor4;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
float random(float3 coord, int resolution) {
float s = sin(coord.z * resolution * resolution + coord.x * resolution + coord.y);
return abs(frac(s * 65364.2354768)); // range 0 -- 1
}
float quinticInterpolation(float t) { // input range 0 -- 1
return t * t * t * (t * (t * 6 - 15) + 10);
}
float getNoise(float2 uv, float res, float z) {
float3 global_coord = float3(uv.x, uv.y, z) * res;
float3 local_coord = float3(frac(global_coord.x), frac(global_coord.y), frac(global_coord.z));
int3 global_square_coord = int3(floor(global_coord.x), floor(global_coord.y), floor(global_coord.z));
float top_left_back = random(global_square_coord + float3(0, 0, 0), res);
float top_right_back = random(global_square_coord + float3(1, 0, 0), res);
float bot_left_back = random(global_square_coord + float3(0, 1, 0), res);
float bot_right_back = random(global_square_coord + float3(1, 1, 0), res);
float top_left_forward = random(global_square_coord + float3(0, 0, 1), res);
float top_right_forward = random(global_square_coord + float3(1, 0, 1), res);
float bot_left_forward = random(global_square_coord + float3(0, 1, 1), res);
float bot_right_forward = random(global_square_coord + float3(1, 1, 1), res);
local_coord = float3(quinticInterpolation(local_coord.x), quinticInterpolation(local_coord.y), local_coord.z);
float txb = lerp(top_left_back, top_right_back, local_coord.x);
float bxb = lerp(bot_left_back, bot_right_back, local_coord.x);
float txf = lerp(top_left_forward, top_right_forward, local_coord.x);
float bxf = lerp(bot_left_forward, bot_right_forward, local_coord.x);
float tbb = lerp(txb, bxb, local_coord.y);
float tbf = lerp(txf, bxf, local_coord.y);
float tb = lerp(tbb, tbf, local_coord.z);
return tb;
}
float3 paint(float x) {
if (x < 0.40) {
return float3(0, 0, 40) / 255;
}
if (x < 0.60) {
return float3(0, 0, 70) / 255;
}
if (x < 0.65) {
return float3(255, 224, 66) / 255;
}
if (x < 0.75) {
return float3(148, 255, 66) / 255;
}
if (x < 0.88) {
return float3(7, 130, 39) / 255;
}
return float3(250, 250, 250) / 255;
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
float global_multiplier = _Multiplier;
float res1 = _Resolution1 * global_multiplier;
float res2 = _Resolution2 * global_multiplier;
float res3 = _Resolution3 * global_multiplier;
float res4 = _Resolution4 * global_multiplier;
float2 uv = IN.uv_MainTex;
// Albedo comes from a texture tinted by color
fixed4 c = tex2D(_MainTex, uv) * _Color;
float time_factor = _Time[0] / global_multiplier;
float summary_octave_factor = _OctaveFactor1 + _OctaveFactor2 + _OctaveFactor3 + _OctaveFactor4;
float4 color_out = _OctaveFactor1 * getNoise(uv, res1, time_factor) / summary_octave_factor;
color_out += _OctaveFactor2 * getNoise(uv, res2, time_factor) / summary_octave_factor;
color_out += _OctaveFactor3 * getNoise(uv, res3, time_factor) / summary_octave_factor;
color_out += _OctaveFactor4 * getNoise(uv, res4, time_factor) / summary_octave_factor;
o.Albedo = paint(pow(color_out, _Power));
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}