Files
2026-05-07 21:38:27 +03:00

119 lines
4.6 KiB
GLSL

#extension GL_ARB_gpu_shader5 : enable
#extension GL_ARB_shading_language_packing : enable
struct faceData {
vec3 glColor;
vec2 lightmap;
vec3 textureBounds;
};
#if defined SHADOW && defined VERTEX_SHADER
#define SSBO_QUALIFIER
#else
#define SSBO_QUALIFIER readonly
#endif
#if WORLD_SPACE_PLAYER_REF == 1
#include "/lib/voxelization/SSBOs/playerVerticesBuffer.glsl"
#endif
#include "/lib/voxelization/SSBOs/blockDataBuffer.glsl"
#include "/lib/voxelization/SSBOs/wsrLodBuffer.glsl"
#include "/lib/voxelization/SSBOs/wsrBuffer.glsl"
// Face index with no duplicates!
// Number of unique indecies 3abc + ab + bc + ca compared to 6abc,
// (where a, b, and c refer to sceneVoxelVolumeSize.x, y, and z)
int getFaceIndex(ivec3 voxelPos, vec3 normal) {
const int offsetY = (sceneVoxelVolumeSize.x + 1) * sceneVoxelVolumeSize.y * sceneVoxelVolumeSize.z;
const int offsetZ = (sceneVoxelVolumeSize.y + 1) * sceneVoxelVolumeSize.x * sceneVoxelVolumeSize.z + offsetY;
if (abs(normal.x) > 0.99)
return max(int(normal.x), 0) + voxelPos.x + voxelPos.y * (sceneVoxelVolumeSize.x + 1) +
voxelPos.z * (sceneVoxelVolumeSize.x + 1) * sceneVoxelVolumeSize.y;
else if (abs(normal.y) > 0.99)
return max(int(normal.y), 0) + voxelPos.y + voxelPos.x * (sceneVoxelVolumeSize.y + 1) +
voxelPos.z * (sceneVoxelVolumeSize.y + 1) * sceneVoxelVolumeSize.x + offsetY;
else
return max(int(normal.z), 0) + voxelPos.z + voxelPos.x * (sceneVoxelVolumeSize.z + 1) +
voxelPos.y * (sceneVoxelVolumeSize.z + 1) * sceneVoxelVolumeSize.x + offsetZ;
}
uvec4 packFaceData(faceData data) {
uvec3 uv = uvec3(clamp(data.textureBounds * 65536.0, 0.0, 65535.0));
uvec2 lightmap = uvec2(clamp(data.lightmap * 65536.0, 0.0, 65535.0));
return uvec4((uv.x << 16u) | uv.y, uv.z, packUnorm4x8(vec4(data.glColor, 0.0)), (lightmap.x << 16u) | lightmap.y);
}
faceData getFaceData(ivec3 voxelPos, vec3 normal) {
uvec4 data = blockDataSSBO.data[getFaceIndex(voxelPos, normal)];
return faceData(unpackUnorm4x8(data.z).xyz,
vec2(data.w >> 16u, data.w & 65535u) / 65536.0,
vec3(data.x >> 16u, data.x & 65535u, data.y) / 65536.0);
}
bool checkLodVoxelAt(ivec3 lodVoxelPos) {
uint voxelIndex = uint(lodVoxelPos.x + lodVoxelPos.y * sceneVoxelLodVolumeSize.x +
lodVoxelPos.z * sceneVoxelLodVolumeSize.x * sceneVoxelLodVolumeSize.y);
uint mask = 1u << (voxelIndex & 31u);
return (wsrLodSSBO.bitmasks[voxelIndex >> 5] & mask) != 0;
}
bool checkVoxelAt(ivec3 voxelPos) {
uint voxelIndex = uint(voxelPos.x + voxelPos.y * sceneVoxelVolumeSize.x +
voxelPos.z * sceneVoxelVolumeSize.x * sceneVoxelVolumeSize.y);
uint mask = 1u << (voxelIndex & 31u);
return (wsrSSBO.bitmasks[voxelIndex >> 5] & mask) != 0;
}
#if defined SHADOW && defined VERTEX_SHADER
void storeFaceData(ivec3 voxelPos, vec3 normal, vec2 origin, float textureRad, bool storeToAllFaces, bool storeToAllFacesExceptTop, vec3 playerPos) {
vec2 lmCoordM = lmCoord;
if (storeToAllFaces || storeToAllFacesExceptTop) {
vec3 playerPosPrevious = playerPos - previousCameraPosition + cameraPosition;
vec3 voxelPosPrevious = playerToPreviousSceneVoxel(playerPosPrevious);
faceData oldFaceData = getFaceData(ivec3(voxelPosPrevious), normal);
lmCoordM = mix(max(lmCoord, oldFaceData.lightmap), lmCoord, 0.01);
}
uvec4 newData = packFaceData(faceData(glColor.rgb, vec2(lmCoordM.x * 0.99 + 0.001, lmCoordM.y), vec3(origin, textureRad)));
if (storeToAllFaces || storeToAllFacesExceptTop) {
vec3 faceOffsets[6] = vec3[6](
vec3( 0.0, 1.0, 0.0),
vec3( 0.0, 0.0, 1.0),
vec3( 1.0, 0.0, 0.0),
vec3( 0.0, 0.0, -1.0),
vec3( 0.0, -1.0, 0.0),
vec3(-1.0, 0.0, 0.0)
);
int start = 0 + int(storeToAllFacesExceptTop);
for(int i = start; i < 6; i++) {
if (!checkVoxelAt(ivec3(voxelPos + faceOffsets[i])))
blockDataSSBO.data[getFaceIndex(voxelPos, faceOffsets[i])] = newData;
}
} else {
blockDataSSBO.data[getFaceIndex(voxelPos, normal)] = newData;
}
}
void updateWsrLodBitmask(ivec3 lodVoxelPos) {
uint voxelIndex = uint(lodVoxelPos.x + lodVoxelPos.y * sceneVoxelLodVolumeSize.x +
lodVoxelPos.z * sceneVoxelLodVolumeSize.x * sceneVoxelLodVolumeSize.y);
atomicOr(wsrLodSSBO.bitmasks[voxelIndex >> 5], 1u << (voxelIndex & 31u));
}
void updateWsrBitmask(ivec3 voxelPos) {
uint voxelIndex = uint(voxelPos.x + voxelPos.y * sceneVoxelVolumeSize.x +
voxelPos.z * sceneVoxelVolumeSize.x * sceneVoxelVolumeSize.y);
atomicOr(wsrSSBO.bitmasks[voxelIndex >> 5], 1u << (voxelIndex & 31u));
}
#endif