From 57f5ad5ea0e50c0143f0a64b4d5fbd9cad642191 Mon Sep 17 00:00:00 2001 From: tom lee Date: Sun, 20 Feb 2022 16:10:22 +0800 Subject: [PATCH] Fix fog using vert instead of per frag. Oh and impl greedy meshing --- .../LodBufferBuilderFactory.java | 1 + .../core/objects/opengl/LodQuadBuilder.java | 230 +++++++++++++++++- src/main/resources/shaders/flat_shaded.frag | 4 +- src/main/resources/shaders/standard.vert | 4 +- 4 files changed, 231 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java index 3cd0e456c..8dd459aef 100644 --- a/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java +++ b/src/main/java/com/seibel/lod/core/builders/bufferBuilding/LodBufferBuilderFactory.java @@ -457,6 +457,7 @@ public class LodBufferBuilderFactory { } // for pos to in list to render // the thread executed successfully + quadBuilder.mergeQuads(); return regPos; } diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java index 6a74df2d8..3ed74bbf9 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodQuadBuilder.java @@ -4,8 +4,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Iterator; -import java.util.function.Function; +import java.util.ListIterator; +import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.enums.LodDirection; import com.seibel.lod.core.enums.LodDirection.Axis; import com.seibel.lod.core.enums.config.GpuUploadMethod; @@ -15,14 +16,15 @@ public class LodQuadBuilder { static final int MAX_BUFFER_SIZE = (1024 * 1024 * 1); static final int QUAD_BYTE_SIZE = (12 * 6); static final int MAX_QUADS_PER_BUFFER = MAX_BUFFER_SIZE / QUAD_BYTE_SIZE; + static final int MAX_MERGED_QUAD_SIZE = 64; static class Quad { final short x; final short y; final short z; - final short w0; - final short w1; - final int color; + short w0; + short w1; + int color; final byte skylight; final byte blocklight; final LodDirection dir; @@ -47,12 +49,181 @@ public class LodQuadBuilder { void calculateDistance(double relativeX, double relativeY, double relativeZ) { distance = pow(relativeX-x) + pow(relativeY-y) + pow(relativeZ-z); } + + private static int _compondCompare(short a0, short b0, short c0, short a1, short b1, short c1) { + if (a0 != a1) return a0-a1; + if (b0 != b1) return b0-b1; + return c0-c1; + } + + public int compareTo1(Quad o) { + if (dir != o.dir) return dir.compareTo(o.dir); + switch (dir.getAxis()) { + case X: + return _compondCompare(x, y, z, o.x, o.y, o.z); + case Y: + return _compondCompare(y, z, x, o.y, o.z, o.x); + case Z: + return _compondCompare(z, y, x, o.z, o.y, o.x); + default: + throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); + } + } + public int compareTo2(Quad o) { + if (dir != o.dir) return dir.compareTo(o.dir); + switch (dir.getAxis()) { + case X: + return _compondCompare(x, z, y, o.x, o.z, o.y); + case Y: + return _compondCompare(y, x, z, o.y, o.x, o.z); + case Z: + return _compondCompare(z, x, y, o.z, o.x, o.y); + default: + throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); + } + } + + public boolean tryMergeWith1(Quad o) + { + if (dir != o.dir) + return false; + if (w0 >= MAX_MERGED_QUAD_SIZE) return false; + switch (dir.getAxis()) + { + case X: + if (x != o.x || + y != o.y || + z + w0 < o.z) + return false; + if (z + w0 > o.z) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w1 != o.w1 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + + w0 += o.w0; + return true; + case Y: + if (y != o.y || + z != o.z || + x + w0 < o.x) + return false; + if (x + w0 > o.x) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w1 != o.w1 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + + w0 += o.w0; + return true; + case Z: + if (z != o.z || + y != o.y || + x + w0 < o.x) + return false; + if (x + w0 > o.x) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w1 != o.w1 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + + w0 += o.w0; + return true; + default: + throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); + } + } + + public boolean tryMergeWith2(Quad o) + { + if (dir != o.dir) + return false; + if (w1 >= MAX_MERGED_QUAD_SIZE) return false; + switch (dir.getAxis()) + { + case X: + if (x != o.x || + z != o.z || + y + w1 < o.y) + return false; + if (y + w1 > o.y) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w0 != o.w0 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + w1 += o.w1; + return true; + case Y: + if (y != o.y || + x != o.x || + z + w1 < o.z) + return false; + if (z + w1 > o.z) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w0 != o.w0 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + w1 += o.w1; + return true; + case Z: + if (z != o.z || + x != o.x || + y + w1 < o.y) + return false; + if (y + w1 > o.y) + { + ClientApi.LOGGER.warn("Overlapping quads detected!"); + o.color = ColorUtil.rgbToInt(255, 0, 0); + return false; + } + if (w0 != o.w0 || + color != o.color || + skylight != o.skylight || + blocklight != o.blocklight) + return false; + w1 += o.w1; + return true; + default: + throw new IllegalArgumentException("Invalid Axis enum: " + dir.getAxis()); + } + } + } final ArrayList quads; public LodQuadBuilder(int initialSize) { - quads = new ArrayList(initialSize); + quads = new ArrayList(); } public void addQuadAdj(LodDirection dir, short x, short y, short z, short w0, short wy, int color, byte skylight, @@ -157,7 +328,56 @@ public class LodQuadBuilder { quads.forEach(p -> p.calculateDistance(dPlayerPosX, dPlayerPosY, dPlayerPosZ)); quads.sort((a, b) -> Double.compare(a.distance, b.distance)); } + private long merggeQuadsPass1() { + quads.sort(Quad::compareTo1); + ListIterator iter = quads.listIterator(); + long mergeCount = 0; + Quad currentQuad = iter.next(); + while (iter.hasNext()) { + Quad nextQuad = iter.next(); + if (currentQuad.tryMergeWith1(nextQuad)) { + mergeCount++; + iter.set(null); + } else { + currentQuad = nextQuad; + } + } + quads.removeIf(o -> o==null); + return mergeCount; + } + + private long merggeQuadsPass2() { + quads.sort(Quad::compareTo2); + ListIterator iter = quads.listIterator(); + long mergeCount = 0; + Quad currentQuad = iter.next(); + while (iter.hasNext()) { + Quad nextQuad = iter.next(); + if (currentQuad.tryMergeWith2(nextQuad)) { + mergeCount++; + iter.set(null); + } else { + currentQuad = nextQuad; + } + } + quads.removeIf(o -> o==null); + return mergeCount; + } + + + public void mergeQuads() { + if (quads.size()<=1) return; + + long mergeCount = 0; + long preQuadsCount = quads.size(); + mergeCount += merggeQuadsPass1(); + mergeCount += merggeQuadsPass2(); + long postQuadsCount = quads.size(); + //if (mergeCount != 0) + //ClientApi.LOGGER.info("Merged {} out of {} quads, to now {} quads.", mergeCount, preQuadsCount, postQuadsCount); + } + public Iterator makeVertexBuffers() { int numOfBuffers = getCurrentNeededVertexBuffers(); return new Iterator() { diff --git a/src/main/resources/shaders/flat_shaded.frag b/src/main/resources/shaders/flat_shaded.frag index aa696ec26..bea983d82 100644 --- a/src/main/resources/shaders/flat_shaded.frag +++ b/src/main/resources/shaders/flat_shaded.frag @@ -1,7 +1,7 @@ #version 150 core in vec4 vertexColor; -in float dist; +in vec3 vertexWorldPos; out vec4 fragColor; @@ -42,6 +42,8 @@ void main() // no fog by default float fogAlpha = 0; + float dist = length(vertexWorldPos); + // less than because nearFogStart is farther away than nearFogEnd if (nearFogEnabled && dist < nearFogStart) { diff --git a/src/main/resources/shaders/standard.vert b/src/main/resources/shaders/standard.vert index 4d4510cb8..9ba0fbdde 100644 --- a/src/main/resources/shaders/standard.vert +++ b/src/main/resources/shaders/standard.vert @@ -4,7 +4,7 @@ in vec4 vPosition; in vec4 color; out vec4 vertexColor; -out float dist; +out vec3 vertexWorldPos; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; @@ -29,7 +29,7 @@ void main() vertexColor = color * texture(lightMap, vec2(light,0.5)); - dist = length(worldSpacePos.xyz); + vertexWorldPos = worldSpacePos.xyz; gl_Position = projectionMatrix * worldSpacePos; }