mojira.dev
MC-219893

Lava fog effect is still applied to spectators

While to a much lesser extent as of the latest snapshot due to the fixing of MC-71530, it still poses slightly problematic with visibility at high distances. Spectator players aren't supposed to be impaired visually by the game like survival players are, so the fog here probably shouldn't exist in this case.

Code Analysis:

Code analysis by @unknown can be found in this comment.

Linked issues

Attachments

Comments

migrated

Can confirm.

Avoma

Video attached.

Avoma

Can confirm in 21w13a.

Avoma

Can confirm in 21w14a.

Avoma

Can confirm in 21w15a.

Avoma

Can confirm in 21w17a.

Avoma

Can confirm in 1.17.1.

ampolive

Can confirm in 1.18 Pre-release 4.

migrated

Can confirm in 1.18 release candidate 1

Avoma

Can confirm in 1.18.1.

Avoma

Can confirm in 1.18.2.

Avoma

Can confirm in 1.19.2.

Apollo30

Code Analysis:

The following is based on a decompiled version of Minecraft 1.20.1 using MCP-Reborn.

net.minecraft.client.Camera.java // Original

public class Camera {
    ...
    public FogType getFluidInCamera() {
            if (!this.initialized) {
                return FogType.NONE;
            } else {
                FluidState fluidstate = this.level.getFluidState(this.blockPosition);
                if (fluidstate.is(FluidTags.WATER) && this.position.y < (double)((float) this.blockPosition.getY() + fluidstate.getHeight(this.level, this.blockPosition))) {
                    return FogType.WATER;
                } else {
                    Camera.NearPlane camera$nearplane = this.getNearPlane();                    for (Vec3 vec3: Arrays.asList(camera$nearplane.forward, camera$nearplane.getTopLeft(), camera$nearplane.getTopRight(), camera$nearplane.getBottomLeft(), camera$nearplane.getBottomRight())) {
                        Vec3 vec31 = this.position.add(vec3);
                        BlockPos blockpos = BlockPos.containing(vec31);
                        FluidState fluidstate1 = this.level.getFluidState(blockpos);
                        if (fluidstate1.is(FluidTags.LAVA)) {
                            if (vec31.y <= (double)(fluidstate1.getHeight(this.level, blockpos) + (float) blockpos.getY())) {
                                return FogType.LAVA;
                            }
                        } else {
                            BlockState blockstate = this.level.getBlockState(blockpos);
                            if (blockstate.is(Blocks.POWDER_SNOW)) {
                                return FogType.POWDER_SNOW;
                            }
                        }
                    }                    return FogType.NONE;
                }
            }
        }
        ...
}

As we can see, this is the method that determines which fog to product to an entity's camera. As a result of this inspection, we can see that there is no conditions to determine whether a player is in spectator or not.

Fix:

net.minecraft.client.Camera.java // Updated

public class Camera {
    ...
    public FogType getFluidInCamera() {
            if (!this.initialized || (this.entity instanceof Player player) && player.isSpectator()) {
                return FogType.NONE;
            } else {
                FluidState fluidstate = this.level.getFluidState(this.blockPosition);
                if (fluidstate.is(FluidTags.WATER) && this.position.y < (double)((float) this.blockPosition.getY() + fluidstate.getHeight(this.level, this.blockPosition))) {
                    return FogType.WATER;
                } else {
                    Camera.NearPlane camera$nearplane = this.getNearPlane();                    for (Vec3 vec3: Arrays.asList(camera$nearplane.forward, camera$nearplane.getTopLeft(), camera$nearplane.getTopRight(), camera$nearplane.getBottomLeft(), camera$nearplane.getBottomRight())) {
                        Vec3 vec31 = this.position.add(vec3);
                        BlockPos blockpos = BlockPos.containing(vec31);
                        FluidState fluidstate1 = this.level.getFluidState(blockpos);
                        if (fluidstate1.is(FluidTags.LAVA)) {
                            if (vec31.y <= (double)(fluidstate1.getHeight(this.level, blockpos) + (float) blockpos.getY())) {
                                return FogType.LAVA;
                            }
                        } else {
                            BlockState blockstate = this.level.getBlockState(blockpos);
                            if (blockstate.is(Blocks.POWDER_SNOW)) {
                                return FogType.POWDER_SNOW;
                            }
                        }
                    }                    return FogType.NONE;
                }
            }
        }
        ...
}

This fix removes any sort of fog whenever the player is in spectator. Giving spectators free reign to look around at anything without any disturbance.

muzikbike

(Unassigned)

Confirmed

Platform

Low

Rendering

spectator-visual-impairments

21w11a, 21w13a, 21w14a, 21w15a, 21w17a, ..., 23w14a, 1.20.1, 23w45a, 1.20.4, 1.21

Retrieved