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

232 lines
10 KiB
GLSL

#if COLORED_LIGHTING < 512
const ivec3 sceneVoxelVolumeSize = ivec3(COLORED_LIGHTING_INTERNAL, 64, COLORED_LIGHTING_INTERNAL);
#else
const ivec3 sceneVoxelVolumeSize = ivec3(512, 64, 512);
#endif
const ivec3 sceneVoxelLodVolumeSize = sceneVoxelVolumeSize / 4;
vec3 playerToSceneVoxel(vec3 playerPos) {
return playerPos + cameraPositionBestFract + 0.5 * vec3(sceneVoxelVolumeSize);
}
vec3 playerToPreviousSceneVoxel(vec3 previousPlayerPos) {
return previousPlayerPos + previousCameraPositionBestFract + 0.5 * vec3(sceneVoxelVolumeSize);
}
bool CheckInsideSceneVoxelVolume(vec3 voxelPos) {
#ifndef SHADOW
voxelPos -= 0.5 * sceneVoxelVolumeSize;
voxelPos += sign(voxelPos) * 0.95;
voxelPos += 0.5 * sceneVoxelVolumeSize;
#endif
voxelPos /= vec3(sceneVoxelVolumeSize);
return clamp01(voxelPos) == voxelPos;
}
#include "/lib/voxelization/reflectionVoxelData.glsl"
#if defined SHADOW && defined VERTEX_SHADER
void UpdateSceneVoxelMap(int mat, vec3 normal, vec3 position) {
ivec3 eligibleStages = ivec3(
MC_RENDER_STAGE_TERRAIN_SOLID,
MC_RENDER_STAGE_TERRAIN_CUTOUT,
MC_RENDER_STAGE_TERRAIN_CUTOUT_MIPPED
);
if (!any(equal(ivec3(renderStage), eligibleStages))) return;
vec3 viewPos = mat3(gl_ModelViewMatrix) * (gl_Vertex.xyz + at_midBlock.xyz / 64.0) + gl_ModelViewMatrix[3].xyz;
vec3 scenePos = mat3(shadowModelViewInverse) * viewPos + shadowModelViewInverse[3].xyz;
vec3 voxelPos = playerToSceneVoxel(scenePos);
if (CheckInsideSceneVoxelVolume(voxelPos)) {
bool doSolidBlockCheck = true;
bool storeToAllFaces = false;
bool storeToAllFacesExceptTop = false;
uint matM = mat > 10 ? uint(mat) : 1u;
vec2 textureRad = abs(texCoord - mc_midTexCoord.xy);
vec2 origin = mc_midTexCoord.xy - textureRad;
if (mat == 10132) { // Grass Block Regular
if (texture2D(tex, mc_midTexCoord.xy).a < 0.5) return; // Grass Block Side Overlay
}
if (abs(mat - 10009) <= 2) { // Leaves (10007, 10009, 10011)
doSolidBlockCheck = false;
}
if (mat == 10129 // Farmland:Dry
|| mat == 10137 // Farmland:Wet
|| mat == 10493 // Dirt Path
) {
doSolidBlockCheck = false;
textureRad *= 0.5;
origin.y += 2.0 / atlasSize.y;
}
if (abs(mat - 10069) <= 1 // Lava (10068, 10070)
) {
if (abs(dot(textureRad, vec2(atlasSize.x, -atlasSize.y))) < 6.5)
storeToAllFaces = true;
else return;
}
// Half blocks that we want to display as full blocks in reflections
if (mat == 10035 // Stone Bricks, Mossy Stone Bricks
|| abs(mat - 10095) <= 12 && mat % 4 == 3 // Stone, Smooth Stone, Granite, Diorite, Andesite, Bricks, Mud Bricks
|| mat == 10155 // Cobblestone, Mossy Cobblestone
|| abs(mat - 10191) <= 32 && mat % 8 == 7 // Oak, Spruce, Birch, Jungle, Acacia, DarkOak, Mangrove, Crimson, Warped
|| mat == 10111 // Cobbled Deepslate
|| mat == 10115 // Polished Deepslate, Deepslate Bricks, Deepslate Tiles
|| mat == 10243 // Sandstone
|| mat == 10247 // Red Sandstone
|| mat == 10295 // Copper
|| mat == 10367 // Quartz
|| mat == 10379 // Purpur
|| mat == 10381 // Powder Snow
|| mat == 10419 // Nether Bricks
|| mat == 10423 // Red Nether Bricks
|| mat == 10431 // End Stone Bricks
|| mat == 10443 // Prismarine, Prismarine Bricks
|| mat == 10447 // Dark Prismarine
|| mat == 10483 // Blackstone
|| mat == 10715 // Tuff
|| mat == 10759 // Bamboo, Bamboo Mosaic
|| mat == 10763 // Cherry
|| mat == 10931 // Pale Oak
) {
if (textureRad.y < 5.0 / atlasSize.y) {
// Discarding if textureRad is too small to fix (somewhat rare) flickering on stairs
if (textureRad.x < 5.0 / atlasSize.x) return;
// Half textureRad for stairs and slabs to not overshoot their textures
textureRad *= 0.5;
// P.S: Don't ask me how any of these checks make sense because I have absolutely no idea either
}
doSolidBlockCheck = false;
if (normal.y < 0.5) storeToAllFacesExceptTop = true; // Not overriding top face or else carpets look broken on top of slabs
}
if (mat == 10669 || mat == 10843|| mat == 10845 || mat == 10925 || mat == 10953) { // Wool Carpets, Moss Carpet, Snow Layers < 8
if (normal.y > 0.5) {
voxelPos.y -= 1.0;
doSolidBlockCheck = false;
} else return;
}
if (mat == 10072 // Fire
|| mat == 10076 // Soul Fire
|| mat == 10332 // Amethyst Clusters
|| mat == 10544 // Glow Lichen
) {
doSolidBlockCheck = false;
storeToAllFaces = true;
}
if (mat == 10652 || mat == 10656) { // Campfire:Lit, Soul Campfire:Lit
if (abs(abs(normal.x) - 0.5) < 0.25) {
doSolidBlockCheck = false;
storeToAllFaces = true;
} else return;
}
// Blocks to remove from reflections
if (mat == 10056 // Lava Cauldron
|| mat == 10404 // Sea Pickle
|| mat == 10496 // Torch
|| mat == 10500 // End Rod
|| mat == 10508 // Chorus Flower:Alive
|| mat == 10512 // Chorus Flower:Dead
|| mat == 10528 // Soul Torch
|| mat == 10556 // End Portal Frame:Active
|| mat == 10572 // Dragon Egg
|| mat == 10604 || mat == 10605 // Redstone Torch
|| mat == 10632 // Cave Vines
|| mat == 10644 // Powered Repeater, Powered Comparator
|| mat == 10776 // Crimson Fungus, Warped Fungus
|| mat == 10780 // Potted Crimson Fungus, Potted Warped Fungus
|| mat == 10836 // Brewing Stand
|| mat == 10884 // Weeping Vines
|| mat == 10972 // Firefly Bush
|| mat == 10976 // Open Eyeblossom
|| mat == 10980 // Potted Open Eyeblossom
|| abs(mat - 10562) <= 2 // Lantern & Soul Lantern
|| abs(mat - 10599) <= 3 // Redstone Wire
|| abs(mat - 10701) <= 3 // Non-Solid Sculk Stuff
|| abs(mat - 10786) <= 2 // Calibrated Sculk Sensor
|| abs(mat - 10911) <= 11 // Lit Candles & Candle Cakes
|| mat == 10984 // Copper Torch
|| mat == 10988 // Copper Lantern
) {
return;
}
if (doSolidBlockCheck) {
if (
mat % 2 == 1 // Non-solids
|| abs(mat - 5000) <= 4999 // Block entities that we treat as non-solid
)
return;
}
imageStore(wsr_img, ivec3(voxelPos), uvec4(matM, 0u, 0u, 0u));
storeFaceData(ivec3(voxelPos), round(normal), origin, textureRad.x, storeToAllFaces, storeToAllFacesExceptTop, scenePos);
updateWsrBitmask(ivec3(voxelPos));
updateWsrLodBitmask(ivec3(voxelPos / 4.0));
}
}
#if WORLD_SPACE_PLAYER_REF == 1
uniform writeonly image2D playerAtlas_img;
#define updateAABB(aabb_min, aabb_max, pos) \
atomicMin(aabb_min.x, pos.x); \
atomicMin(aabb_min.y, pos.y); \
atomicMin(aabb_min.z, pos.z); \
atomicMax(aabb_max.x, pos.x); \
atomicMax(aabb_max.y, pos.y); \
atomicMax(aabb_max.z, pos.z);
void UpdatePlayerVertexList(vec3 position) {
if (entityId == 50017 && textureSize(tex, 0) == ivec2(64) && gl_VertexID < 288) { // Current Player
// The atlas takes 4 frames to fully generate, reload every 600 frames
if (framemod600 > 5 && framemod600 <= 9 && gl_VertexID < 256) {
int i = gl_VertexID * 4 + int(framemod4) * 1024;
for (int j = 0; j < 4; j++) {
ivec2 coord = ivec2((i + j) % 64, (i + j) / 64);
imageStore(playerAtlas_img, coord, texelFetch(tex, coord, 0));
}
}
ivec3 aabbPos = ivec3(position * 1000.0);
if (gl_VertexID < 48) { // Head
updateAABB(playerVerticesSSBO.bounds.headMin, playerVerticesSSBO.bounds.headMax, aabbPos);
} else if (gl_VertexID < 96) { // Right Hand
updateAABB(playerVerticesSSBO.bounds.rightHandMin, playerVerticesSSBO.bounds.rightHandMax, aabbPos);
} else if (gl_VertexID < 144) { // Left Leg
updateAABB(playerVerticesSSBO.bounds.leftLegMin, playerVerticesSSBO.bounds.leftLegMax, aabbPos);
} else if (gl_VertexID < 192) { // Left Hand
updateAABB(playerVerticesSSBO.bounds.leftHandMin, playerVerticesSSBO.bounds.leftHandMax, aabbPos);
} else if (gl_VertexID < 240) { // Right leg
updateAABB(playerVerticesSSBO.bounds.rightLegMin, playerVerticesSSBO.bounds.rightLegMax, aabbPos);
} else { // Torso
updateAABB(playerVerticesSSBO.bounds.torsoMin, playerVerticesSSBO.bounds.torsoMax, aabbPos);
}
if (gl_VertexID % 4 != 3) {
int ssboIndex = gl_VertexID - gl_VertexID / 4;
playerVerticesSSBO.vertexPositions[ssboIndex] = position;
playerVerticesSSBO.vertexData[ssboIndex] = texCoord;
}
}
}
#endif
#endif