189 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| 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.FilterMode;
 | |
| import com.mojang.blaze3d.textures.GpuTexture;
 | |
| import com.mojang.blaze3d.textures.GpuTextureView;
 | |
| import com.mojang.blaze3d.textures.TextureFormat;
 | |
| import com.mojang.blaze3d.vertex.VertexFormat;
 | |
| import java.util.OptionalInt;
 | |
| import net.fabricmc.api.EnvType;
 | |
| import net.fabricmc.api.Environment;
 | |
| import net.minecraft.client.Minecraft;
 | |
| import net.minecraft.client.multiplayer.ClientLevel;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.util.profiling.Profiler;
 | |
| import net.minecraft.util.profiling.ProfilerFiller;
 | |
| import net.minecraft.world.effect.MobEffects;
 | |
| import net.minecraft.world.entity.LivingEntity;
 | |
| import net.minecraft.world.level.dimension.DimensionType;
 | |
| import org.joml.Vector3f;
 | |
| 
 | |
| @Environment(EnvType.CLIENT)
 | |
| public class LightTexture implements AutoCloseable {
 | |
| 	public static final int FULL_BRIGHT = 15728880;
 | |
| 	public static final int FULL_SKY = 15728640;
 | |
| 	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()
 | |
| 		.putInt()
 | |
| 		.putFloat()
 | |
| 		.putFloat()
 | |
| 		.putFloat()
 | |
| 		.putFloat()
 | |
| 		.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 gpuDevice = RenderSystem.getDevice();
 | |
| 		this.texture = gpuDevice.createTexture("Light Texture", 12, TextureFormat.RGBA8, 16, 16, 1, 1);
 | |
| 		this.texture.setTextureFilter(FilterMode.LINEAR, false);
 | |
| 		this.textureView = gpuDevice.createTextureView(this.texture);
 | |
| 		gpuDevice.createCommandEncoder().clearColorTexture(this.texture, -1);
 | |
| 		this.ubo = new MappableRingBuffer(() -> "Lightmap UBO", 130, LIGHTMAP_UBO_SIZE);
 | |
| 	}
 | |
| 
 | |
| 	public GpuTextureView getTextureView() {
 | |
| 		return this.textureView;
 | |
| 	}
 | |
| 
 | |
| 	public void close() {
 | |
| 		this.texture.close();
 | |
| 		this.textureView.close();
 | |
| 		this.ubo.close();
 | |
| 	}
 | |
| 
 | |
| 	public void tick() {
 | |
| 		this.blockLightRedFlicker = this.blockLightRedFlicker + (float)((Math.random() - Math.random()) * Math.random() * Math.random() * 0.1);
 | |
| 		this.blockLightRedFlicker *= 0.9F;
 | |
| 		this.updateLightTexture = true;
 | |
| 	}
 | |
| 
 | |
| 	public void turnOffLightLayer() {
 | |
| 		RenderSystem.setShaderTexture(2, null);
 | |
| 	}
 | |
| 
 | |
| 	public void turnOnLightLayer() {
 | |
| 		RenderSystem.setShaderTexture(2, this.textureView);
 | |
| 	}
 | |
| 
 | |
| 	private float calculateDarknessScale(LivingEntity entity, float gamma, float partialTick) {
 | |
| 		float f = 0.45F * gamma;
 | |
| 		return Math.max(0.0F, Mth.cos((entity.tickCount - partialTick) * (float) Math.PI * 0.025F) * f);
 | |
| 	}
 | |
| 
 | |
