rearch foliage rendering into dedicated pipeline
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
3b0e39d169
commit
6d2b4bf318
@ -1336,6 +1336,7 @@ Normalized mouse pos lookup function
|
||||
(03/27/2025)
|
||||
Disable fluid sim for performance
|
||||
Increase fall delay
|
||||
Rearchitect foliage rendering to combat grass pop-in/pop-out
|
||||
|
||||
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import org.joml.Vector3i;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* Manages ambient foliage (grass, small plants, etc) that should be shown, typically instanced
|
||||
*/
|
||||
|
||||
@ -35,6 +35,7 @@ import electrosphere.renderer.buffer.ShaderAttribute;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* Contains a set of foliage entities and groups them together.
|
||||
*/
|
||||
|
||||
@ -13,6 +13,7 @@ import electrosphere.util.ds.octree.ChunkTree;
|
||||
import electrosphere.util.ds.octree.ChunkTree.ChunkTreeNode;
|
||||
import electrosphere.util.math.GeomUtils;
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* A whole chunk of foliage
|
||||
*/
|
||||
|
||||
@ -8,21 +8,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.actor.instance.TextureInstancedActor;
|
||||
import electrosphere.renderer.buffer.HomogenousUniformBuffer.HomogenousBufferTypes;
|
||||
import electrosphere.renderer.buffer.ShaderAttribute;
|
||||
import electrosphere.renderer.meshgen.TransvoxelModelGeneration.TransvoxelChunkData;
|
||||
@ -468,51 +461,6 @@ public class FoliageCell {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all entities in the foliage cell
|
||||
*/
|
||||
protected void draw(){
|
||||
if(this.modelEntity != null){
|
||||
Matrix4d modelMatrix = new Matrix4d();
|
||||
Vector3d cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||||
|
||||
RenderPipelineState renderPipelineState = Globals.renderingEngine.getRenderPipelineState();
|
||||
OpenGLState openGLState = Globals.renderingEngine.getOpenGLState();
|
||||
|
||||
Vector3d realPosition = this.getRealPos();
|
||||
Vector3d cameraModifiedPosition = new Vector3d(realPosition).sub(cameraCenter);
|
||||
//frustum check entire cell
|
||||
int size = (int)Math.pow(2,this.lod);
|
||||
boolean shouldRender = renderPipelineState.getFrustumIntersection().testSphere(
|
||||
(float)(cameraModifiedPosition.x + size / 2.0),
|
||||
(float)(cameraModifiedPosition.y + size / 2.0),
|
||||
(float)(cameraModifiedPosition.z + size / 2.0),
|
||||
(float)(size)
|
||||
);
|
||||
if(shouldRender){
|
||||
//disable frustum check and instead perform at cell level
|
||||
boolean currentFrustumCheckState = renderPipelineState.shouldFrustumCheck();
|
||||
renderPipelineState.setFrustumCheck(false);
|
||||
Vector3d grassPosition = EntityUtils.getPosition(modelEntity);
|
||||
Quaterniond grassRotation = EntityUtils.getRotation(modelEntity);
|
||||
TextureInstancedActor actor = TextureInstancedActor.getTextureInstancedActor(modelEntity);
|
||||
|
||||
if(actor != null){
|
||||
modelMatrix = modelMatrix.identity();
|
||||
modelMatrix.translate(cameraModifiedPosition);
|
||||
modelMatrix.rotate(new Quaterniond(grassRotation));
|
||||
modelMatrix.scale(new Vector3d(EntityUtils.getScale(modelEntity)));
|
||||
actor.applySpatialData(modelMatrix,grassPosition);
|
||||
|
||||
|
||||
//draw
|
||||
actor.draw(renderPipelineState, openGLState);
|
||||
renderPipelineState.setFrustumCheck(currentFrustumCheckState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the real-space position of the foliage cell
|
||||
* @return the real-space position
|
||||
|
||||
@ -319,26 +319,6 @@ public class FoliageCellManager {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw all foliage cells
|
||||
*/
|
||||
public void draw(){
|
||||
this.recursivelyDraw(this.chunkTree.getRoot());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws all foliage cells recursively
|
||||
* @param node The current node
|
||||
*/
|
||||
private void recursivelyDraw(WorldOctTreeNode<FoliageCell> node){
|
||||
if(node.getChildren() != null && node.getChildren().size() > 0){
|
||||
for(int i = 0; i < 8; i++){
|
||||
this.recursivelyDraw(node.getChildren().get(i));
|
||||
}
|
||||
}
|
||||
node.getData().draw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum distance from a node to a point
|
||||
* @param pos the position to check against
|
||||
|
||||
@ -19,6 +19,7 @@ import electrosphere.engine.assetmanager.queue.QueuedTexture.QueuedTextureType;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.state.foliage.AmbientFoliage;
|
||||
import electrosphere.game.data.foliage.type.FoliageType;
|
||||
@ -223,6 +224,7 @@ public class FoliageModel {
|
||||
EntityUtils.getScale(rVal).set(1,1,1);
|
||||
//add ambient foliage behavior tree
|
||||
AmbientFoliage.attachAmbientFoliageTree(rVal, 1.0f, foliageType.getGrowthModel().getGrowthRate());
|
||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.DRAW_FOLIAGE_PASS);
|
||||
}
|
||||
if(toDelete != null){
|
||||
ClientEntityUtils.destroyEntity(toDelete);
|
||||
|
||||
@ -28,5 +28,6 @@ public class EntityTags {
|
||||
public static final String DRAW_CAST_SHADOW = "drawCastShadow";
|
||||
public static final String DRAW_VOLUMETIC_DEPTH_PASS = "drawVolumetricDepthPass"; //draw in the volumetic phase of the volumetric pass
|
||||
public static final String DRAW_VOLUMETIC_SOLIDS_PASS = "drawVolumetricSolidsPass"; //draw in the non-volumetic phase of the volumetric pass
|
||||
public static final String DRAW_FOLIAGE_PASS = "drawFoliagePass"; //draw in the foliage pass
|
||||
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ import electrosphere.renderer.framebuffer.Renderbuffer;
|
||||
import electrosphere.renderer.light.LightManager;
|
||||
import electrosphere.renderer.pipelines.CompositePipeline;
|
||||
import electrosphere.renderer.pipelines.FirstPersonItemsPipeline;
|
||||
import electrosphere.renderer.pipelines.FoliagePipeline;
|
||||
import electrosphere.renderer.pipelines.ImGuiPipeline;
|
||||
import electrosphere.renderer.pipelines.MainContentNoOITPipeline;
|
||||
import electrosphere.renderer.pipelines.MainContentPipeline;
|
||||
@ -169,6 +170,7 @@ public class RenderingEngine {
|
||||
ShadowMapPipeline shadowMapPipeline = new ShadowMapPipeline();
|
||||
VolumeBufferPipeline volumeBufferPipeline = new VolumeBufferPipeline();
|
||||
NormalsForOutlinePipeline normalsForOutlinePipeline = new NormalsForOutlinePipeline();
|
||||
FoliagePipeline foliagePipeline = new FoliagePipeline();
|
||||
OutlineNormalsPipeline outlineNormalsPipeline = new OutlineNormalsPipeline();
|
||||
CompositePipeline compositePipeline = new CompositePipeline();
|
||||
PostProcessingPipeline postProcessingPipeline = new PostProcessingPipeline();
|
||||
@ -672,6 +674,14 @@ public class RenderingEngine {
|
||||
return this.postProcessingPipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the foliage pipeline
|
||||
* @return The foliage pipeline
|
||||
*/
|
||||
public FoliagePipeline getFoliagePipeline(){
|
||||
return foliagePipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current opengl state
|
||||
* @return
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package electrosphere.renderer.pipelines;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Sphered;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.actor.instance.TextureInstancedActor;
|
||||
|
||||
/**
|
||||
* Pipeline for rendering foliage
|
||||
*/
|
||||
public class FoliagePipeline implements RenderPipeline {
|
||||
|
||||
/**
|
||||
* Template bounding shere used for checking frustum for this cell
|
||||
*/
|
||||
static Sphered boundingSphere = new Sphered(0.5,0.5,0.5,8);
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Set<Entity> foliageEntities = Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_FOLIAGE_PASS);
|
||||
if(foliageEntities != null){
|
||||
for(Entity foliageEntity : foliageEntities){
|
||||
Matrix4d modelMatrix = new Matrix4d();
|
||||
Vector3d cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||||
Vector3d realPosition = EntityUtils.getPosition(foliageEntity);
|
||||
|
||||
Vector3d cameraModifiedPosition = new Vector3d(realPosition).sub(cameraCenter);
|
||||
//frustum check entire cell
|
||||
boolean shouldRender = renderPipelineState.getFrustumIntersection().testSphere((float)(cameraModifiedPosition.x + boundingSphere.x), (float)(cameraModifiedPosition.y + boundingSphere.y), (float)(cameraModifiedPosition.z + boundingSphere.z), (float)(boundingSphere.r));
|
||||
if(shouldRender){
|
||||
//disable frustum check and instead perform at cell level
|
||||
boolean currentFrustumCheckState = renderPipelineState.shouldFrustumCheck();
|
||||
renderPipelineState.setFrustumCheck(false);
|
||||
Vector3d grassPosition = EntityUtils.getPosition(foliageEntity);
|
||||
Quaterniond grassRotation = EntityUtils.getRotation(foliageEntity);
|
||||
TextureInstancedActor actor = TextureInstancedActor.getTextureInstancedActor(foliageEntity);
|
||||
|
||||
|
||||
modelMatrix = modelMatrix.identity();
|
||||
modelMatrix.translate(cameraModifiedPosition);
|
||||
modelMatrix.rotate(new Quaterniond(grassRotation));
|
||||
modelMatrix.scale(new Vector3d(EntityUtils.getScale(foliageEntity)));
|
||||
actor.applySpatialData(modelMatrix,grassPosition);
|
||||
|
||||
|
||||
//draw
|
||||
actor.draw(renderPipelineState, openGLState);
|
||||
renderPipelineState.setFrustumCheck(currentFrustumCheckState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -86,7 +86,7 @@ public class MainContentPipeline implements RenderPipeline {
|
||||
currentActor.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
Globals.foliageCellManager.draw();
|
||||
Globals.renderingEngine.getFoliagePipeline().render(openGLState, renderPipelineState);
|
||||
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){
|
||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||
if(shouldDrawSolidPass(currentEntity)){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user