Minecraft Consoles latest changes + Better shadow for water in Extra mode

Culling for water need more work in extra graphics mode.
This commit is contained in:
GabsPuNs
2026-04-08 23:47:27 -04:00
parent 23102c65b6
commit 4dfedbffd1
12 changed files with 453 additions and 102 deletions

View File

@@ -326,7 +326,10 @@ bool TileRenderer::tesselateInWorld( Tile* tt, int x, int y, int z, int forceDat
retVal = tesselateQuartzInWorld(tt, x, y, z);
break;
case Tile::SHAPE_WATER:
retVal = tesselateWaterInWorld( tt, x, y, z );
if (Minecraft::GetInstance()->options->mipmapsBlend)
retVal = tesselateWaterInWorldAO( tt, x, y, z );
else
retVal = tesselateWaterInWorld( tt, x, y, z );
break;
case Tile::SHAPE_CACTUS:
retVal = tesselateCactusInWorld( tt, x, y, z );
@@ -4755,6 +4758,209 @@ bool TileRenderer::tesselateWaterInWorld(Tile* tt, int x, int y, int z)
return changed;
}
bool TileRenderer::tesselateWaterInWorldAO(Tile* tt, int x, int y, int z)
{
Tesselator* t = Tesselator::getInstance();
int col = tt->getColor(level, x, y, z);
float r = ((col >> 16) & 0xff) / 255.0f;
float g = ((col >> 8) & 0xff) / 255.0f;
float b = (col & 0xff) / 255.0f;
bool up = tt->shouldRenderFace(level, x, y + 1, z, 1);
bool down = tt->shouldRenderFace(level, x, y - 1, z, 0);
bool dirs[4];
dirs[0] = tt->shouldRenderFace( level, x, y, z - 1, 2 );
dirs[1] = tt->shouldRenderFace( level, x, y, z + 1, 3 );
dirs[2] = tt->shouldRenderFace( level, x - 1, y, z, 4 );
dirs[3] = tt->shouldRenderFace( level, x + 1, y, z, 5 );
if (!up && !down && !dirs[0] && !dirs[1] && !dirs[2] && !dirs[3])
return false;
bool changed = false;
Material* m = tt->material;
int data = level->getData(x, y, z);
float h0 = getWaterHeight(x, y, z, m);
float h1 = getWaterHeight(x, y, z + 1, m);
float h2 = getWaterHeight(x + 1, y, z + 1, m);
float h3 = getWaterHeight(x + 1, y, z, m);
float maxh = h0;
if (h1 > maxh) maxh = h1;
if (h2 > maxh) maxh = h2;
if (h3 > maxh) maxh = h3;
// 4J - added. Farm tiles often found beside water, but they consider themselves non-solid as they only extend up to 15.0f / 16.0f.
// If the max height of this water is below that level, don't bother rendering sides bordering onto farmland.
if (maxh <= ( 15.0f / 16.0f ))
{
if (level->getTile(x, y, z - 1) == Tile::farmland_Id) dirs[0] = false;
if (level->getTile(x, y, z + 1) == Tile::farmland_Id) dirs[1] = false;
if (level->getTile(x - 1, y, z) == Tile::farmland_Id) dirs[2] = false;
if (level->getTile(x + 1, y, z) == Tile::farmland_Id) dirs[3] = false;
}
constexpr float EPS = 0.0001f;
if (noCulling || up)
{
changed = true;
Icon* tex = getTexture(tt, 1, data);
float angle = static_cast<float>(LiquidTile::getSlopeAngle(level, x, y, z, m));
if (angle > -999.0f) tex = getTexture(tt, 2, data);
h0 -= EPS; h1 -= EPS; h2 -= EPS; h3 -= EPS;
float u0, v0, u1, v1, u2, v2, u3, v3;
if (angle >= -999.0f)
{
float cc = 8.0f;
float fsin = Mth::sin(angle) * 0.25f;
float fcos = Mth::cos(angle) * 0.25f;
u0 = tex->getU(cc + (-fcos - fsin) * SharedConstants::WORLD_RESOLUTION);
v0 = tex->getV(cc + (fsin - fcos) * SharedConstants::WORLD_RESOLUTION);
u1 = tex->getU(cc + (fsin - fcos) * SharedConstants::WORLD_RESOLUTION);
v1 = tex->getV(cc + (fcos + fsin) * SharedConstants::WORLD_RESOLUTION);
u2 = tex->getU(cc + (fcos + fsin) * SharedConstants::WORLD_RESOLUTION);
v2 = tex->getV(cc + (fcos - fsin) * SharedConstants::WORLD_RESOLUTION);
u3 = tex->getU(cc + (fcos - fsin) * SharedConstants::WORLD_RESOLUTION);
v3 = tex->getV(cc + (-fcos - fsin) * SharedConstants::WORLD_RESOLUTION);
}
else
{
u0 = tex->getU(0.0f, true); v0 = tex->getV(0.0f, true);
u1 = u0; v1 = tex->getV(SharedConstants::WORLD_RESOLUTION, true);
u2 = tex->getU(SharedConstants::WORLD_RESOLUTION, true); v2 = v1;
u3 = u2; v3 = v0;
}
int pY = y + 1;
int centerColor = tt->getLightColor(level, x, pY, z);
float ll0Y0 = tt->getShadeBrightness(level, x, pY, z);
auto getWaterLight = [&](int sx, int sy, int sz) -> int {
if (level->isSolidBlockingTile(sx, sy, sz)) return centerColor;
return tt->getLightColor(level, sx, sy, sz);
};
auto getWaterBr = [&](int sx, int sy, int sz) -> float {
if (level->isSolidBlockingTile(sx, sy, sz)) return ll0Y0;
return tt->getShadeBrightness(level, sx, sy, sz);
};
int ccxY0 = getWaterLight(x - 1, pY, z);
int ccXY0 = getWaterLight(x + 1, pY, z);
int cc0Yz = getWaterLight(x, pY, z - 1);
int cc0YZ = getWaterLight(x, pY, z + 1);
float llxY0 = getWaterBr(x - 1, pY, z);
float llXY0 = getWaterBr(x + 1, pY, z);
float ll0Yz = getWaterBr(x, pY, z - 1);
float ll0YZ = getWaterBr(x, pY, z + 1);
float llxYz, llXYz, llxYZ, llXYZ;
int ccxYz, ccXYz, ccxYZ, ccXYZ;
llxYz = getWaterBr(x - 1, pY, z - 1); ccxYz = getWaterLight(x - 1, pY, z - 1);
llXYz = getWaterBr(x + 1, pY, z - 1); ccXYz = getWaterLight(x + 1, pY, z - 1);
llxYZ = getWaterBr(x - 1, pY, z + 1); ccxYZ = getWaterLight(x - 1, pY, z + 1);
llXYZ = getWaterBr(x + 1, pY, z + 1); ccXYZ = getWaterLight(x + 1, pY, z + 1);
float b0 = (llxY0 + llxYz + ll0Y0 + ll0Yz) / 4.0f;
int c0 = blend(ccxY0, ccxYz, centerColor, cc0Yz);
float b1 = (llxYZ + llxY0 + ll0YZ + ll0Y0) / 4.0f;
int c1 = blend(ccxYZ, ccxY0, cc0YZ, centerColor);
float b2 = (ll0YZ + ll0Y0 + llXYZ + llXY0) / 4.0f;
int c2 = blend(cc0YZ, centerColor, ccXYZ, ccXY0);
float b3 = (ll0Y0 + ll0Yz + llXY0 + llXYz) / 4.0f;
int c3 = blend(centerColor, cc0Yz, ccXY0, ccXYz);
t->tex2(c0); t->color(r * b0, g * b0, b * b0);
t->vertexUV((float)x, (float)(y + h0), (float)z, u0, v0);
t->tex2(c1); t->color(r * b1, g * b1, b * b1);
t->vertexUV((float)x, (float)(y + h1), (float)(z + 1), u1, v1);
t->tex2(c2); t->color(r * b2, g * b2, b * b2);
t->vertexUV((float)(x + 1), (float)(y + h2), (float)(z + 1), u2, v2);
t->tex2(c3); t->color(r * b3, g * b3, b * b3);
t->vertexUV((float)(x + 1), (float)(y + h3), (float)z, u3, v3);
if (static_cast<LiquidTile*>(tt)->LiquidTile::shouldRenderBackwardUpFace(level, x, y + 1, z))
{
t->tex2(c0); t->color(r * b0, g * b0, b * b0);
t->vertexUV((float)x, (float)(y + h0), (float)z, u0, v0);
t->tex2(c3); t->color(r * b3, g * b3, b * b3);
t->vertexUV((float)(x + 1), (float)(y + h3), (float)z, u3, v3);
t->tex2(c2); t->color(r * b2, g * b2, b * b2);
t->vertexUV((float)(x + 1), (float)(y + h2), (float)(z + 1), u2, v2);
t->tex2(c1); t->color(r * b1, g * b1, b * b1);
t->vertexUV((float)x, (float)(y + h1), (float)(z + 1), u1, v1);
}
}
if (noCulling || down)
{
t->tex2(getLightColor(tt, level, x, y - 1, z));
float bl = tt->getShadeBrightness(level, x, y - 1, z);
t->color(r * 0.5f * bl, g * 0.5f * bl, b * 0.5f * bl);
renderFaceDown(tt, x, y + EPS, z, getTexture(tt, 0));
changed = true;
}
for (int face = 0; face < 4; face++)
{
if (noCulling || dirs[face])
{
int xt = x, zt = z;
float x0, z0, x1, z1, hh0, hh1;
if (face == 0) { zt--; x1 = x + 1.0f; z1 = z + EPS; x0 = x; z0 = z + EPS; hh0 = h0; hh1 = h3; }
else if (face == 1) { zt++; x1 = x; z1 = z + 1.0f - EPS; x0 = x + 1.0f; z0 = z + 1.0f - EPS; hh0 = h2; hh1 = h1; }
else if (face == 2) { xt--; x1 = x + EPS; z1 = z; x0 = x + EPS; z0 = z + 1.0f; hh0 = h1; hh1 = h0; }
else { xt++; x0 = x + 1.0f - EPS; z1 = z + 1.0f; x1 = x + 1.0f - EPS; z0 = z; hh0 = h3; hh1 = h2; }
changed = true;
Icon* tex = getTexture(tt, face + 2, data);
float side_v_h0 = tex->getV((1.0f - hh0) * 8.0f);
float side_v_h1 = tex->getV((1.0f - hh1) * 8.0f);
float side_u0 = tex->getU(0.0f, true), side_u1 = tex->getU(8.0f, true), side_v1 = tex->getV(8.0f, true);
int lightTop = getLightColor(tt, level, xt, y + 1, zt);
int lightBot = getLightColor(tt, level, xt, y, zt);
float br = (face < 2) ? 0.8f : 0.6f;
t->tex2(lightTop); t->color(br * r, br * g, br * b);
t->vertexUV(x0, y + hh0, z0, side_u0, side_v_h0);
t->vertexUV(x1, y + hh1, z1, side_u1, side_v_h1);
t->tex2(lightBot);
t->vertexUV(x1, (float)y, z1, side_u1, side_v1);
t->vertexUV(x0, (float)y, z0, side_u0, side_v1);
t->tex2(lightBot);
t->vertexUV(x0, (float)y, z0, side_u0, side_v1);
t->vertexUV(x1, (float)y, z1, side_u1, side_v1);
t->tex2(lightTop);
t->vertexUV(x1, y + hh1, z1, side_u1, side_v_h1);
t->vertexUV(x0, y + hh0, z0, side_u0, side_v_h0);
}
}
tileShapeY0 = 0.0f;
tileShapeY1 = 1.0f;
return changed;
}
float TileRenderer::getWaterHeight( int x, int y, int z, Material* m )
{
int count = 0;