summaryrefslogtreecommitdiff
path: root/gfx/gl/shaders/landmass.fs
blob: 55e3c244afe3918cfe7abaf7ac10ede84910259c (plain)
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
#version 330 core

include(`materialOut.glsl')
in vec3 FragPos;
in vec3 Normal;
flat in vec3 ColourBias;

uniform sampler2D texture0;
uniform ivec3 viewPoint;

const vec3 grass = vec3(.1, .4, .05);
const vec3 slope = vec3(.6, .6, .4);
const vec3 rock = vec3(.2, .2, .1);
const vec3 sand = vec3(.76, .7, .5);
const vec3 snow = vec3(.97, .97, .99);

const int beachline = 500;
const int snowline_low = 28000;
const int snowline_high = 30000;

const float slope_min = .99;
const float slope_mid = .95;
const float slope_max = .90;

vec3
mixBetween(vec3 colA, vec3 colB, float blend, float low, float high)
{
	return mix(colA, colB, (blend - low) / (high - low));
}

void
main()
{
	ivec3 position = ivec3(FragPos) + viewPoint;
	vec3 color = texture(texture0, vec2(position.xy % 10000) / 10000.0).rgb;

	int height = position.z;
	if (ColourBias.r >= 0) {
		color *= ColourBias;
	}
	else if (height < beachline) { // Sandy beach
		color *= sand;
	}
	else if (Normal.z < slope_max) { // Dark rocky face
		color *= rock;
	}
	else { // Colour by lesser slope
		if (Normal.z < slope_mid) {
			color *= mixBetween(rock, slope, Normal.z, slope_max, slope_mid);
		}
		else if (Normal.z < slope_min) {
			color *= mixBetween(slope, grass, Normal.z, slope_mid, slope_min);
		}
		else {
			color *= grass;
		}

		// Add a snow covering
		if (height > snowline_low) {
			vec3 tsnow = color * snow;
			if (height > snowline_high) {
				color = tsnow;
			}
			else {
				color = mixBetween(color, tsnow, height, snowline_low, snowline_high);
			}
		}
	}

	gPosition = ivec4(position, 1);
	gNormal = vec4(Normal, 1);
	gAlbedoSpec = vec4(color, 1);
}