2025-11-24 22:52:51 +03:00

179 lines
8.9 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.google.common.collect.Lists
* org.joml.Vector4f
* org.joml.Vector4fc
* org.lwjgl.system.MemoryStack
*/
package net.minecraft.client.renderer.fog;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import com.mojang.blaze3d.buffers.Std140Builder;
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
import com.mojang.blaze3d.systems.GpuDevice;
import com.mojang.blaze3d.systems.RenderSystem;
import java.nio.ByteBuffer;
import java.util.List;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.MappableRingBuffer;
import net.minecraft.client.renderer.fog.FogData;
import net.minecraft.client.renderer.fog.environment.AtmosphericFogEnvironment;
import net.minecraft.client.renderer.fog.environment.BlindnessFogEnvironment;
import net.minecraft.client.renderer.fog.environment.DarknessFogEnvironment;
import net.minecraft.client.renderer.fog.environment.FogEnvironment;
import net.minecraft.client.renderer.fog.environment.LavaFogEnvironment;
import net.minecraft.client.renderer.fog.environment.PowderedSnowFogEnvironment;
import net.minecraft.client.renderer.fog.environment.WaterFogEnvironment;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.material.FogType;
import org.joml.Vector4f;
import org.joml.Vector4fc;
import org.lwjgl.system.MemoryStack;
public class FogRenderer
implements AutoCloseable {
public static final int FOG_UBO_SIZE = new Std140SizeCalculator().putVec4().putFloat().putFloat().putFloat().putFloat().putFloat().putFloat().get();
private static final List<FogEnvironment> FOG_ENVIRONMENTS = Lists.newArrayList((Object[])new FogEnvironment[]{new LavaFogEnvironment(), new PowderedSnowFogEnvironment(), new BlindnessFogEnvironment(), new DarknessFogEnvironment(), new WaterFogEnvironment(), new AtmosphericFogEnvironment()});
private static boolean fogEnabled = true;
private final GpuBuffer emptyBuffer;
private final MappableRingBuffer regularBuffer;
public FogRenderer() {
GpuDevice device = RenderSystem.getDevice();
this.regularBuffer = new MappableRingBuffer(() -> "Fog UBO", 130, FOG_UBO_SIZE);
try (MemoryStack stack = MemoryStack.stackPush();){
ByteBuffer buffer = stack.malloc(FOG_UBO_SIZE);
this.updateBuffer(buffer, 0, new Vector4f(0.0f), Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
this.emptyBuffer = device.createBuffer(() -> "Empty fog", 128, buffer.flip());
}
RenderSystem.setShaderFog(this.getBuffer(FogMode.NONE));
}
@Override
public void close() {
this.emptyBuffer.close();
this.regularBuffer.close();
}
public void endFrame() {
this.regularBuffer.rotate();
}
public GpuBufferSlice getBuffer(FogMode mode) {
if (!fogEnabled) {
return this.emptyBuffer.slice(0, FOG_UBO_SIZE);
}
return switch (mode.ordinal()) {
default -> throw new MatchException(null, null);
case 0 -> this.emptyBuffer.slice(0, FOG_UBO_SIZE);
case 1 -> this.regularBuffer.currentBuffer().slice(0, FOG_UBO_SIZE);
};
}
private Vector4f computeFogColor(Camera camera, float partialTicks, ClientLevel level, int renderDistance, float darkenWorldAmount) {
LivingEntity livingEntity;
FogType fogType = this.getFogType(camera);
Entity entity = camera.entity();
FogEnvironment colorSourceEnvironment = null;
FogEnvironment darknessModifyingEnvironment = null;
for (FogEnvironment fogEnvironment : FOG_ENVIRONMENTS) {
if (!fogEnvironment.isApplicable(fogType, entity)) continue;
if (colorSourceEnvironment == null && fogEnvironment.providesColor()) {
colorSourceEnvironment = fogEnvironment;
}
if (darknessModifyingEnvironment != null || !fogEnvironment.modifiesDarkness()) continue;
darknessModifyingEnvironment = fogEnvironment;
}
if (colorSourceEnvironment == null) {
throw new IllegalStateException("No color source environment found");
}
int color = colorSourceEnvironment.getBaseColor(level, camera, renderDistance, partialTicks);
float voidDarknessOnsetRange = level.getLevelData().voidDarknessOnsetRange();
float darkness = Mth.clamp((voidDarknessOnsetRange + (float)level.getMinY() - (float)camera.position().y) / voidDarknessOnsetRange, 0.0f, 1.0f);
if (darknessModifyingEnvironment != null) {
LivingEntity livingEntity2 = (LivingEntity)entity;
darkness = darknessModifyingEnvironment.getModifiedDarkness(livingEntity2, darkness, partialTicks);
}
float fogRed = ARGB.redFloat(color);
float fogGreen = ARGB.greenFloat(color);
float fogBlue = ARGB.blueFloat(color);
if (darkness > 0.0f && fogType != FogType.LAVA && fogType != FogType.POWDER_SNOW) {
float brightness = Mth.square(1.0f - darkness);
fogRed *= brightness;
fogGreen *= brightness;
fogBlue *= brightness;
}
if (darkenWorldAmount > 0.0f) {
fogRed = Mth.lerp(darkenWorldAmount, fogRed, fogRed * 0.7f);
fogGreen = Mth.lerp(darkenWorldAmount, fogGreen, fogGreen * 0.6f);
fogBlue = Mth.lerp(darkenWorldAmount, fogBlue, fogBlue * 0.6f);
}
float brightenFactor = fogType == FogType.WATER ? (entity instanceof LocalPlayer ? ((LocalPlayer)entity).getWaterVision() : 1.0f) : (entity instanceof LivingEntity && (livingEntity = (LivingEntity)entity).hasEffect(MobEffects.NIGHT_VISION) && !livingEntity.hasEffect(MobEffects.DARKNESS) ? GameRenderer.getNightVisionScale(livingEntity, partialTicks) : 0.0f);
if (fogRed != 0.0f && fogGreen != 0.0f && fogBlue != 0.0f) {
float targetScale = 1.0f / Math.max(fogRed, Math.max(fogGreen, fogBlue));
fogRed = Mth.lerp(brightenFactor, fogRed, fogRed * targetScale);
fogGreen = Mth.lerp(brightenFactor, fogGreen, fogGreen * targetScale);
fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * targetScale);
}
return new Vector4f(fogRed, fogGreen, fogBlue, 1.0f);
}
public static boolean toggleFog() {
fogEnabled = !fogEnabled;
return fogEnabled;
}
public Vector4f setupFog(Camera camera, int renderDistanceInChunks, DeltaTracker deltaTracker, float darkenWorldAmount, ClientLevel level) {
float partialTickTime = deltaTracker.getGameTimeDeltaPartialTick(false);
Vector4f fogColor = this.computeFogColor(camera, partialTickTime, level, renderDistanceInChunks, darkenWorldAmount);
float renderDistanceInBlocks = renderDistanceInChunks * 16;
FogType fogType = this.getFogType(camera);
Entity entity = camera.entity();
FogData fog = new FogData();
for (FogEnvironment fogEnvironment : FOG_ENVIRONMENTS) {
if (!fogEnvironment.isApplicable(fogType, entity)) continue;
fogEnvironment.setupFog(fog, camera, level, renderDistanceInBlocks, deltaTracker);
break;
}
float renderDistanceFogSpan = Mth.clamp(renderDistanceInBlocks / 10.0f, 4.0f, 64.0f);
fog.renderDistanceStart = renderDistanceInBlocks - renderDistanceFogSpan;
fog.renderDistanceEnd = renderDistanceInBlocks;
try (GpuBuffer.MappedView view = RenderSystem.getDevice().createCommandEncoder().mapBuffer(this.regularBuffer.currentBuffer(), false, true);){
this.updateBuffer(view.data(), 0, fogColor, fog.environmentalStart, fog.environmentalEnd, fog.renderDistanceStart, fog.renderDistanceEnd, fog.skyEnd, fog.cloudEnd);
}
return fogColor;
}
private FogType getFogType(Camera camera) {
FogType blockFogType = camera.getFluidInCamera();
if (blockFogType == FogType.NONE) {
return FogType.ATMOSPHERIC;
}
return blockFogType;
}
private void updateBuffer(ByteBuffer byteBuffer, int offset, Vector4f fogColor, float environmentalStart, float environmentalEnd, float renderDistanceStart, float renderDistanceEnd, float skyEnd, float endClouds) {
byteBuffer.position(offset);
Std140Builder.intoBuffer(byteBuffer).putVec4((Vector4fc)fogColor).putFloat(environmentalStart).putFloat(environmentalEnd).putFloat(renderDistanceStart).putFloat(renderDistanceEnd).putFloat(skyEnd).putFloat(endClouds);
}
public static enum FogMode {
NONE,
WORLD;
}
}