232 lines
10 KiB
GLSL
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
|