yabba/shaders/geometry.glsl
#version 150 core
///shaderType:geometry
layout(triangles) in;
layout(triangle_strip, max_vertices = 7) out;
in vec2 posVO[];
in vec2 texPosVO[];
out vec2 posGO;
out vec2 texPosGO;
uniform uvec2 modelType;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model;
const vec2 texPosTL = vec2(0.0, 0.0);
const vec2 texPosBL = vec2(0.0, 1.0);
const vec2 texPosTR = vec2(1.0, 0.0);
const vec2 texPosBR = vec2(1.0, 1.0);
void emit(in int i, in vec2 tp) {
gl_Position = gl_in[i].gl_Position;
posGO = posVO[i];
texPosGO = tp;
EmitVertex();
}
void emit(in int i) {
emit(i, texPosVO[i]);
}
void emit(in int i, in vec4 height) {
gl_Position = gl_in[i].gl_Position + height;
posGO = posVO[i];
texPosGO = texPosVO[i];
EmitVertex();
}
void emit(in int i, in int j, in vec4 height) {
gl_Position = ((gl_in[i].gl_Position + gl_in[j].gl_Position) / 2.0) + height;
posGO = (posVO[i] + posVO[j]) / 2.0;
texPosGO = (texPosVO[i] + texPosVO[j]) / 2.0;
EmitVertex();
}
void main() {
bool triangle_type = (texPosVO[0].y == 0.0); // tl,bl,tr (true) or bl,tr,br (false)
vec4 height = proj * view * model * vec4(
0.0,
0.0,
0.03 * float(((modelType.x - 1u) / 2u) + 1u),
0.0
); // no offset here
if (modelType.x == 0u) { // flat
emit(0);
emit(1);
emit(2);
} else if ((modelType.x & 1u) == 1u) { // odd -> spike
if (triangle_type) { // TODO: merge adjacent spikes by looking at the borders in modelType.y?
emit(1);
emit(0);
emit(1, 2, height); // randomized but stable half height?
emit(2);
} else {
emit(0);
emit(2);
emit(0, 1, height);
emit(1);
}
} else { // even -> box
// 6--4 2--0
// | /| /|\ |
// |/ | //| \|
// 51--3--4 4--3--15
// |\ |// | /|
// | \|/ |/ |
// 0--2 4--6
if (triangle_type) {
emit(1, texPosBR); // mirror tex coords at the edges for re-used vertices
emit(0, texPosTR);
emit(1, height);
emit(0, height);
emit(2, height);
emit(0, texPosBL);
emit(2, texPosBR);
} else {
emit(1, texPosTL);
emit(2, texPosBL);
emit(1, height);
emit(2, height);
emit(0, height);
emit(2, texPosTR);
emit(0, texPosTL);
}
}
EndPrimitive();
}