| 	public void updateLightTexture(float partialTicks) {
 | |
| 		if (this.updateLightTexture) {
 | |
| 			this.updateLightTexture = false;
 | |
| 			ProfilerFiller profilerFiller = Profiler.get();
 | |
| 			profilerFiller.push("lightTex");
 | |
| 			ClientLevel clientLevel = this.minecraft.level;
 | |
| 			if (clientLevel != null) {
 | |
| 				float f = clientLevel.getSkyDarken(1.0F);
 | |
| 				float g;
 | |
| 				if (clientLevel.getSkyFlashTime() > 0) {
 | |
| 					g = 1.0F;
 | |
| 				} else {
 | |
| 					g = f * 0.95F + 0.05F;
 | |
| 				}
 | |
| 
 | |
| 				float h = this.minecraft.options.darknessEffectScale().get().floatValue();
 | |
| 				float i = this.minecraft.player.getEffectBlendFactor(MobEffects.DARKNESS, partialTicks) * h;
 | |
| 				float j = this.calculateDarknessScale(this.minecraft.player, i, partialTicks) * h;
 | |
| 				float k = this.minecraft.player.getWaterVision();
 | |
| 				float l;
 | |
| 				if (this.minecraft.player.hasEffect(MobEffects.NIGHT_VISION)) {
 | |
| 					l = GameRenderer.getNightVisionScale(this.minecraft.player, partialTicks);
 | |
| 				} else if (k > 0.0F && this.minecraft.player.hasEffect(MobEffects.CONDUIT_POWER)) {
 | |
| 					l = k;
 | |
| 				} else {
 | |
| 					l = 0.0F;
 | |
| 				}
 | |
| 
 | |
| 				Vector3f vector3f = new Vector3f(f, f, 1.0F).lerp(new Vector3f(1.0F, 1.0F, 1.0F), 0.35F);
 | |
| 				float m = this.blockLightRedFlicker + 1.5F;
 | |
| 				float n = clientLevel.dimensionType().ambientLight();
 | |
| 				boolean bl = clientLevel.effects().forceBrightLightmap();
 | |
| 				float o = this.minecraft.options.gamma().get().floatValue();
 | |
| 				RenderSystem.AutoStorageIndexBuffer autoStorageIndexBuffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
 | |
| 				GpuBuffer gpuBuffer = autoStorageIndexBuffer.getBuffer(6);
 | |
| 				CommandEncoder commandEncoder = RenderSystem.getDevice().createCommandEncoder();
 | |
| 
 | |
| 				try (GpuBuffer.MappedView mappedView = commandEncoder.mapBuffer(this.ubo.currentBuffer(), false, true)) {
 | |
| 					Std140Builder.intoBuffer(mappedView.data())
 | |
| 						.putFloat(n)
 | |
| 						.putFloat(g)
 | |
| 						.putFloat(m)
 | |
| 						.putInt(bl ? 1 : 0)
 | |
| 						.putFloat(l)
 | |
| 						.putFloat(j)
 | |
| 						.putFloat(this.renderer.getDarkenWorldAmount(partialTicks))
 | |
| 						.putFloat(Math.max(0.0F, o - i))
 | |
| 						.putVec3(vector3f);
 | |
| 				}
 | |
| 
 | |
| 				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.setVertexBuffer(0, RenderSystem.getQuadVertexBuffer());
 | |
| 					renderPass.setIndexBuffer(gpuBuffer, autoStorageIndexBuffer.type());
 | |
| 					renderPass.drawIndexed(0, 0, 6, 1);
 | |
| 				}
 | |
| 
 | |
| 				this.ubo.rotate();
 | |
| 				profilerFiller.pop();
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	public static float getBrightness(DimensionType dimensionType, int lightLevel) {
 | |
| 		return getBrightness(dimensionType.ambientLight(), lightLevel);
 | |
| 	}
 | |
| 
 | |
| 	public static float getBrightness(float ambientLight, int lightLevel) {
 | |
| 		float f = lightLevel / 15.0F;
 | |
| 		float g = f / (4.0F - 3.0F * f);
 | |
| 		return Mth.lerp(ambientLight, g, 1.0F);
 | |
| 	}
 | |
| 
 | |
| 	public static int pack(int blockLight, int skyLight) {
 | |
| 		return blockLight << 4 | skyLight << 20;
 | |
| 	}
 | |
| 
 | |
| 	public static int block(int packedLight) {
 | |
| 		return packedLight >>> 4 & 15;
 | |
| 	}
 | |
| 
 | |
| 	public static int sky(int packedLight) {
 | |
| 		return packedLight >>> 20 & 15;
 | |
| 	}
 | |
| 
 | |
| 	public static int lightCoordsWithEmission(int packedLight, int emission) {
 | |
| 		if (emission == 0) {
 | |
| 			return packedLight;
 | |
| 		} else {
 | |
| 			int i = Math.max(sky(packedLight), emission);
 | |
| 			int j = Math.max(block(packedLight), emission);
 | |
| 			return pack(j, i);
 | |
| 		}
 | |
| 	}
 | |
| }
 |