245 lines
7.2 KiB
GLSL
245 lines
7.2 KiB
GLSL
#version 450
|
||
|
||
layout (points) in;
|
||
layout (triangle_strip, max_vertices = 4) out;
|
||
|
||
layout(location = 0) in highp uvec3 Geometry[];
|
||
|
||
layout(location = 0) out Fragment {
|
||
vec3 GeoPos; // Реальная позиция в мире
|
||
uint VoxMTL; // Материал вокселя
|
||
vec2 LUV;
|
||
} fragment;
|
||
|
||
layout(push_constant) uniform UniformBufferObject {
|
||
mat4 projview;
|
||
mat4 model;
|
||
} ubo;
|
||
|
||
// struct VoxelVertexPoint {
|
||
// uint32_t
|
||
// FX : 9, FY : 9, FZ : 9, // Позиция
|
||
// Place : 3, // Положение распространения xz, xy, zy, и обратные
|
||
// N1 : 1, // Не занято
|
||
// LS : 1, // Масштаб карты освещения (1м/16 или 1м)
|
||
// TX : 8, TY : 8, // Размер+1
|
||
// VoxMtl : 16, // Материал вокселя DefVoxelId_t
|
||
// LU : 14, LV : 14, // Позиция на карте освещения
|
||
// N2 : 2; // Не занято
|
||
// };
|
||
|
||
void main() {
|
||
vec4 baseVec = vec4(
|
||
float(Geometry[0].x & 0x1ff) / 16.f,
|
||
float((Geometry[0].x >> 9) & 0x1ff) / 16.f,
|
||
float((Geometry[0].x >> 18) & 0x1ff) / 16.f,
|
||
1
|
||
);
|
||
|
||
vec2 size = vec2(
|
||
float(Geometry[0].y & 0xff)+1,
|
||
float((Geometry[0].y >> 8) & 0xff)+1
|
||
);
|
||
|
||
uint voxMTL = ((Geometry[0].y >> 16) & 0xffff);
|
||
vec2 luv = vec2(float(Geometry[0].z & 0x3fff)+0.5f, float((Geometry[0].z >> 14) & 0x3fff)+0.5f);
|
||
|
||
// Стартовая вершина
|
||
vec4 tempVec = baseVec;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv;
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
|
||
int place = int(Geometry[0].x >> 27) & 0x3;
|
||
switch(place) {
|
||
case 0: // xz
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.z += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec.z += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
case 1: // xy
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
case 2: // zy
|
||
tempVec = baseVec;
|
||
tempVec.z += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.z += size.x;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
case 3: // xz inv
|
||
tempVec = baseVec;
|
||
tempVec.z += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec.z += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
case 4: // xy inv
|
||
tempVec = baseVec;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.x += size.x;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
case 5: // zy inv
|
||
tempVec = baseVec;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, 0);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.z += size.x;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(0, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
tempVec = baseVec;
|
||
tempVec.z += size.x;
|
||
tempVec.y += size.y;
|
||
tempVec = ubo.model*tempVec;
|
||
fragment.GeoPos = vec3(tempVec);
|
||
fragment.VoxMTL = voxMTL;
|
||
fragment.LUV = luv+vec2(size.x, size.y);
|
||
gl_Position = ubo.projview*tempVec;
|
||
EmitVertex();
|
||
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
EndPrimitive();
|
||
}
|