vanilla fluid rendering: water and lava as fluid polygons with level/neighbour corner heights, flow textures, double-sided and overlay faces, texture alpha, opaque lava, waterlogged blocks and seagrass/kelp/bubble columns hold water, underwater and lava fog from biome water_fog attributes with gaussian biome blend, fogged sky disc, 6/7 fov in fluids, sky light under water also for underwater cameras, fluid test scenes
This commit is contained in:
1 parent
9093c1ccfb
commit
4348b5fca0
8 files changed
+1160
-175
No files matched your search
@@ -12,6 +12,7 @@ import javax.imageio.ImageIO;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -212,6 +213,30 @@ public class PPTest extends JavaPlugin {
|
||||
scenes.put("items_inverted", new Scene("items_inverted", this::itemsInverted, 3, 2.4, 7, 3, 0.6, 1.5));
|
||||
scenes.put("xmas_chests", new Scene("xmas_chests", this::xmasChests, 6, 3.6, 9.5, 6, 0.5, 1.5));
|
||||
scenes.put("frames_markers", new Scene("frames_markers", this::framesMarkers, 2.5, 2.4, 4.2, 2.5, 2.4, 0));
|
||||
// Fluids (vanilla FluidRenderer / FogRenderer): liq_flow = water flowing with physics (rendered 200 ticks after
|
||||
// building): a source on a 3-high terrace spreading and falling over its edges, a lone source spreading on
|
||||
// the floor, a sunk 3x3 source pool (surface 8/9 below the rim). liq_logged = waterlogged blocks in a 1-deep
|
||||
// pool, standing in the air (water inside, surface at 8/9) and under water. liq_under* = camera in a
|
||||
// 22x22x8 tank with concrete pillars at growing distances (water fog), seen from 3 and 7 deep, looking up at
|
||||
// the surface (bridge + lily pads above), just under the surface, from above; _swamp/_warm = same tank in a
|
||||
// swamp / warm ocean (water_fog_color, swamp end x0.85, water_color). liq_lava = lava pool, flowing levels
|
||||
// and a falling column; liq_lava_in = camera inside the lava (lava fog).
|
||||
scenes.put("liq_flow", new Scene("liq_flow", this::liqFlow, -3, 8, -9, 6, 0, 0));
|
||||
scenes.put("liq_flow_close", new Scene("liq_flow_close", this::liqFlow, 7.5, 1.6, 9, 11, 0, 5));
|
||||
scenes.put("liq_flow_fall", new Scene("liq_flow_fall", this::liqFlow, -4, 3, 7, 2, 1.5, 0));
|
||||
scenes.put("liq_logged", new Scene("liq_logged", this::liqLogged, 6, 3.6, -4.5, 6, -0.5, 3.5));
|
||||
scenes.put("liq_logged_close", new Scene("liq_logged_close", this::liqLogged, 2.2, 0.7, -1.4, 3, -0.4, 1.5));
|
||||
scenes.put("liq_logged_air", new Scene("liq_logged_air", this::liqLogged, 4, 1.6, 2.6, 4.5, 0.4, 5.5));
|
||||
scenes.put("liq_under", new Scene("liq_under", o -> liqUnder(o, Biome.PLAINS), -3.5, -3, -8.5, 12, -5, 6));
|
||||
scenes.put("liq_under_deep", new Scene("liq_under_deep", o -> liqUnder(o, Biome.PLAINS), -3.5, -7, -8.5, 12, -6, 6));
|
||||
scenes.put("liq_under_up", new Scene("liq_under_up", o -> liqUnder(o, Biome.PLAINS), 6.2, -6, -4, 6.4, 0, 0.5));
|
||||
scenes.put("liq_under_shallow", new Scene("liq_under_shallow", o -> liqUnder(o, Biome.PLAINS), -3.5, -0.45, -8.5, 12, 0.6, 6));
|
||||
scenes.put("liq_under_top", new Scene("liq_under_top", o -> liqUnder(o, Biome.PLAINS), -3, 4, -10, 6, -6, 2));
|
||||
scenes.put("liq_under_swamp", new Scene("liq_under_swamp", o -> liqUnder(o, Biome.SWAMP), -3.5, -3, -8.5, 12, -5, 6));
|
||||
scenes.put("liq_under_warm", new Scene("liq_under_warm", o -> liqUnder(o, Biome.WARM_OCEAN), -3.5, -3, -8.5, 12, -5, 6));
|
||||
scenes.put("liq_under_warm_top", new Scene("liq_under_warm_top", o -> liqUnder(o, Biome.WARM_OCEAN), -3, 4, -10, 6, -6, 2));
|
||||
scenes.put("liq_lava", new Scene("liq_lava", this::liqLava, 4, 4.5, -6, 9, 0, 1));
|
||||
scenes.put("liq_lava_in", new Scene("liq_lava_in", this::liqLava, 3.5, -0.5, 1.5, 9, -0.5, 1.5));
|
||||
}
|
||||
|
||||
private static ItemStack shield(DyeColor base, Object... patterns) {
|
||||
@@ -838,7 +863,7 @@ public class PPTest extends JavaPlugin {
|
||||
t.printStackTrace();
|
||||
}
|
||||
// Let one tick pass (passengers/leashes settle), then render.
|
||||
Bukkit.getScheduler().runTaskLater(this, () -> render(sc, o), sc.name.equals("proj_shake") ? 4 : sc.name.startsWith("proj_") ? 30 : sc.name.startsWith("be_contents") ? 100 : 10);
|
||||
Bukkit.getScheduler().runTaskLater(this, () -> render(sc, o), sc.name.equals("proj_shake") ? 4 : sc.name.startsWith("proj_") ? 30 : sc.name.startsWith("be_contents") ? 100 : sc.name.startsWith("liq_flow") ? 200 : 10);
|
||||
}
|
||||
|
||||
private void render(Scene sc, Location o) {
|
||||
@@ -846,7 +871,7 @@ public class PPTest extends JavaPlugin {
|
||||
Location eye = o.clone().add(sc.camX, sc.camY, sc.camZ);
|
||||
Vector look = o.clone().add(sc.lookX, sc.lookY, sc.lookZ).toVector().subtract(eye.toVector());
|
||||
eye.setDirection(look);
|
||||
RenderJob job = r.prepare(eye, sc.name.endsWith("_sq") ? new Resolution(384, 384) : sc.name.startsWith("proj_") || sc.name.startsWith("rf_") || sc.name.startsWith("pose_") || sc.name.startsWith("frames") || sc.name.startsWith("geo_") || sc.name.startsWith("items_") || sc.name.startsWith("xmas_") ? new Resolution(960, 640) : new Resolution(480, 320), null);
|
||||
RenderJob job = r.prepare(eye, sc.name.endsWith("_sq") ? new Resolution(384, 384) : sc.name.startsWith("proj_") || sc.name.startsWith("rf_") || sc.name.startsWith("pose_") || sc.name.startsWith("frames") || sc.name.startsWith("geo_") || sc.name.startsWith("liq_") || sc.name.startsWith("items_") || sc.name.startsWith("xmas_") ? new Resolution(960, 640) : new Resolution(480, 320), null);
|
||||
if (sc.name.equals("dbg")) {
|
||||
try {
|
||||
java.lang.reflect.Field f = DefaultScreenRenderer.class.getDeclaredField("objectBaker");
|
||||
@@ -2067,4 +2092,111 @@ public class PPTest extends JavaPlugin {
|
||||
}
|
||||
return mapItem(v);
|
||||
}
|
||||
|
||||
// --- fluids ------------------------------------------------------------------------------------------------
|
||||
|
||||
/** Sets the biome of the scene area (deterministic water colour / water fog). */
|
||||
private void biome(Location o, Biome biome) {
|
||||
for (int x = -8; x < 20; x += 2)
|
||||
for (int z = -14; z < 14; z += 2)
|
||||
for (int y = -16; y < 16; y += 2)
|
||||
w.setBiome(o.getBlockX() + x, o.getBlockY() + y, o.getBlockZ() + z, biome);
|
||||
}
|
||||
|
||||
/** A block placed WITH physics (fluids schedule their flow ticks). */
|
||||
private void putPhys(Location o, int x, int y, int z, String data) {
|
||||
o.clone().add(x, y, z).getBlock().setBlockData(Bukkit.createBlockData("minecraft:" + data), true);
|
||||
}
|
||||
|
||||
private void liqFlow(Location o) {
|
||||
biome(o, Biome.PLAINS);
|
||||
// Stone rim keeps the water on the platform.
|
||||
for (int x = -5; x <= 16; x++)
|
||||
for (int z = -11; z <= 10; z++)
|
||||
if (x == -5 || x == 16 || z == -11 || z == 10) put(o, x, 0, z, "stone");
|
||||
for (int x = 0; x <= 4; x++)
|
||||
for (int z = -2; z <= 2; z++)
|
||||
for (int y = 0; y <= 2; y++) put(o, x, y, z, "stone");
|
||||
for (int x = 10; x <= 12; x++)
|
||||
for (int z = -6; z <= -4; z++) {
|
||||
put(o, x, -2, z, "sand");
|
||||
put(o, x, -1, z, "water");
|
||||
}
|
||||
putPhys(o, 2, 3, 0, "water");
|
||||
putPhys(o, 11, 0, 5, "water");
|
||||
}
|
||||
|
||||
private static final String[] LOGGED = {
|
||||
"oak_stairs[facing=north,waterlogged=true]", "stone_slab[type=bottom,waterlogged=true]",
|
||||
"stone_slab[type=top,waterlogged=true]", "oak_fence[waterlogged=true]", "glass_pane[waterlogged=true]",
|
||||
"seagrass", "kelp_plant", "tube_coral[waterlogged=true]", "oak_leaves[waterlogged=true,persistent=true]",
|
||||
"lantern[waterlogged=true]", "sea_pickle[pickles=3,waterlogged=true]", "oak_trapdoor[half=bottom,open=false,waterlogged=true]"};
|
||||
|
||||
private void liqLogged(Location o) {
|
||||
biome(o, Biome.PLAINS);
|
||||
for (int x = -1; x <= LOGGED.length; x++)
|
||||
for (int z = 0; z <= 2; z++) {
|
||||
put(o, x, -2, z, "sand");
|
||||
put(o, x, -1, z, "water");
|
||||
}
|
||||
for (int i = 0; i < LOGGED.length; i++) {
|
||||
put(o, i, -1, 1, LOGGED[i]); // in the pool
|
||||
put(o, i, 0, 5, LOGGED[i]); // in the air: water inside, surface at 8/9
|
||||
}
|
||||
// Under water: a waterlogged stair and slab with a water source above them.
|
||||
put(o, 2, 0, 8, "oak_stairs[facing=south,waterlogged=true]");
|
||||
put(o, 2, 1, 8, "water");
|
||||
put(o, 4, 0, 8, "stone_slab[type=bottom,waterlogged=true]");
|
||||
put(o, 4, 1, 8, "water");
|
||||
// Water next to glass and leaves (overlay faces) on the floor.
|
||||
put(o, 7, 0, 8, "water");
|
||||
put(o, 8, 0, 8, "glass");
|
||||
put(o, 9, 0, 8, "water");
|
||||
put(o, 10, 0, 8, "oak_leaves[persistent=true]");
|
||||
}
|
||||
|
||||
private void liqUnder(Location o, Biome biome) {
|
||||
biome(o, biome);
|
||||
for (int x = -5; x <= 17; x++)
|
||||
for (int z = -11; z <= 11; z++)
|
||||
for (int y = -9; y <= -1; y++) {
|
||||
boolean wall = x == -5 || x == 17 || z == -11 || z == 11;
|
||||
put(o, x, y, z, wall ? "stone_bricks" : y == -9 ? "sand" : "water");
|
||||
}
|
||||
String[] pillars = {"red_concrete", "yellow_concrete", "lime_concrete", "blue_concrete", "white_concrete", "orange_concrete"};
|
||||
int[][] at = {{0, 0}, {4, -4}, {8, 4}, {12, -6}, {15, 8}, {16, -10}};
|
||||
for (int i = 0; i < pillars.length; i++)
|
||||
for (int y = -8; y <= -4; y++) put(o, at[i][0], y, at[i][1], pillars[i]);
|
||||
put(o, 2, -8, 3, "gold_block");
|
||||
put(o, 2, -7, 3, "glass");
|
||||
put(o, 5, -8, 1, "oak_stairs[facing=west,waterlogged=true]");
|
||||
for (int i = 0; i < 8; i++) put(o, -2 + i * 2, -8, -6 + (i % 3), "seagrass");
|
||||
// Above the water: a bridge and lily pads, seen from below through the surface.
|
||||
for (int x = 3; x <= 9; x++) put(o, x, 2, 1, "oak_planks");
|
||||
put(o, 6, 0, -2, "lily_pad");
|
||||
put(o, 7, 0, -1, "lily_pad");
|
||||
}
|
||||
|
||||
private void liqLava(Location o) {
|
||||
biome(o, Biome.PLAINS);
|
||||
for (int x = -2; x <= 17; x++)
|
||||
for (int z = -3; z <= 5; z++)
|
||||
if (x == -2 || x == 17 || z == -3 || z == 5) put(o, x, 0, z, "stone");
|
||||
for (int x = 2; x <= 4; x++)
|
||||
for (int z = 0; z <= 2; z++) {
|
||||
put(o, x, -2, z, "basalt");
|
||||
put(o, x, -1, z, "lava");
|
||||
}
|
||||
// A source with flowing lava around it (overworld drop-off 2: amounts 8/6/4/2 = levels 0/2/4/6).
|
||||
for (int dx = -3; dx <= 3; dx++)
|
||||
for (int dz = -3; dz <= 3; dz++) {
|
||||
int d = Math.abs(dx) + Math.abs(dz);
|
||||
if (d <= 3) put(o, 9 + dx, 0, 1 + dz, d == 0 ? "lava" : "lava[level=" + (2 * d) + "]");
|
||||
}
|
||||
// Lava falling from a pillar.
|
||||
for (int y = 0; y <= 2; y++) put(o, 14, y, 1, "stone");
|
||||
put(o, 14, 3, 1, "lava");
|
||||
put(o, 15, 3, 1, "lava[level=2]");
|
||||
for (int y = 0; y <= 2; y++) put(o, 15, y, 1, "lava[level=10]");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user