From ee232dc049ce836d2f785803b5057d686048019a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Wed, 2 Feb 2022 01:33:16 +0100 Subject: [PATCH] Disable projection when occluded. --- .../client/renderer/ProjectorDepthRenderer.java | 2 +- .../common/blockentity/ProjectorBlockEntity.java | 16 +++++++++++++++- .../cil/oc2/common/mixin/LevelRendererMixin.java | 2 +- .../assets/oc2/shaders/core/projectors.fsh | 9 +-------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/li/cil/oc2/client/renderer/ProjectorDepthRenderer.java b/src/main/java/li/cil/oc2/client/renderer/ProjectorDepthRenderer.java index d5a4b4ef..2a2134f1 100644 --- a/src/main/java/li/cil/oc2/client/renderer/ProjectorDepthRenderer.java +++ b/src/main/java/li/cil/oc2/client/renderer/ProjectorDepthRenderer.java @@ -66,7 +66,7 @@ public final class ProjectorDepthRenderer { private static final Camera PROJECTOR_DEPTH_CAMERA = new Camera(); private static final DepthOnlyRenderTarget MAIN_CAMERA_DEPTH = new DepthOnlyRenderTarget(MainTarget.DEFAULT_WIDTH, MainTarget.DEFAULT_HEIGHT); private static final float PROJECTOR_FORWARD_SHIFT = 7 / 16f; // From center of projector block. - private static final float PROJECTOR_NEAR = 0.5f - PROJECTOR_FORWARD_SHIFT - 0.5f / 16f; // Not quite forward edge, to allow occluding with neighboring block. + private static final float PROJECTOR_NEAR = 0.5f - PROJECTOR_FORWARD_SHIFT; private static final float PROJECTOR_FAR = ProjectorBlockEntity.MAX_RENDER_DISTANCE; private static final int HALF_FRUSTUM_WIDTH = (ProjectorBlockEntity.MAX_WIDTH - 1) / 2; private static final int FRUSTUM_HEIGHT = ProjectorBlockEntity.MAX_HEIGHT - 1; diff --git a/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java b/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java index 35297ab2..8be564b5 100644 --- a/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java +++ b/src/main/java/li/cil/oc2/common/blockentity/ProjectorBlockEntity.java @@ -15,6 +15,7 @@ import li.cil.oc2.jcodec.common.model.ColorSpace; import li.cil.oc2.jcodec.common.model.Picture; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunk; @@ -103,7 +104,20 @@ public final class ProjectorBlockEntity extends ModBlockEntity implements Tickab } public boolean isProjecting() { - return isProjecting; + if (!isProjecting || level == null) { + return false; + } + + final Direction facing = getBlockState().getValue(ProjectorBlock.FACING); + final BlockPos neighborPos = getBlockPos().relative(facing); + final int neighborChunkX = SectionPos.blockToSectionCoord(neighborPos.getX()); + final int neighborChunkZ = SectionPos.blockToSectionCoord(neighborPos.getZ()); + if (!level.hasChunk(neighborChunkX, neighborChunkZ)) { + return false; + } + + final BlockState neighborBlockState = level.getBlockState(neighborPos); + return !neighborBlockState.isSolidRender(level, neighborPos); } public void setProjecting(final boolean value) { diff --git a/src/main/java/li/cil/oc2/common/mixin/LevelRendererMixin.java b/src/main/java/li/cil/oc2/common/mixin/LevelRendererMixin.java index 88913833..6c54789b 100644 --- a/src/main/java/li/cil/oc2/common/mixin/LevelRendererMixin.java +++ b/src/main/java/li/cil/oc2/common/mixin/LevelRendererMixin.java @@ -136,7 +136,7 @@ public abstract class LevelRendererMixin { } } - @Inject(method = {"entityTarget", "getItemEntityTarget"}, at = @At("HEAD"), cancellable = true) + @Inject(method = {"entityTarget", "getItemEntityTarget", "getWeatherTarget"}, at = @At("HEAD"), cancellable = true) private void redirectToMainTarget(final CallbackInfoReturnable cir) { if (ProjectorDepthRenderer.isIsRenderingProjectorDepth()) { cir.setReturnValue(Minecraft.getInstance().getMainRenderTarget()); diff --git a/src/main/resources/assets/oc2/shaders/core/projectors.fsh b/src/main/resources/assets/oc2/shaders/core/projectors.fsh index 65d30769..0cba6dde 100644 --- a/src/main/resources/assets/oc2/shaders/core/projectors.fsh +++ b/src/main/resources/assets/oc2/shaders/core/projectors.fsh @@ -60,10 +60,6 @@ bool isInClipBounds(vec3 v) { v.z >= -1 && v.z <= 1; } -float toLinearDepth(float depth, float zNear, float zFar) { - return zNear * zFar / (zFar + depth * (zNear - zFar)); -} - bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, sampler2D projectorColorSampler, sampler2D projectorDepthSampler, out vec4 result) { @@ -78,9 +74,6 @@ bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, vec4 projectorClipPosPrediv = projectorCamera * vec4(worldPos, 1); float linearDepth = projectorClipPosPrediv.z; - if (linearDepth >= MAX_DISTANCE) { - return false; - } vec3 projectorClipPos = projectorClipPosPrediv.xyz / projectorClipPosPrediv.w; if (!isInClipBounds(projectorClipPos)) { @@ -105,7 +98,7 @@ bool getProjectorColor(vec3 worldPos, vec3 worldNormal, mat4 projectorCamera, void main() { float depth = texture2D(Sampler0, texCoord).r; - // Check for no hit, e.g. sky, for early exit. + // Check for no hit, for early exit. if (depth >= 1) { discard; }