#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