Disable projection when occluded.

This commit is contained in:
Florian Nücke
2022-02-02 01:33:16 +01:00
parent 05c2f43abd
commit ee232dc049
4 changed files with 18 additions and 11 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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<RenderTarget> cir) {
if (ProjectorDepthRenderer.isIsRenderingProjectorDepth()) {
cir.setReturnValue(Minecraft.getInstance().getMainRenderTarget());

View File

@@ -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;
}