This commit is contained in:
mcrcortex
2024-09-29 10:44:16 +10:00
parent 5e72b945c4
commit 3d2129c1d4
7 changed files with 59 additions and 21 deletions

View File

@@ -38,7 +38,7 @@ public class ModelBakerySubsystem {
public void tick() {
//There should be a method to access the frame time IIRC, if the user framecap is unlimited lock it to like 60 fps for computation
int BUDGET = 10;//TODO: make this computed based on the remaining free time in a frame (and like div by 2 to reduce overhead) (with a min of 1)
int BUDGET = 20;//TODO: make this computed based on the remaining free time in a frame (and like div by 2 to reduce overhead) (with a min of 1)
for (int i = 0; i < BUDGET && !this.blockIdQueue.isEmpty(); i++) {
int blockId = -1;

View File

@@ -0,0 +1,38 @@
package me.cortex.voxy.client.core.rendering;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
//CPU side cache for section geometry, not thread safe
public class GeometryCache {
private long maxCombinedSize;
private long currentSize;
private final Long2ObjectLinkedOpenHashMap<BuiltSection> cache = new Long2ObjectLinkedOpenHashMap<>();
public GeometryCache(long maxSize) {
this.maxCombinedSize = maxSize;
}
//Puts the section into the cache
public void put(BuiltSection section) {
var prev = this.cache.put(section.position, section);
this.currentSize += section.geometryBuffer.size;
if (prev != null) {
this.currentSize -= prev.geometryBuffer.size;
prev.free();
}
while (this.maxCombinedSize <= this.currentSize) {
var entry = this.cache.removeFirst();
this.currentSize -= entry.geometryBuffer.size;
entry.free();
}
}
public BuiltSection remove(long position) {
var section = this.cache.remove(position);
if (section != null) {
this.currentSize -= section.geometryBuffer.size;
}
return section;
}
}

View File

@@ -47,7 +47,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
//Max sections: ~500k
//Max geometry: 1 gb
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<19, (1L<<30)-1024);
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<19, (1L<<31)-1024);
//Do something incredibly hacky, we dont need to keep the reference to this around, so just connect and discard
var router = new SectionUpdateRouter();
@@ -69,7 +69,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
this.sectionUpdateQueue.push(section);
});
this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager, 256);
this.traversal = new HierarchicalOcclusionTraverser(this.nodeManager);
world.setDirtyCallback(router::forward);
@@ -79,7 +79,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
//this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(0, 0,0,0));
//this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, 0,0,0));
/*
final int H_WIDTH = 10;
for (int x = -H_WIDTH; x <= H_WIDTH; x++) {
for (int y = -1; y <= 0; y++) {
@@ -87,7 +87,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
}
}
}*/
}
}
public void setup(Camera camera) {

View File

@@ -28,9 +28,10 @@ import static org.lwjgl.opengl.GL45.*;
// TODO: swap to persistent gpu threads instead of dispatching MAX_ITERATIONS of compute layers
public class HierarchicalOcclusionTraverser {
public static final int REQUEST_QUEUE_SIZE = 256;
private final NodeManager2 nodeManager;
private final int maxRequestCount;
private final GlBuffer requestBuffer;
private final GlBuffer nodeBuffer;
@@ -61,7 +62,7 @@ public class HierarchicalOcclusionTraverser {
.defineIf("DEBUG", Voxy.SHADER_DEBUG)
.define("MAX_ITERATIONS", MAX_ITERATIONS)
.define("LOCAL_SIZE_BITS", LOCAL_WORK_SIZE_BITS)
.define("REQUEST_QUEUE_SIZE", NodeManager.REQUEST_QUEUE_SIZE)
.define("REQUEST_QUEUE_SIZE", REQUEST_QUEUE_SIZE)
.define("HIZ_BINDING", 0)
@@ -79,11 +80,10 @@ public class HierarchicalOcclusionTraverser {
.compile();
public HierarchicalOcclusionTraverser(NodeManager2 nodeManager, int requestBufferCount) {
public HierarchicalOcclusionTraverser(NodeManager2 nodeManager) {
this.nodeManager = nodeManager;
this.requestBuffer = new GlBuffer(requestBufferCount*8L+8).zero();
this.requestBuffer = new GlBuffer(REQUEST_QUEUE_SIZE*8L+8).zero();
this.nodeBuffer = new GlBuffer(nodeManager.maxNodeCount*16L).zero();
this.maxRequestCount = requestBufferCount;
glSamplerParameteri(this.hizSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
@@ -245,8 +245,8 @@ public class HierarchicalOcclusionTraverser {
Logger.warn("Count over max buffer size, clamping, got count: " + count);
count = (int) ((this.requestBuffer.size()>>3)-1);
}
if (count > this.maxRequestCount) {
System.err.println("Count larger than 'maxRequestCount', overflow captured. Overflowed by " + (count-this.maxRequestCount));
if (count > REQUEST_QUEUE_SIZE) {
System.err.println("Count larger than 'maxRequestCount', overflow captured. Overflowed by " + (count-REQUEST_QUEUE_SIZE));
}
if (count != 0) {
//this.nodeManager.processRequestQueue(count, ptr + 8);

View File

@@ -35,7 +35,7 @@ public class VoxyCommon implements ModInitializer {
//This is hardcoded like this because people do not understand what they are doing
private static final boolean GlobalVerificationDisableOverride = false;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true");
private static final boolean GlobalVerificationDisableOverride = true;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true");
public static boolean isVerificationFlagOn(String name) {
return (!GlobalVerificationDisableOverride) && System.getProperty("voxy."+name, "true").equals("true");
}

View File

@@ -5,6 +5,9 @@ layout(location = 0) in vec2 uv;
layout(binding = 0) uniform sampler2D depthTex;
void main() {
vec4 depths = textureGather(depthTex, uv, 0); // Get depth values from all surrounding texels.
//depths = mix(vec4(0), depths, lessThanEqual(vec4(0.99999999), depths));
bvec4 cv = lessThanEqual(vec4(0.99999999), depths);
if (any(cv) && !all(cv)) {
depths = mix(vec4(0), depths, cv);
}
gl_FragDepth = max(max(depths.x, depths.y), max(depths.z, depths.w)); // Write conservative depth.
}
}

View File

@@ -21,8 +21,6 @@ vec3 minBB;
vec3 maxBB;
vec2 size;
uint lod;
//Sets up screenspace with the given node id, returns true on success false on failure/should not continue
//Accesses data that is setup in the main traversal and is just shared to here
void setupScreenspace(in UnpackedNode node) {
@@ -35,7 +33,6 @@ void setupScreenspace(in UnpackedNode node) {
vec3 point = VP*(((transform.transform*vec4((node.pos<<node.lodLevel) - transform.originPos.xyz, 1))
+ (transform.worldPos.xyz-camChunkPos))-camSubChunk);
*/
lod = node.lodLevel;
vec4 base = VP*vec4(vec3(((node.pos<<node.lodLevel)-camSecPos)<<5)-camSubSecPos, 1);
@@ -86,10 +83,10 @@ bool isCulledByHiz() {
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1)));
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f;
bool culled = textureLod(hizDepthSampler, vec3(midpoint, minBB.z), miplevel) < 0.0001f;
/*
if (culled) {
printf("HiZ sample point not culled: (%f,%f)@%f against %f, level %d", midpoint.x, midpoint.y, miplevel, minBB.z, lod);
}*/
printf("HiZ sample point culled: (%f,%f)@%f against %f", midpoint.x, midpoint.y, miplevel, minBB.z);
}
return culled;
}