clustering terrain draw calls
This commit is contained in:
parent
44ae9909ee
commit
7d04008197
Binary file not shown.
@ -1972,6 +1972,7 @@ Performance improvements
|
|||||||
- AI does not simulate for low-lod server entities
|
- AI does not simulate for low-lod server entities
|
||||||
- Nearby entity lookup caching per frame
|
- Nearby entity lookup caching per frame
|
||||||
- Far-away entities do not spawn physics by default
|
- Far-away entities do not spawn physics by default
|
||||||
|
- Clustering terrain draw calls
|
||||||
Lod emitter service checker function
|
Lod emitter service checker function
|
||||||
Mesh profiling
|
Mesh profiling
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ public class EntityDataStrings {
|
|||||||
Terrain Entity
|
Terrain Entity
|
||||||
*/
|
*/
|
||||||
public static final String TERRAIN_IS_TERRAIN = "terrainEntity";
|
public static final String TERRAIN_IS_TERRAIN = "terrainEntity";
|
||||||
|
public static final String BLOCK_ENTITY = "blockEntity";
|
||||||
public static final String CORRESPONDING_DRAW_CELL = "correspondingDrawCell";
|
public static final String CORRESPONDING_DRAW_CELL = "correspondingDrawCell";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -113,6 +113,7 @@ public class BlockChunkEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
solidsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
solidsEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
solidsEnt.putData(EntityDataStrings.BLOCK_ENTITY, true);
|
||||||
rVal.add(solidsEnt);
|
rVal.add(solidsEnt);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -165,6 +166,7 @@ public class BlockChunkEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
transparentEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
transparentEnt.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
transparentEnt.putData(EntityDataStrings.BLOCK_ENTITY, true);
|
||||||
rVal.add(transparentEnt);
|
rVal.add(transparentEnt);
|
||||||
|
|
||||||
|
|
||||||
@ -189,6 +191,7 @@ public class BlockChunkEntity {
|
|||||||
Quaterniond entityRot = EntityUtils.getRotation(entity);
|
Quaterniond entityRot = EntityUtils.getRotation(entity);
|
||||||
PhysicsUtils.setGeomTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainCollider);
|
PhysicsUtils.setGeomTransform(realm.getCollisionEngine(), entityPos, entityRot, terrainCollider);
|
||||||
entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
entity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
entity.putData(EntityDataStrings.BLOCK_ENTITY, true);
|
||||||
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
CommonEntityUtils.setEntityType(entity, EntityType.ENGINE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -163,4 +163,13 @@ public class TerrainChunk {
|
|||||||
return entity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN);
|
return entity.containsKey(EntityDataStrings.TERRAIN_IS_TERRAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this is a block entity
|
||||||
|
* @param entity The entity
|
||||||
|
* @return True if it is a block entity, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isBlockEntity(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.BLOCK_ENTITY);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,6 +139,52 @@ public class MainContentPipeline implements RenderPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(Entity currentEntity : this.drawTargetAccumulator.getTerrainEntities()){
|
||||||
|
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(new Matrix4d(modelTransformMatrix),new Vector3d(position));
|
||||||
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState,openGLState);
|
||||||
|
|
||||||
|
//tracking
|
||||||
|
this.terrainChunks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Entity currentEntity : this.drawTargetAccumulator.getBlockEntities()){
|
||||||
|
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(new Matrix4d(modelTransformMatrix),new Vector3d(position));
|
||||||
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState,openGLState);
|
||||||
|
|
||||||
|
//tracking
|
||||||
|
this.terrainChunks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
renderPipelineState.setUseBones(true);
|
renderPipelineState.setUseBones(true);
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids Foliage");
|
Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids Foliage");
|
||||||
|
|||||||
@ -164,6 +164,46 @@ public class ShadowMapPipeline implements RenderPipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for(Entity currentEntity : this.drawTargetAccumulator.getTerrainEntities()){
|
||||||
|
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(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
|
||||||
|
Vector3d cameraModifiedPosition = posVec.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(new Matrix4d(modelTransformMatrix),new Vector3d(position));
|
||||||
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState,openGLState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Entity currentEntity : this.drawTargetAccumulator.getBlockEntities()){
|
||||||
|
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(CameraEntityUtils.getCameraCenter(Globals.clientState.playerCamera));
|
||||||
|
Vector3d cameraModifiedPosition = posVec.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(new Matrix4d(modelTransformMatrix),new Vector3d(position));
|
||||||
|
//draw
|
||||||
|
currentActor.draw(renderPipelineState,openGLState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,12 +3,15 @@ package electrosphere.renderer.target;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accumulates non-spatially identical draw calls to batch to gpu
|
* Accumulates non-spatially identical draw calls to batch to gpu
|
||||||
*/
|
*/
|
||||||
@ -19,6 +22,16 @@ public class DrawTargetAccumulator {
|
|||||||
*/
|
*/
|
||||||
private Map<String,ModelAccumulatorData> modelPathAccumulatorMap = new HashMap<String,ModelAccumulatorData>();
|
private Map<String,ModelAccumulatorData> modelPathAccumulatorMap = new HashMap<String,ModelAccumulatorData>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups terrain entities
|
||||||
|
*/
|
||||||
|
private List<Entity> terrainEntities = new LinkedList<Entity>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups block entities
|
||||||
|
*/
|
||||||
|
private List<Entity> blockEntities = new LinkedList<Entity>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a call to draw a given model
|
* Adds a call to draw a given model
|
||||||
@ -37,6 +50,22 @@ public class DrawTargetAccumulator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a terrain entity
|
||||||
|
* @param entity The entity
|
||||||
|
*/
|
||||||
|
public void addTerrainCall(Entity entity){
|
||||||
|
this.terrainEntities.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a block entity
|
||||||
|
* @param entity The entity
|
||||||
|
*/
|
||||||
|
public void addBlockCall(Entity entity){
|
||||||
|
this.blockEntities.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the calls to make
|
* Gets the calls to make
|
||||||
* @return The calls to make
|
* @return The calls to make
|
||||||
@ -52,6 +81,24 @@ public class DrawTargetAccumulator {
|
|||||||
for(ModelAccumulatorData data : modelPathAccumulatorMap.values()){
|
for(ModelAccumulatorData data : modelPathAccumulatorMap.values()){
|
||||||
data.count = 0;
|
data.count = 0;
|
||||||
}
|
}
|
||||||
|
this.terrainEntities.clear();
|
||||||
|
this.blockEntities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of terrain entities
|
||||||
|
* @return The list of terrain entities
|
||||||
|
*/
|
||||||
|
public List<Entity> getTerrainEntities(){
|
||||||
|
return this.terrainEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of block entities
|
||||||
|
* @return The list of block entities
|
||||||
|
*/
|
||||||
|
public List<Entity> getBlockEntities(){
|
||||||
|
return this.blockEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import electrosphere.entity.DrawableUtils;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.types.terrain.TerrainChunk;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.pipelines.MainContentPipeline;
|
import electrosphere.renderer.pipelines.MainContentPipeline;
|
||||||
import electrosphere.renderer.pipelines.NormalsForOutlinePipeline;
|
import electrosphere.renderer.pipelines.NormalsForOutlinePipeline;
|
||||||
@ -112,6 +113,26 @@ public class DrawTargetEvaluator {
|
|||||||
normalAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
|
normalAccumulator.addCall(currentActor.getModelPath(), position, modelTransformMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if(TerrainChunk.isBlockEntity(currentEntity)){
|
||||||
|
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
|
||||||
|
mainAccumulator.addBlockCall(currentEntity);
|
||||||
|
}
|
||||||
|
if(dist < ShadowMapPipeline.DRAW_CUTOFF_DIST && shadowList.contains(currentEntity)){
|
||||||
|
shadowAccumulator.addBlockCall(currentEntity);
|
||||||
|
}
|
||||||
|
if(dist < NormalsForOutlinePipeline.DRAW_CUTOFF_DIST && NormalsForOutlinePipeline.shouldDraw(currentEntity)){
|
||||||
|
normalAccumulator.addBlockCall(currentEntity);
|
||||||
|
}
|
||||||
|
} else if(TerrainChunk.isTerrainEntity(currentEntity)) {
|
||||||
|
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
|
||||||
|
mainAccumulator.addTerrainCall(currentEntity);
|
||||||
|
}
|
||||||
|
if(dist < ShadowMapPipeline.DRAW_CUTOFF_DIST && shadowList.contains(currentEntity)){
|
||||||
|
shadowAccumulator.addTerrainCall(currentEntity);
|
||||||
|
}
|
||||||
|
if(dist < NormalsForOutlinePipeline.DRAW_CUTOFF_DIST && NormalsForOutlinePipeline.shouldDraw(currentEntity)){
|
||||||
|
normalAccumulator.addTerrainCall(currentEntity);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
|
if(MainContentPipeline.shouldDrawSolidPass(currentEntity)){
|
||||||
mainQueue.add(currentEntity);
|
mainQueue.add(currentEntity);
|
||||||
|
|||||||
@ -103,6 +103,7 @@ public class PhysicsDataCell {
|
|||||||
this.blockData = BlockMeshgen.rasterize(this.blockChunk);
|
this.blockData = BlockMeshgen.rasterize(this.blockChunk);
|
||||||
BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData);
|
BlockChunkEntity.serverCreateBlockChunkEntity(localBlockPhysicsEntity, this.blockData);
|
||||||
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
localBlockPhysicsEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
|
||||||
|
localBlockPhysicsEntity.putData(EntityDataStrings.BLOCK_ENTITY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user