////////////////////////////////////////// // Complementary Shaders by EminGT // // With Euphoria Patches by SpacEagle17 // ////////////////////////////////////////// //Common// #include "/lib/common.glsl" //////////Shadowcomp 1//////////Shadowcomp 1//////////Shadowcomp 1////////// #ifdef SHADOWCOMP #define OPTIMIZATION_ACT_BEHIND_PLAYER #define OPTIMIZATION_ACT_HALF_RATE_SPREADING //#define OPTIMIZATION_ACT_SHARED_MEMORY layout (local_size_x = 8, local_size_y = 8, local_size_z = 8) in; #if COLORED_LIGHTING_INTERNAL == 128 const ivec3 workGroups = ivec3(16, 8, 16); #elif COLORED_LIGHTING_INTERNAL == 192 const ivec3 workGroups = ivec3(24, 12, 24); #elif COLORED_LIGHTING_INTERNAL == 256 const ivec3 workGroups = ivec3(32, 16, 32); #elif COLORED_LIGHTING_INTERNAL == 384 const ivec3 workGroups = ivec3(48, 24, 48); #elif COLORED_LIGHTING_INTERNAL == 512 const ivec3 workGroups = ivec3(64, 32, 64); #elif COLORED_LIGHTING_INTERNAL == 768 const ivec3 workGroups = ivec3(96, 32, 96); #elif COLORED_LIGHTING_INTERNAL == 1024 const ivec3 workGroups = ivec3(128, 32, 128); #endif #ifdef OPTIMIZATION_ACT_SHARED_MEMORY shared vec4 sharedLight[10][10][10]; #endif //Common Variables// writeonly uniform image3D floodfill_img; writeonly uniform image3D floodfill_img_copy; //Common Functions// vec4 GetLightSample(sampler3D lightSampler, ivec3 pos) { #ifdef OPTIMIZATION_ACT_SHARED_MEMORY ivec3 localPos = pos - ivec3(gl_WorkGroupID) * ivec3(8); // Convert global pos to local shared pos if (all(greaterThanEqual(localPos, ivec3(0))) && all(lessThan(localPos, ivec3(8)))) { return sharedLight[localPos.x][localPos.y][localPos.z]; } else { return texelFetch(lightSampler, pos, 0); // fallback to global fetch } #else return texelFetch(lightSampler, pos, 0); #endif } vec4 GetLightCalculated(sampler3D lightSampler, ivec3 pos, ivec3 voxelVolumeSize, uint voxel) { vec4 light_px = GetLightSample(lightSampler, clamp(pos + ivec3( 1, 0, 0), ivec3(0), voxelVolumeSize - 1)); vec4 light_py = GetLightSample(lightSampler, clamp(pos + ivec3( 0, 1, 0), ivec3(0), voxelVolumeSize - 1)); vec4 light_pz = GetLightSample(lightSampler, clamp(pos + ivec3( 0, 0, 1), ivec3(0), voxelVolumeSize - 1)); vec4 light_nx = GetLightSample(lightSampler, clamp(pos + ivec3(-1, 0, 0), ivec3(0), voxelVolumeSize - 1)); vec4 light_ny = GetLightSample(lightSampler, clamp(pos + ivec3( 0, -1, 0), ivec3(0), voxelVolumeSize - 1)); vec4 light_nz = GetLightSample(lightSampler, clamp(pos + ivec3( 0, 0, -1), ivec3(0), voxelVolumeSize - 1)); vec4 light = light_px + light_py + light_pz + light_nx + light_ny + light_nz; light /= 6.42; // Slightly higher than 6 to prevent the light from travelling too far if (voxel >= 200u) { vec3 tint = specialTintColor[min(voxel - 200u, specialTintColor.length() - 1u)]; light.rgb *= tint; light.a *= dot(tint, vec3(0.333333)); } return light; } //Includes// #include "/lib/voxelization/lightVoxelization.glsl" //Program// void main() { ivec3 pos = ivec3(gl_GlobalInvocationID); vec3 posM = vec3(pos) / vec3(voxelVolumeSize); vec3 posOffset = floor(previousCameraPosition) - floor(cameraPosition); ivec3 previousPos = pos - ivec3(posOffset); ivec3 localPos = ivec3(gl_LocalInvocationID); #ifdef OPTIMIZATION_ACT_SHARED_MEMORY vec4 prevLight = vec4(0.0); if (int(framemod2) == 0) prevLight = texelFetch(floodfill_sampler, previousPos, 0); else prevLight = texelFetch(floodfill_sampler_copy, previousPos, 0); sharedLight[localPos.x][localPos.y][localPos.z] = prevLight; barrier(); ivec3 alignedOffset = ivec3(posOffset) / 8 * 8; previousPos = pos - alignedOffset; #endif #ifdef OPTIMIZATION_ACT_BEHIND_PLAYER ivec3 absPosFromCenter = abs(pos - voxelVolumeSize / 2); if (absPosFromCenter.x + absPosFromCenter.y + absPosFromCenter.z > 16) { vec4 viewPos = gbufferProjectionInverse * vec4(0.0, 0.0, 1.0, 1.0); viewPos /= viewPos.w; vec3 nPlayerPos = normalize(mat3(gbufferModelViewInverse) * viewPos.xyz); if (dot(normalize(posM - 0.5), nPlayerPos) < 0.0) { #ifdef COLORED_LIGHT_FOG if (int(framemod2) == 0) { imageStore(floodfill_img_copy, pos, GetLightSample(floodfill_sampler, previousPos)); } else { imageStore(floodfill_img, pos, GetLightSample(floodfill_sampler_copy, previousPos)); } #endif return; } } #endif vec4 light = vec4(0.0); uint rawData = GetVoxelVolumeRaw(pos); uint voxel = rawData & 32767u; uint isColorwheelGeometry = (rawData - voxel) >> 15u; if (voxel == 1u) { // Solid Blocks light = vec4(0.0); } else if (voxel == 0u || voxel >= 200u) { // Air, Non-solids, Translucents if (int(framemod2) == 0) { #ifdef OPTIMIZATION_ACT_HALF_RATE_SPREADING if (posM.z > 0.5) light = GetLightSample(floodfill_sampler, previousPos); else #endif light = GetLightCalculated(floodfill_sampler, previousPos, voxelVolumeSize, voxel); } else { #ifdef OPTIMIZATION_ACT_HALF_RATE_SPREADING if (posM.z < 0.5) light = GetLightSample(floodfill_sampler_copy, previousPos); else #endif light = GetLightCalculated(floodfill_sampler_copy, previousPos, voxelVolumeSize, voxel); } } else { // Light Sources vec4 color = GetSpecialBlocklightColor(int(voxel)); if (isColorwheelGeometry == 1u) color.a = 1.0; light = max(light, vec4(pow2(color.rgb), color.a)); } light = clamp(light, vec4(0.0), vec4(1000.0)); // Prevents a random NaN from consuming the volume if (int(framemod2) == 0) { imageStore(floodfill_img_copy, pos, light); } else { imageStore(floodfill_img, pos, light); } } #endif