125 lines
3.2 KiB
GLSL
125 lines
3.2 KiB
GLSL
#version 430 core
|
|
|
|
struct FaceData {
|
|
uint pack; // All data in 4 bytes
|
|
};
|
|
|
|
layout(std430, binding = 0) buffer FaceBuffer {
|
|
uint faces[];
|
|
};
|
|
|
|
uniform mat4 view;
|
|
uniform mat4 projection;
|
|
uniform int chunkX;
|
|
uniform int chunkY;
|
|
|
|
out vec2 fragUV;
|
|
out float lighting;
|
|
out vec3 fragPos;
|
|
|
|
const float lightMult[6] = float[6](0.6, 0.6, 1.0, 0.5, 0.8, 0.8);
|
|
|
|
const vec3 offsets[6][6] = vec3[6][6](
|
|
vec3[6]( // +X
|
|
vec3(1, 0, 0),
|
|
vec3(1, 1, 1),
|
|
vec3(1, 0, 1),
|
|
vec3(1, 1, 1),
|
|
vec3(1, 0, 0),
|
|
vec3(1, 1, 0)
|
|
),
|
|
vec3[6]( // -X
|
|
vec3(0, 0, 1),
|
|
vec3(0, 1, 0),
|
|
vec3(0, 0, 0),
|
|
vec3(0, 1, 0),
|
|
vec3(0, 0, 1),
|
|
vec3(0, 1, 1)
|
|
),
|
|
vec3[6]( // +Y
|
|
vec3(0, 1, 0),
|
|
vec3(1, 1, 1),
|
|
vec3(1, 1, 0),
|
|
vec3(1, 1, 1),
|
|
vec3(0, 1, 0),
|
|
vec3(0, 1, 1)
|
|
),
|
|
vec3[6]( // -Y
|
|
vec3(0, 0, 1),
|
|
vec3(1, 0, 0),
|
|
vec3(1, 0, 1),
|
|
vec3(1, 0, 0),
|
|
vec3(0, 0, 1),
|
|
vec3(0, 0, 0)
|
|
),
|
|
vec3[6]( // +Z
|
|
vec3(1, 0, 1),
|
|
vec3(0, 1, 1),
|
|
vec3(0, 0, 1),
|
|
vec3(0, 1, 1),
|
|
vec3(1, 0, 1),
|
|
vec3(1, 1, 1)
|
|
),
|
|
vec3[6]( // -Z
|
|
vec3(0, 0, 0),
|
|
vec3(1, 1, 0),
|
|
vec3(1, 0, 0),
|
|
vec3(1, 1, 0),
|
|
vec3(0, 0, 0),
|
|
vec3(0, 1, 0)
|
|
)
|
|
);
|
|
|
|
const vec2 uvs[6] = vec2[6](vec2(0,0), vec2(1,1), vec2(1,0), vec2(1,1), vec2(0,0), vec2(0,1));
|
|
|
|
// Function to unpack the 4-byte face data
|
|
// Bit layout from C# (little-endian, but we read as uint):
|
|
// Bits 31-24: Y (8 bits) 0-255
|
|
// Bits 23-20: Z (4 bits) 0-15
|
|
// Bits 19-16: X (4 bits) 0-15
|
|
// Bits 15-10: Texture (6 bits) 0-63
|
|
// Bits 9-7: Facing (3 bits) 0-7
|
|
// Bits 6-3: Light (4 bits) 0-15
|
|
// Bits 2-0: unused (3 bits)
|
|
void unpackFace(uint pack, out uint x, out uint y, out uint z,
|
|
out uint facing, out uint texture, out uint lightLevel)
|
|
{
|
|
y = (pack >> 24) & 0xFFu; // Y: bits 24-31 (8 bits)
|
|
z = (pack >> 20) & 0x0Fu; // Z: bits 20-23 (4 bits)
|
|
x = (pack >> 16) & 0x0Fu; // X: bits 16-19 (4 bits)
|
|
texture = (pack >> 10) & 0x3Fu; // Texture: bits 10-15 (6 bits)
|
|
facing = (pack >> 7) & 0x07u; // Facing: bits 7-9 (3 bits)
|
|
lightLevel = (pack >> 3) & 0x0Fu;// Light: bits 3-6 (4 bits)
|
|
}
|
|
|
|
void main()
|
|
{
|
|
uint faceIndex = gl_VertexID / 6u;
|
|
uint vertIndex = gl_VertexID % 6u;
|
|
|
|
uint pack = faces[faceIndex];
|
|
|
|
uint x, y, z, facing, texture, lightLevel;
|
|
unpackFace(pack, x, y, z, facing, texture, lightLevel);
|
|
|
|
vec3 basePos = vec3(x, y, z) + vec3(chunkX, 0, chunkY) * 16.0;
|
|
|
|
vec4 worldPos = vec4(basePos + offsets[facing][vertIndex], 1.0);
|
|
float light = float(lightLevel) / 255.0; // use later for caves and stuff
|
|
|
|
// UV mapping
|
|
uint col = texture & 15u; // texture % 16
|
|
uint row = texture >> 4; // texture / 16
|
|
row = 15u - row; // invert row so 0 is top
|
|
|
|
// convert to float after int math, divide by 16
|
|
vec2 uv = uvs[vertIndex] * 0.0625;
|
|
uv.x += float(col) * 0.0625;
|
|
uv.y += float(row) * 0.0625;
|
|
|
|
fragUV = uv;
|
|
lighting = lightMult[facing];
|
|
|
|
fragPos = vec3(worldPos.x, worldPos.y, worldPos.z);
|
|
gl_Position = projection * view * worldPos;
|
|
} |