use of net.coderbot.iris.shadows.CullingDataCache in project Iris by IrisShaders.
the class ShadowRenderer method renderShadows.
@Override
public void renderShadows(LevelRendererAccessor levelRenderer, Camera playerCamera) {
// vanilla ShaderInstances.
if (blendModeOverride != null) {
blendModeOverride.apply();
} else {
BlendModeOverride.restore();
}
Minecraft client = Minecraft.getInstance();
profiler.popPush("shadows");
ACTIVE = true;
// NB: We store the previous player buffers in order to be able to allow mods rendering entities in the shadow pass (Flywheel) to use the shadow buffers instead.
RenderBuffers playerBuffers = levelRenderer.getRenderBuffers();
levelRenderer.setRenderBuffers(buffers);
visibleBlockEntities = new ArrayList<>();
// Create our camera
PoseStack modelView = createShadowModelView(this.sunPathRotation, this.intervalSize);
MODELVIEW = modelView.last().pose().copy();
float[] projMatrix;
if (this.fov != null) {
// If FOV is not null, the pack wants a perspective based projection matrix. (This is to support legacy packs)
projMatrix = ShadowMatrices.createPerspectiveMatrix(this.fov);
} else {
projMatrix = ShadowMatrices.createOrthoMatrix(halfPlaneLength);
}
PROJECTION = new Matrix4f();
((Matrix4fAccess) (Object) PROJECTION).copyFromArray(projMatrix);
profiler.push("terrain_setup");
if (levelRenderer instanceof CullingDataCache) {
((CullingDataCache) levelRenderer).saveState();
}
profiler.push("initialize frustum");
terrainFrustumHolder = createShadowFrustum(renderDistanceMultiplier, terrainFrustumHolder);
// Determine the player camera position
Vector3d cameraPos = CameraUniforms.getUnshiftedCameraPosition();
double cameraX = cameraPos.x();
double cameraY = cameraPos.y();
double cameraZ = cameraPos.z();
// Center the frustum on the player camera position
terrainFrustumHolder.getFrustum().prepare(cameraX, cameraY, cameraZ);
profiler.pop();
// Disable chunk occlusion culling - it's a bit complex to get this properly working with shadow rendering
// as-is, however in the future it will be good to work on restoring it for a nice performance boost.
//
// TODO: Get chunk occlusion working with shadows
boolean wasChunkCullingEnabled = client.smartCull;
client.smartCull = false;
// Always schedule a terrain update
// TODO: Only schedule a terrain update if the sun / moon is moving, or the shadow map camera moved.
((LevelRenderer) levelRenderer).needsUpdate();
// Execute the vanilla terrain setup / culling routines using our shadow frustum.
levelRenderer.invokeSetupRender(playerCamera, terrainFrustumHolder.getFrustum(), false, levelRenderer.getFrameId(), false);
// Don't forget to increment the frame counter! This variable is arbitrary and only used in terrain setup,
// and if it's not incremented, the vanilla culling code will get confused and think that it's already seen
// chunks during traversal, and break rendering in concerning ways.
levelRenderer.setFrameId(levelRenderer.getFrameId() + 1);
client.smartCull = wasChunkCullingEnabled;
profiler.popPush("terrain");
pipeline.pushProgram(GbufferProgram.NONE);
pipeline.beginShadowRender();
setupGlState(projMatrix);
// Render all opaque terrain unless pack requests not to
if (shouldRenderTerrain) {
levelRenderer.invokeRenderChunkLayer(RenderType.solid(), modelView, cameraX, cameraY, cameraZ);
levelRenderer.invokeRenderChunkLayer(RenderType.cutout(), modelView, cameraX, cameraY, cameraZ);
levelRenderer.invokeRenderChunkLayer(RenderType.cutoutMipped(), modelView, cameraX, cameraY, cameraZ);
}
// Reset our shader program in case Sodium overrode it.
//
// If we forget to do this entities will be very small on most shaderpacks since they're being rendered
// without shaders, which doesn't integrate with their shadow distortion code.
setupShadowProgram();
profiler.popPush("entities");
// Get the current tick delta. Normally this is the same as client.getTickDelta(), but when the game is paused,
// it is set to a fixed value.
final float tickDelta = CapturedRenderingState.INSTANCE.getTickDelta();
// Create a constrained shadow frustum for entities to avoid rendering faraway entities in the shadow pass
// TODO: Make this configurable and disable-able
boolean hasEntityFrustum = false;
if (entityShadowDistanceMultiplier == 1.0F || entityShadowDistanceMultiplier < 0.0F) {
entityFrustumHolder.setInfo(terrainFrustumHolder.getFrustum(), terrainFrustumHolder.getDistanceInfo(), terrainFrustumHolder.getCullingInfo());
} else {
hasEntityFrustum = true;
entityFrustumHolder = createShadowFrustum(renderDistanceMultiplier * entityShadowDistanceMultiplier, entityFrustumHolder);
}
Frustum entityShadowFrustum = entityFrustumHolder.getFrustum();
entityShadowFrustum.prepare(cameraX, cameraY, cameraZ);
// rendering.
if (renderBuffersExt != null) {
renderBuffersExt.beginLevelRendering();
}
if (buffers instanceof DrawCallTrackingRenderBuffers) {
((DrawCallTrackingRenderBuffers) buffers).resetDrawCounts();
}
MultiBufferSource.BufferSource bufferSource = buffers.bufferSource();
if (shouldRenderEntities) {
renderEntities(levelRenderer, entityShadowFrustum, bufferSource, modelView, cameraX, cameraY, cameraZ, tickDelta);
}
if (shouldRenderBlockEntities) {
renderBlockEntities(bufferSource, modelView, cameraX, cameraY, cameraZ, tickDelta, hasEntityFrustum);
}
profiler.popPush("draw entities");
// NB: Don't try to draw the translucent parts of entities afterwards. It'll cause problems since some
// shader packs assume that everything drawn afterwards is actually translucent and should cast a colored
// shadow...
bufferSource.endBatch();
copyPreTranslucentDepth();
profiler.popPush("translucent terrain");
// Just something to watch out for, however...
if (shouldRenderTranslucent) {
levelRenderer.invokeRenderChunkLayer(RenderType.translucent(), modelView, cameraX, cameraY, cameraZ);
}
if (renderBuffersExt != null) {
renderBuffersExt.endLevelRendering();
}
debugStringTerrain = ((LevelRenderer) levelRenderer).getChunkStatistics();
profiler.popPush("generate mipmaps");
generateMipmaps();
profiler.popPush("restore gl state");
restoreGlState(client);
pipeline.endShadowRender();
// Note: This MUST happen before popProgram, otherwise we'll mess up the blend mode override of the program that
// is being restored.
BlendModeOverride.restore();
// Note: This unbinds the shadow framebuffer
pipeline.popProgram(GbufferProgram.NONE);
if (levelRenderer instanceof CullingDataCache) {
((CullingDataCache) levelRenderer).restoreState();
}
levelRenderer.setRenderBuffers(playerBuffers);
ACTIVE = false;
profiler.popPush("updatechunks");
}
Aggregations