aboutsummaryrefslogtreecommitdiff
path: root/src/shader/code/vertex.glsl
blob: 10abf0c9bda96eba6e63633a05cd75c9b2f719bf (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
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
static const std::string VERTEX_SHADER_CODE = R"(
#version 430

layout (location=0) in vec3 VertexPosition;

out VS_OUT {
	vec3 color;
} vs_out;

uniform uint nX;
uniform uint nY;

uniform bool show_quality;
uniform bool show_curl;
uniform int  palette_factor;

/// Vector utilities

float sq(float x) {
	return x*x;
}

float norm(vec2 v) {
	return sqrt(sq(v.x)+sq(v.y));
}

/// Array indexing

vec2 fluidVertexAtIndex(uint i) {
	const float y = floor(float(i) / float(nX));
	return vec2(
		i - nX*y,
		y
	);
}

/// Material number meaning

bool isInactive(int material) {
	return material == 0;
}

bool isWallFrontier(int material) {
	return material == 2 || material == 3;
}

/// Data restriction

float restrictedQuality(float quality) {
	if ( quality < 0.0 ) {
		return 0.0;
	} else {
		return min(1.0, quality / palette_factor);
	}
}

float restrictedCurl(float curl) {
	if ( abs(curl) < 1.0 ) {
		return 0.5;
	} else {
		return 0.5 + 0.5*min(1.0, curl / sq(palette_factor));
	}
}

/// Color palettes

vec3 greenYellowRedPalette(float x) {
	if ( x < 0.5 ) {
		return mix(
			vec3(0.0, 1.0, 0.0),
			vec3(1.0, 1.0, 0.0),
			2*x
		);
	} else {
		return mix(
			vec3(1.0, 1.0, 0.0),
			vec3(1.0, 0.0, 0.0),
			2*(x - 0.5)
		);
	}
}

vec3 blueBlackRedPalette(float x) {
	if ( x < 0.5 ) {
		return mix(
			vec3(0.0, 0.0, 1.0),
			vec3(0.0, 0.0, 0.0),
			2*x
		);
	} else {
		return mix(
			vec3(0.0, 0.0, 0.0),
			vec3(1.0, 0.0, 0.0),
			2*(x - 0.5)
		);
	}
}

vec3 blackGoldPalette(float x) {
	return mix(
		vec3(0.0, 0.0, 0.0),
		vec3(0.5, 0.35, 0.05),
		x
	);
}

vec3 blueRedPalette(float x) {
	return mix(
		vec3(0.0, 0.0, 1.0),
		vec3(1.0, 0.0, 0.0),
		x
	);
}

/// Actual vertex shader

void main() {
	const vec2 idx = fluidVertexAtIndex(gl_VertexID);

	gl_Position  = vec4(
		idx.x - nX/2,
		idx.y - nY/2,
		0.,
		1.
	);

	const int material = int(round(VertexPosition.z));

	if ( isInactive(material) ) {
		vs_out.color = vec3(0.5, 0.5, 0.5);
	} else if ( isWallFrontier(material) ) {
		vs_out.color = vec3(0.0, 0.0, 0.0);
	} else {
		if ( show_quality ) {
			vs_out.color = greenYellowRedPalette(
				restrictedQuality(VertexPosition.y)
			);
		} else if ( show_curl ) {
			vs_out.color = blueBlackRedPalette(
				restrictedCurl(VertexPosition.x)
			);
		} else {
			vs_out.color = blueRedPalette(
				norm(VertexPosition.xy) / palette_factor
			);
		}
	}
}
)";