165 lines
7.5 KiB
Java
165 lines
7.5 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.joml.Vector3f
|
|
* org.joml.Vector3fc
|
|
*/
|
|
package net.minecraft.client.renderer;
|
|
|
|
import com.mojang.blaze3d.buffers.GpuBuffer;
|
|
import com.mojang.blaze3d.buffers.Std140Builder;
|
|
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
|
import com.mojang.blaze3d.systems.CommandEncoder;
|
|
import com.mojang.blaze3d.systems.GpuDevice;
|
|
import com.mojang.blaze3d.systems.RenderPass;
|
|
import com.mojang.blaze3d.systems.RenderSystem;
|
|
import com.mojang.blaze3d.textures.GpuTexture;
|
|
import com.mojang.blaze3d.textures.GpuTextureView;
|
|
import com.mojang.blaze3d.textures.TextureFormat;
|
|
import java.util.OptionalInt;
|
|
import net.minecraft.client.Camera;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.multiplayer.ClientLevel;
|
|
import net.minecraft.client.renderer.EndFlashState;
|
|
import net.minecraft.client.renderer.GameRenderer;
|
|
import net.minecraft.client.renderer.MappableRingBuffer;
|
|
import net.minecraft.client.renderer.RenderPipelines;
|
|
import net.minecraft.util.ARGB;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.profiling.Profiler;
|
|
import net.minecraft.util.profiling.ProfilerFiller;
|
|
import net.minecraft.world.attribute.EnvironmentAttributes;
|
|
import net.minecraft.world.effect.MobEffects;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.level.dimension.DimensionType;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3fc;
|
|
|
|
public class LightTexture
|
|
implements AutoCloseable {
|
|
public static final int FULL_BRIGHT = 0xF000F0;
|
|
public static final int FULL_SKY = 0xF00000;
|
|
public static final int FULL_BLOCK = 240;
|
|
private static final int TEXTURE_SIZE = 16;
|
|
private static final int LIGHTMAP_UBO_SIZE = new Std140SizeCalculator().putFloat().putFloat().putFloat().putFloat().putFloat().putFloat().putFloat().putVec3().putVec3().get();
|
|
private final GpuTexture texture;
|
|
private final GpuTextureView textureView;
|
|
private boolean updateLightTexture;
|
|
private float blockLightRedFlicker;
|
|
private final GameRenderer renderer;
|
|
private final Minecraft minecraft;
|
|
private final MappableRingBuffer ubo;
|
|
|
|
public LightTexture(GameRenderer renderer, Minecraft minecraft) {
|
|
this.renderer = renderer;
|
|
this.minecraft = minecraft;
|
|
GpuDevice device = RenderSystem.getDevice();
|
|
this.texture = device.createTexture("Light Texture", 12, TextureFormat.RGBA8, 16, 16, 1, 1);
|
|
this.textureView = device.createTextureView(this.texture);
|
|
device.createCommandEncoder().clearColorTexture(this.texture, -1);
|
|
this.ubo = new MappableRingBuffer(() -> "Lightmap UBO", 130, LIGHTMAP_UBO_SIZE);
|
|
}
|
|
|
|
public GpuTextureView getTextureView() {
|
|
return this.textureView;
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
this.texture.close();
|
|
this.textureView.close();
|
|
this.ubo.close();
|
|
}
|
|
|
|
public void tick() {
|
|
this.blockLightRedFlicker += (float)((Math.random() - Math.random()) * Math.random() * Math.random() * 0.1);
|
|
this.blockLightRedFlicker *= 0.9f;
|
|
this.updateLightTexture = true;
|
|
}
|
|
|
|
private float calculateDarknessScale(LivingEntity camera, float darknessGamma, float partialTickTime) {
|
|
float darkness = 0.45f * darknessGamma;
|
|
return Math.max(0.0f, Mth.cos(((float)camera.tickCount - partialTickTime) * (float)Math.PI * 0.025f) * darkness);
|
|
}
|
|
|
|
public void updateLightTexture(float partialTicks) {
|
|
Vector3f ambientColor;
|
|
if (!this.updateLightTexture) {
|
|
return;
|
|
}
|
|
this.updateLightTexture = false;
|
|
ProfilerFiller profiler = Profiler.get();
|
|
profiler.push("lightTex");
|
|
ClientLevel level = this.minecraft.level;
|
|
if (level == null) {
|
|
return;
|
|
}
|
|
Camera camera = this.minecraft.gameRenderer.getMainCamera();
|
|
int skyLightColor = camera.attributeProbe().getValue(EnvironmentAttributes.SKY_LIGHT_COLOR, partialTicks);
|
|
float ambientLight = level.dimensionType().ambientLight();
|
|
float skyFactor = camera.attributeProbe().getValue(EnvironmentAttributes.SKY_LIGHT_FACTOR, partialTicks).floatValue();
|
|
EndFlashState endFlashState = level.endFlashState();
|
|
if (endFlashState != null) {
|
|
ambientColor = new Vector3f(0.99f, 1.12f, 1.0f);
|
|
if (!this.minecraft.options.hideLightningFlash().get().booleanValue()) {
|
|
float intensity = endFlashState.getIntensity(partialTicks);
|
|
skyFactor = this.minecraft.gui.getBossOverlay().shouldCreateWorldFog() ? (skyFactor += intensity / 3.0f) : (skyFactor += intensity);
|
|
}
|
|
} else {
|
|
ambientColor = new Vector3f(1.0f, 1.0f, 1.0f);
|
|
}
|
|
float darknessEffectScale = this.minecraft.options.darknessEffectScale().get().floatValue();
|
|
float darknessGamma = this.minecraft.player.getEffectBlendFactor(MobEffects.DARKNESS, partialTicks) * darknessEffectScale;
|
|
float darknessScale = this.calculateDarknessScale(this.minecraft.player, darknessGamma, partialTicks) * darknessEffectScale;
|
|
float waterVision = this.minecraft.player.getWaterVision();
|
|
float nightVision = this.minecraft.player.hasEffect(MobEffects.NIGHT_VISION) ? GameRenderer.getNightVisionScale(this.minecraft.player, partialTicks) : (waterVision > 0.0f && this.minecraft.player.hasEffect(MobEffects.CONDUIT_POWER) ? waterVision : 0.0f);
|
|
float blockFactor = this.blockLightRedFlicker + 1.5f;
|
|
float brightness = this.minecraft.options.gamma().get().floatValue();
|
|
CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder();
|
|
try (GpuBuffer.MappedView view = commandEncoder.mapBuffer(this.ubo.currentBuffer(), false, true);){
|
|
Std140Builder.intoBuffer(view.data()).putFloat(ambientLight).putFloat(skyFactor).putFloat(blockFactor).putFloat(nightVision).putFloat(darknessScale).putFloat(this.renderer.getDarkenWorldAmount(partialTicks)).putFloat(Math.max(0.0f, brightness - darknessGamma)).putVec3((Vector3fc)ARGB.vector3fFromRGB24(skyLightColor)).putVec3((Vector3fc)ambientColor);
|
|
}
|
|
try (RenderPass renderPass = commandEncoder.createRenderPass(() -> "Update light", this.textureView, OptionalInt.empty());){
|
|
renderPass.setPipeline(RenderPipelines.LIGHTMAP);
|
|
RenderSystem.bindDefaultUniforms(renderPass);
|
|
renderPass.setUniform("LightmapInfo", this.ubo.currentBuffer());
|
|
renderPass.draw(0, 3);
|
|
}
|
|
this.ubo.rotate();
|
|
profiler.pop();
|
|
}
|
|
|
|
public static float getBrightness(DimensionType dimensionType, int level) {
|
|
return LightTexture.getBrightness(dimensionType.ambientLight(), level);
|
|
}
|
|
|
|
public static float getBrightness(float ambientLight, int level) {
|
|
float v = (float)level / 15.0f;
|
|
float curvedV = v / (4.0f - 3.0f * v);
|
|
return Mth.lerp(ambientLight, curvedV, 1.0f);
|
|
}
|
|
|
|
public static int pack(int block, int sky) {
|
|
return block << 4 | sky << 20;
|
|
}
|
|
|
|
public static int block(int lightCoords) {
|
|
return lightCoords >>> 4 & 0xF;
|
|
}
|
|
|
|
public static int sky(int lightCoords) {
|
|
return lightCoords >>> 20 & 0xF;
|
|
}
|
|
|
|
public static int lightCoordsWithEmission(int lightCoords, int emission) {
|
|
if (emission == 0) {
|
|
return lightCoords;
|
|
}
|
|
int sky = Math.max(LightTexture.sky(lightCoords), emission);
|
|
int block = Math.max(LightTexture.block(lightCoords), emission);
|
|
return LightTexture.pack(block, sky);
|
|
}
|
|
}
|
|
|