Working better
This commit is contained in:
@@ -115,21 +115,6 @@ public class VoxelCore {
|
|||||||
System.out.println("Voxy core initialized");
|
System.out.println("Voxy core initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
private IRenderInterface<?> createRenderBackend() {
|
|
||||||
if (false) {
|
|
||||||
return new Gl46HierarchicalRenderer(this.modelManager);
|
|
||||||
} else if (true) {
|
|
||||||
return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
|
||||||
} else {
|
|
||||||
if (VoxyConfig.CONFIG.useMeshShaders()) {
|
|
||||||
return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
|
||||||
} else {
|
|
||||||
return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void enqueueIngest(WorldChunk worldChunk) {
|
public void enqueueIngest(WorldChunk worldChunk) {
|
||||||
this.world.ingestService.enqueueIngest(worldChunk);
|
this.world.ingestService.enqueueIngest(worldChunk);
|
||||||
}
|
}
|
||||||
@@ -275,4 +260,20 @@ public class VoxelCore {
|
|||||||
public WorldEngine getWorldEngine() {
|
public WorldEngine getWorldEngine() {
|
||||||
return this.world;
|
return this.world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private IRenderInterface<?> createRenderBackend() {
|
||||||
|
if (true) {
|
||||||
|
return new Gl46HierarchicalRenderer(this.modelManager);
|
||||||
|
} else if (true) {
|
||||||
|
return new Gl46MeshletsFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
||||||
|
} else {
|
||||||
|
if (VoxyConfig.CONFIG.useMeshShaders()) {
|
||||||
|
return new NvMeshFarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
||||||
|
} else {
|
||||||
|
return new Gl46FarWorldRenderer(this.modelManager, VoxyConfig.CONFIG.geometryBufferSize, VoxyConfig.CONFIG.maxSections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,17 +62,17 @@ public class Gl46HierarchicalRenderer implements IRenderInterface<Gl46Hierarchic
|
|||||||
this.sectionSelector = new HierarchicalOcclusionRenderer(new INodeInteractor() {
|
this.sectionSelector = new HierarchicalOcclusionRenderer(new INodeInteractor() {
|
||||||
@Override
|
@Override
|
||||||
public void watchUpdates(long pos) {
|
public void watchUpdates(long pos) {
|
||||||
|
System.err.println("Watch: " + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unwatchUpdates(long pos) {
|
public void unwatchUpdates(long pos) {
|
||||||
|
System.err.println("Unwatch: " + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestMesh(long pos) {
|
public void requestMesh(long pos) {
|
||||||
|
System.err.println("Request: " + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -93,7 +93,7 @@ public class Gl46HierarchicalRenderer implements IRenderInterface<Gl46Hierarchic
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{//Run the hierarchical selector over the buffer to generate the set of render sections
|
if (true) {//Run the hierarchical selector over the buffer to generate the set of render sections
|
||||||
var i = new int[1];
|
var i = new int[1];
|
||||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, i);
|
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, i);
|
||||||
this.sectionSelector.doHierarchicalTraversalSelection(viewport, i[0], this.renderSections);
|
this.sectionSelector.doHierarchicalTraversalSelection(viewport, i[0], this.renderSections);
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ public abstract class Viewport <A extends Viewport<A>> {
|
|||||||
public int width;
|
public int width;
|
||||||
public int height;
|
public int height;
|
||||||
int frameId;
|
int frameId;
|
||||||
Matrix4f projection;
|
public Matrix4f projection;
|
||||||
Matrix4f modelView;
|
public Matrix4f modelView;
|
||||||
double cameraX;
|
public double cameraX;
|
||||||
double cameraY;
|
public double cameraY;
|
||||||
double cameraZ;
|
public double cameraZ;
|
||||||
|
|
||||||
protected Viewport() {
|
protected Viewport() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ import me.cortex.voxy.client.core.gl.shader.Shader;
|
|||||||
import me.cortex.voxy.client.core.gl.shader.ShaderType;
|
import me.cortex.voxy.client.core.gl.shader.ShaderType;
|
||||||
import me.cortex.voxy.client.core.rendering.Gl46HierarchicalViewport;
|
import me.cortex.voxy.client.core.rendering.Gl46HierarchicalViewport;
|
||||||
import me.cortex.voxy.client.core.rendering.HiZBuffer;
|
import me.cortex.voxy.client.core.rendering.HiZBuffer;
|
||||||
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
|
|
||||||
import me.cortex.voxy.client.core.rendering.hierarchical.INodeInteractor;
|
|
||||||
import me.cortex.voxy.client.core.rendering.hierarchical.MeshManager;
|
|
||||||
import me.cortex.voxy.client.core.rendering.hierarchical.NodeManager;
|
|
||||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
|
import me.cortex.voxy.client.mixin.joml.AccessFrustumIntersection;
|
||||||
import java.util.function.Consumer;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL30.glBindBufferBase;
|
import static org.lwjgl.opengl.GL30.glBindBufferBase;
|
||||||
import static org.lwjgl.opengl.GL33.glBindSampler;
|
import static org.lwjgl.opengl.GL33.glBindSampler;
|
||||||
@@ -44,14 +43,32 @@ public class HierarchicalOcclusionRenderer {
|
|||||||
.compile();
|
.compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadUniform() {
|
private void uploadUniform(Gl46HierarchicalViewport viewport) {
|
||||||
long ptr = UploadStream.INSTANCE.upload(this.uniformBuffer, 0, 1024);
|
long ptr = UploadStream.INSTANCE.upload(this.uniformBuffer, 0, 1024);
|
||||||
|
int sx = MathHelper.floor(viewport.cameraX)>>5;
|
||||||
|
int sy = MathHelper.floor(viewport.cameraY)>>5;
|
||||||
|
int sz = MathHelper.floor(viewport.cameraZ)>>5;
|
||||||
|
|
||||||
|
new Matrix4f(viewport.projection).mul(viewport.modelView).getToAddress(ptr); ptr += 4*4*4;
|
||||||
|
|
||||||
|
MemoryUtil.memPutInt(ptr, sx); ptr += 4;
|
||||||
|
MemoryUtil.memPutInt(ptr, sy); ptr += 4;
|
||||||
|
MemoryUtil.memPutInt(ptr, sz); ptr += 4;
|
||||||
|
MemoryUtil.memPutInt(ptr, viewport.width); ptr += 4;
|
||||||
|
|
||||||
|
var innerTranslation = new Vector3f((float) (viewport.cameraX-(sx<<5)), (float) (viewport.cameraY-(sy<<5)), (float) (viewport.cameraZ-(sz<<5)));
|
||||||
|
innerTranslation.getToAddress(ptr); ptr += 4*3;
|
||||||
|
|
||||||
|
MemoryUtil.memPutInt(ptr, viewport.height); ptr += 4;
|
||||||
|
|
||||||
|
MemoryUtil.memPutInt(ptr, NodeManager.REQUEST_QUEUE_SIZE); ptr += 4;
|
||||||
|
MemoryUtil.memPutInt(ptr, 1000000); ptr += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doHierarchicalTraversalSelection(Gl46HierarchicalViewport viewport, int depthBuffer, GlBuffer renderSelectionResult) {
|
public void doHierarchicalTraversalSelection(Gl46HierarchicalViewport viewport, int depthBuffer, GlBuffer renderSelectionResult) {
|
||||||
this.uploadUniform();
|
this.uploadUniform(viewport);
|
||||||
this.nodeManager.upload();
|
this.nodeManager.upload();
|
||||||
|
UploadStream.INSTANCE.commit();
|
||||||
|
|
||||||
//Make hiz
|
//Make hiz
|
||||||
this.hiz.buildMipChain(depthBuffer, viewport.width, viewport.height);
|
this.hiz.buildMipChain(depthBuffer, viewport.width, viewport.height);
|
||||||
@@ -75,6 +92,8 @@ public class HierarchicalOcclusionRenderer {
|
|||||||
glDispatchCompute(1,1,1);
|
glDispatchCompute(1,1,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glBindSampler(0, 0);
|
||||||
|
glBindTextureUnit(0, 0);
|
||||||
this.nodeManager.download();
|
this.nodeManager.download();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class NodeManager {
|
|||||||
Arrays.fill(this.localNodeData, 0);
|
Arrays.fill(this.localNodeData, 0);
|
||||||
|
|
||||||
|
|
||||||
this.setNodePosition(0, WorldEngine.getWorldSectionId(0, 0,5,0));
|
this.setNodePosition(0, WorldEngine.getWorldSectionId(2, 0,0,0));
|
||||||
this.setChildPtr(0, NODE_MSK, 0);
|
this.setChildPtr(0, NODE_MSK, 0);
|
||||||
this.setMeshId(0, MESH_MSK);
|
this.setMeshId(0, MESH_MSK);
|
||||||
this.pushNode(0);
|
this.pushNode(0);
|
||||||
@@ -165,7 +165,7 @@ public class NodeManager {
|
|||||||
|
|
||||||
private boolean isLeafNode(int node) {
|
private boolean isLeafNode(int node) {
|
||||||
//TODO: maybe make this flag based instead of checking the child ptr?
|
//TODO: maybe make this flag based instead of checking the child ptr?
|
||||||
return this.getNodeChildPtr(node) != NODE_MSK;
|
return this.getNodeChildPtr(node) == NODE_MSK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Its ment to return if the node is just an empty mesh or if all the children are also empty
|
//Its ment to return if the node is just an empty mesh or if all the children are also empty
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class MarkedObjectList<T> {
|
|||||||
|
|
||||||
private final Int2ObjectFunction<T[]> arrayGenerator;
|
private final Int2ObjectFunction<T[]> arrayGenerator;
|
||||||
private final Supplier<T> nullSupplier;
|
private final Supplier<T> nullSupplier;
|
||||||
private final HierarchicalBitSet bitSet = new HierarchicalBitSet(-1);
|
private final HierarchicalBitSet bitSet = new HierarchicalBitSet();
|
||||||
private T[] objects;//Should maybe make a getter function instead
|
private T[] objects;//Should maybe make a getter function instead
|
||||||
|
|
||||||
public MarkedObjectList(Int2ObjectFunction<T[]> arrayGenerator, Supplier<T> nullSupplier) {
|
public MarkedObjectList(Int2ObjectFunction<T[]> arrayGenerator, Supplier<T> nullSupplier) {
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ public class HierarchicalBitSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HierarchicalBitSet() {
|
||||||
|
this(1<<(6*4));
|
||||||
|
}
|
||||||
|
|
||||||
public int allocateNext() {
|
public int allocateNext() {
|
||||||
if (this.A==-1) {
|
if (this.A==-1) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -50,14 +50,25 @@ void setupScreenspace(in UnpackedNode node) {
|
|||||||
vec4 pPoint = (VP*vec4(vec3((i&1)!=0,(i&2)!=0,(i&4)!=0)*32,1));//Size of section is 32x32x32 (need to change it to a bounding box in the future)
|
vec4 pPoint = (VP*vec4(vec3((i&1)!=0,(i&2)!=0,(i&4)!=0)*32,1));//Size of section is 32x32x32 (need to change it to a bounding box in the future)
|
||||||
pPoint += base;
|
pPoint += base;
|
||||||
vec3 point = pPoint.xyz/pPoint.w;
|
vec3 point = pPoint.xyz/pPoint.w;
|
||||||
|
//TODO: CLIP TO VIEWPORT
|
||||||
minBB = min(minBB, point);
|
minBB = min(minBB, point);
|
||||||
maxBB = max(maxBB, point);
|
maxBB = max(maxBB, point);
|
||||||
}
|
}
|
||||||
|
//printf("Screenspace MIN: %f, %f, %f MAX: %f, %f, %f", minBB.x,minBB.y,minBB.z, maxBB.x,maxBB.y,maxBB.z);
|
||||||
|
|
||||||
size = maxBB.xy - minBB.xy;
|
size = maxBB.xy - minBB.xy;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Checks if the node is implicitly culled (outside frustum)
|
||||||
|
bool outsideFrustum() {
|
||||||
|
return any(lessThanEqual(maxBB, vec3(-1f, -1f, 0f))) || any(lessThanEqual(vec3(1f, 1f, 1f), minBB));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCulledByHiz() {
|
bool isCulledByHiz() {
|
||||||
|
if (minBB.z < 0) {//Minpoint is behind the camera, its always going to pass
|
||||||
|
return false;
|
||||||
|
}
|
||||||
vec2 ssize = size.xy * vec2(ivec2(screenW, screenH));
|
vec2 ssize = size.xy * vec2(ivec2(screenW, screenH));
|
||||||
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1)));
|
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1)));
|
||||||
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5;
|
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5;
|
||||||
@@ -66,5 +77,6 @@ bool isCulledByHiz() {
|
|||||||
|
|
||||||
//Returns if we should decend into its children or not
|
//Returns if we should decend into its children or not
|
||||||
bool shouldDecend() {
|
bool shouldDecend() {
|
||||||
return (size.x*size.y) > (64*64F);
|
//printf("Screen area %f: %f, %f", (size.x*size.y*float(screenW)*float(screenH)), float(screenW), float(screenH));
|
||||||
|
return (size.x*size.y*screenW*screenH) > (64*64F);
|
||||||
}
|
}
|
||||||
@@ -77,8 +77,8 @@ layout(binding = 2, std430) restrict buffer QueueData {
|
|||||||
|
|
||||||
|
|
||||||
void addRequest(inout UnpackedNode node) {
|
void addRequest(inout UnpackedNode node) {
|
||||||
printf("requested");
|
|
||||||
if (!hasRequested(node)) {
|
if (!hasRequested(node)) {
|
||||||
|
printf("requested");
|
||||||
//TODO: maybe try using only 1 variable and it being <0 being bad
|
//TODO: maybe try using only 1 variable and it being <0 being bad
|
||||||
if (requestQueueIndex < requestQueueMaxSize) {
|
if (requestQueueIndex < requestQueueMaxSize) {
|
||||||
//Mark node as having a request submitted to prevent duplicate submissions
|
//Mark node as having a request submitted to prevent duplicate submissions
|
||||||
@@ -113,7 +113,7 @@ void main() {
|
|||||||
|
|
||||||
//debugDumpNode(node);
|
//debugDumpNode(node);
|
||||||
|
|
||||||
if (isCulledByHiz()) {
|
if (outsideFrustum() || isCulledByHiz()) {
|
||||||
//printf("HizCulled");
|
//printf("HizCulled");
|
||||||
//We are done here, dont do any more, the issue is the shader barriers maybe
|
//We are done here, dont do any more, the issue is the shader barriers maybe
|
||||||
// its culled, maybe just mark it as culled?
|
// its culled, maybe just mark it as culled?
|
||||||
|
|||||||
Reference in New Issue
Block a user