diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index c19881fc..90168f4e 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -2111,6 +2111,7 @@ Fix physics performance issues (06/04/2025) ServerGroundMovementTree actually moves collidable-based entities Client uses non-rigid-body collidables for farther away entities (via client LOD tree) +Reorder main content draw calls to support non-OIT transparencies better diff --git a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java index a593b7c1..87385d1b 100644 --- a/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/MainContentPipeline.java @@ -95,50 +95,10 @@ public class MainContentPipeline implements RenderPipeline { Vector3d positionVec = new Vector3d(); Vector3d scaleVec = new Vector3d(); Vector3d cameraCenterVec = CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera); - for(Entity currentEntity : this.standardDrawCall){ - Vector3d position = EntityUtils.getPosition(currentEntity); - if( - currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)!=null - ){ - //fetch actor - Actor currentActor = EntityUtils.getActor(currentEntity); - //calculate camera-modified vector3d - Vector3d cameraCenter = scaleVec.set(cameraCenterVec); - Vector3d cameraModifiedPosition = positionVec.set(position).sub(cameraCenter); - //calculate and apply model transform - modelTransformMatrix = modelTransformMatrix.identity(); - modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); - modelTransformMatrix.scale(scaleVec.set(EntityUtils.getScale(currentEntity))); - currentActor.applySpatialData(modelTransformMatrix,position); - //draw - currentActor.draw(renderPipelineState,openGLState); - //tracking - if(currentEntity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN)){ - this.terrainChunks++; - } - } - } + // + //Draw terrain (guarantees partial transparencies have terrain behind them at least) renderPipelineState.setUseBones(false); - for(ModelAccumulatorData accumulator : this.drawTargetAccumulator.getCalls()){ - Model model = Globals.assetManager.fetchModel(accumulator.getModelPath()); - if(model != null){ - int count = accumulator.getCount(); - List transforms = accumulator.getTransforms(); - List positions = accumulator.getPositions(); - model.setMeshMask(null); - for(int meshIndex = 0; meshIndex < model.getMeshCount(); meshIndex++){ - for(int i = 0; i < count; i++){ - Vector3d position = positions.get(i); - Matrix4d transform = transforms.get(i); - model.setWorldPos(position); - model.setModelMatrix(transform); - model.drawMesh(renderPipelineState, openGLState, meshIndex); - } - } - } - } for(Entity currentEntity : this.drawTargetAccumulator.getTerrainEntities()){ Vector3d position = EntityUtils.getPosition(currentEntity); if( @@ -186,6 +146,57 @@ public class MainContentPipeline implements RenderPipeline { } } renderPipelineState.setUseBones(true); + + // + //draw main models + for(Entity currentEntity : this.standardDrawCall){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)!=null + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + //calculate camera-modified vector3d + Vector3d cameraCenter = scaleVec.set(cameraCenterVec); + Vector3d cameraModifiedPosition = positionVec.set(position).sub(cameraCenter); + //calculate and apply model transform + modelTransformMatrix = modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(scaleVec.set(EntityUtils.getScale(currentEntity))); + currentActor.applySpatialData(modelTransformMatrix,position); + //draw + currentActor.draw(renderPipelineState,openGLState); + + //tracking + if(currentEntity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN)){ + this.terrainChunks++; + } + } + } + + // + //draw low-LOD non-terrain models + renderPipelineState.setUseBones(false); + for(ModelAccumulatorData accumulator : this.drawTargetAccumulator.getCalls()){ + Model model = Globals.assetManager.fetchModel(accumulator.getModelPath()); + if(model != null){ + int count = accumulator.getCount(); + List transforms = accumulator.getTransforms(); + List positions = accumulator.getPositions(); + model.setMeshMask(null); + for(int meshIndex = 0; meshIndex < model.getMeshCount(); meshIndex++){ + for(int i = 0; i < count; i++){ + Vector3d position = positions.get(i); + Matrix4d transform = transforms.get(i); + model.setWorldPos(position); + model.setModelMatrix(transform); + model.drawMesh(renderPipelineState, openGLState, meshIndex); + } + } + } + } + renderPipelineState.setUseBones(true); Globals.profiler.endCpuSample(); Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids Foliage"); Globals.renderingEngine.getFoliagePipeline().render(openGLState, renderPipelineState);