Code/net/minecraft/client/renderer/SkyRenderer.java

320 lines
16 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.client.renderer;
import com.mojang.blaze3d.buffers.BufferType;
import com.mojang.blaze3d.buffers.BufferUsage;
import com.mojang.blaze3d.buffers.GpuBuffer;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.systems.RenderPass;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.textures.GpuTexture;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.MeshData;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.math.Axis;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.AbstractTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.TriState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Matrix4fStack;
import org.joml.Vector3f;
@OnlyIn(Dist.CLIENT)
public class SkyRenderer implements AutoCloseable {
private static final ResourceLocation SUN_LOCATION = ResourceLocation.withDefaultNamespace("textures/environment/sun.png");
private static final ResourceLocation MOON_LOCATION = ResourceLocation.withDefaultNamespace("textures/environment/moon_phases.png");
public static final ResourceLocation END_SKY_LOCATION = ResourceLocation.withDefaultNamespace("textures/environment/end_sky.png");
private static final float SKY_DISC_RADIUS = 512.0F;
private static final int SKY_VERTICES = 10;
private static final int STAR_COUNT = 1500;
private static final int END_SKY_QUAD_COUNT = 6;
private final GpuBuffer starBuffer;
private final RenderSystem.AutoStorageIndexBuffer starIndices = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
private final GpuBuffer topSkyBuffer;
private final GpuBuffer bottomSkyBuffer;
private final GpuBuffer endSkyBuffer;
private int starIndexCount;
public SkyRenderer() {
this.starBuffer = this.buildStars();
this.endSkyBuffer = buildEndSky();
try (ByteBufferBuilder bytebufferbuilder = new ByteBufferBuilder(10 * DefaultVertexFormat.POSITION.getVertexSize())) {
BufferBuilder bufferbuilder = new BufferBuilder(bytebufferbuilder, VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION);
this.buildSkyDisc(bufferbuilder, 16.0F);
try (MeshData meshdata = bufferbuilder.buildOrThrow()) {
this.topSkyBuffer = RenderSystem.getDevice()
.createBuffer(() -> "Top sky vertex buffer", BufferType.VERTICES, BufferUsage.STATIC_WRITE, meshdata.vertexBuffer());
}
bufferbuilder = new BufferBuilder(bytebufferbuilder, VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION);
this.buildSkyDisc(bufferbuilder, -16.0F);
try (MeshData meshdata1 = bufferbuilder.buildOrThrow()) {
this.bottomSkyBuffer = RenderSystem.getDevice()
.createBuffer(() -> "Bottom sky vertex buffer", BufferType.VERTICES, BufferUsage.STATIC_WRITE, meshdata1.vertexBuffer());
}
}
}
private GpuBuffer buildStars() {
RandomSource randomsource = RandomSource.create(10842L);
float f = 100.0F;
GpuBuffer gpubuffer;
try (ByteBufferBuilder bytebufferbuilder = new ByteBufferBuilder(DefaultVertexFormat.POSITION.getVertexSize() * 1500 * 4)) {
BufferBuilder bufferbuilder = new BufferBuilder(bytebufferbuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION);
for (int i = 0; i < 1500; i++) {
float f1 = randomsource.nextFloat() * 2.0F - 1.0F;
float f2 = randomsource.nextFloat() * 2.0F - 1.0F;
float f3 = randomsource.nextFloat() * 2.0F - 1.0F;
float f4 = 0.15F + randomsource.nextFloat() * 0.1F;
float f5 = Mth.lengthSquared(f1, f2, f3);
if (!(f5 <= 0.010000001F) && !(f5 >= 1.0F)) {
Vector3f vector3f = new Vector3f(f1, f2, f3).normalize(100.0F);
float f6 = (float)(randomsource.nextDouble() * (float) Math.PI * 2.0);
Matrix3f matrix3f = new Matrix3f().rotateTowards(new Vector3f(vector3f).negate(), new Vector3f(0.0F, 1.0F, 0.0F)).rotateZ(-f6);
bufferbuilder.addVertex(new Vector3f(f4, -f4, 0.0F).mul(matrix3f).add(vector3f));
bufferbuilder.addVertex(new Vector3f(f4, f4, 0.0F).mul(matrix3f).add(vector3f));
bufferbuilder.addVertex(new Vector3f(-f4, f4, 0.0F).mul(matrix3f).add(vector3f));
bufferbuilder.addVertex(new Vector3f(-f4, -f4, 0.0F).mul(matrix3f).add(vector3f));
}
}
try (MeshData meshdata = bufferbuilder.buildOrThrow()) {
this.starIndexCount = meshdata.drawState().indexCount();
gpubuffer = RenderSystem.getDevice()
.createBuffer(() -> "Stars vertex buffer", BufferType.VERTICES, BufferUsage.STATIC_WRITE, meshdata.vertexBuffer());
}
}
return gpubuffer;
}
private void buildSkyDisc(VertexConsumer p_375466_, float p_363584_) {
float f = Math.signum(p_363584_) * 512.0F;
p_375466_.addVertex(0.0F, p_363584_, 0.0F);
for (int i = -180; i <= 180; i += 45) {
p_375466_.addVertex(f * Mth.cos(i * (float) (Math.PI / 180.0)), p_363584_, 512.0F * Mth.sin(i * (float) (Math.PI / 180.0)));
}
}
public void renderSkyDisc(float p_369198_, float p_369913_, float p_362432_) {
RenderSystem.setShaderColor(p_369198_, p_369913_, p_362432_, 1.0F);
GpuTexture gputexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
GpuTexture gputexture1 = Minecraft.getInstance().getMainRenderTarget().getDepthTexture();
try (RenderPass renderpass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(gputexture, OptionalInt.empty(), gputexture1, OptionalDouble.empty())) {
renderpass.setPipeline(RenderPipelines.SKY);
renderpass.setVertexBuffer(0, this.topSkyBuffer);
renderpass.draw(0, 10);
}
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
}
public void renderDarkDisc() {
RenderSystem.setShaderColor(0.0F, 0.0F, 0.0F, 1.0F);
Matrix4fStack matrix4fstack = RenderSystem.getModelViewStack();
matrix4fstack.pushMatrix();
matrix4fstack.translate(0.0F, 12.0F, 0.0F);
GpuTexture gputexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
GpuTexture gputexture1 = Minecraft.getInstance().getMainRenderTarget().getDepthTexture();
try (RenderPass renderpass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(gputexture, OptionalInt.empty(), gputexture1, OptionalDouble.empty())) {
renderpass.setPipeline(RenderPipelines.SKY);
renderpass.setVertexBuffer(0, this.bottomSkyBuffer);
renderpass.draw(0, 10);
}
matrix4fstack.popMatrix();
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
}
public void renderSunMoonAndStars(
PoseStack p_362673_,
MultiBufferSource.BufferSource p_376689_,
float p_369057_,
int p_364932_,
float p_366540_,
float p_368016_,
FogParameters p_362209_
) {
p_362673_.pushPose();
p_362673_.mulPose(Axis.YP.rotationDegrees(-90.0F));
p_362673_.mulPose(Axis.XP.rotationDegrees(p_369057_ * 360.0F));
this.renderSun(p_366540_, p_376689_, p_362673_);
this.renderMoon(p_364932_, p_366540_, p_376689_, p_362673_);
p_376689_.endBatch();
if (p_368016_ > 0.0F) {
this.renderStars(p_362209_, p_368016_, p_362673_);
}
p_362673_.popPose();
}
private void renderSun(float p_363755_, MultiBufferSource p_376565_, PoseStack p_369287_) {
float f = 30.0F;
float f1 = 100.0F;
VertexConsumer vertexconsumer = p_376565_.getBuffer(RenderType.celestial(SUN_LOCATION));
int i = ARGB.white(p_363755_);
Matrix4f matrix4f = p_369287_.last().pose();
vertexconsumer.addVertex(matrix4f, -30.0F, 100.0F, -30.0F).setUv(0.0F, 0.0F).setColor(i);
vertexconsumer.addVertex(matrix4f, 30.0F, 100.0F, -30.0F).setUv(1.0F, 0.0F).setColor(i);
vertexconsumer.addVertex(matrix4f, 30.0F, 100.0F, 30.0F).setUv(1.0F, 1.0F).setColor(i);
vertexconsumer.addVertex(matrix4f, -30.0F, 100.0F, 30.0F).setUv(0.0F, 1.0F).setColor(i);
}
private void renderMoon(int p_367893_, float p_364034_, MultiBufferSource p_377520_, PoseStack p_369177_) {
float f = 20.0F;
int i = p_367893_ % 4;
int j = p_367893_ / 4 % 2;
float f1 = (i + 0) / 4.0F;
float f2 = (j + 0) / 2.0F;
float f3 = (i + 1) / 4.0F;
float f4 = (j + 1) / 2.0F;
float f5 = 100.0F;
VertexConsumer vertexconsumer = p_377520_.getBuffer(RenderType.celestial(MOON_LOCATION));
int k = ARGB.white(p_364034_);
Matrix4f matrix4f = p_369177_.last().pose();
vertexconsumer.addVertex(matrix4f, -20.0F, -100.0F, 20.0F).setUv(f3, f4).setColor(k);
vertexconsumer.addVertex(matrix4f, 20.0F, -100.0F, 20.0F).setUv(f1, f4).setColor(k);
vertexconsumer.addVertex(matrix4f, 20.0F, -100.0F, -20.0F).setUv(f1, f2).setColor(k);
vertexconsumer.addVertex(matrix4f, -20.0F, -100.0F, -20.0F).setUv(f3, f2).setColor(k);
}
private void renderStars(FogParameters p_362284_, float p_361462_, PoseStack p_364130_) {
Matrix4fStack matrix4fstack = RenderSystem.getModelViewStack();
matrix4fstack.pushMatrix();
matrix4fstack.mul(p_364130_.last().pose());
RenderSystem.setShaderColor(p_361462_, p_361462_, p_361462_, p_361462_);
RenderSystem.setShaderFog(FogParameters.NO_FOG);
RenderPipeline renderpipeline = RenderPipelines.STARS;
GpuTexture gputexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
GpuTexture gputexture1 = Minecraft.getInstance().getMainRenderTarget().getDepthTexture();
GpuBuffer gpubuffer = this.starIndices.getBuffer(this.starIndexCount);
try (RenderPass renderpass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(gputexture, OptionalInt.empty(), gputexture1, OptionalDouble.empty())) {
renderpass.setPipeline(renderpipeline);
renderpass.setVertexBuffer(0, this.starBuffer);
renderpass.setIndexBuffer(gpubuffer, this.starIndices.type());
renderpass.drawIndexed(0, this.starIndexCount);
}
RenderSystem.setShaderFog(p_362284_);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
matrix4fstack.popMatrix();
}
public void renderSunriseAndSunset(PoseStack p_365939_, MultiBufferSource.BufferSource p_377149_, float p_368996_, int p_365467_) {
p_365939_.pushPose();
p_365939_.mulPose(Axis.XP.rotationDegrees(90.0F));
float f = Mth.sin(p_368996_) < 0.0F ? 180.0F : 0.0F;
p_365939_.mulPose(Axis.ZP.rotationDegrees(f));
p_365939_.mulPose(Axis.ZP.rotationDegrees(90.0F));
Matrix4f matrix4f = p_365939_.last().pose();
VertexConsumer vertexconsumer = p_377149_.getBuffer(RenderType.sunriseSunset());
float f1 = ARGB.alphaFloat(p_365467_);
vertexconsumer.addVertex(matrix4f, 0.0F, 100.0F, 0.0F).setColor(p_365467_);
int i = ARGB.transparent(p_365467_);
int j = 16;
for (int k = 0; k <= 16; k++) {
float f2 = k * (float) (Math.PI * 2) / 16.0F;
float f3 = Mth.sin(f2);
float f4 = Mth.cos(f2);
vertexconsumer.addVertex(matrix4f, f3 * 120.0F, f4 * 120.0F, -f4 * 40.0F * f1).setColor(i);
}
p_365939_.popPose();
}
private static GpuBuffer buildEndSky() {
GpuBuffer gpubuffer;
try (ByteBufferBuilder bytebufferbuilder = new ByteBufferBuilder(24 * DefaultVertexFormat.POSITION_TEX_COLOR.getVertexSize())) {
BufferBuilder bufferbuilder = new BufferBuilder(bytebufferbuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR);
for (int i = 0; i < 6; i++) {
Matrix4f matrix4f = new Matrix4f();
switch (i) {
case 1:
matrix4f.rotationX((float) (Math.PI / 2));
break;
case 2:
matrix4f.rotationX((float) (-Math.PI / 2));
break;
case 3:
matrix4f.rotationX((float) Math.PI);
break;
case 4:
matrix4f.rotationZ((float) (Math.PI / 2));
break;
case 5:
matrix4f.rotationZ((float) (-Math.PI / 2));
}
bufferbuilder.addVertex(matrix4f, -100.0F, -100.0F, -100.0F).setUv(0.0F, 0.0F).setColor(-14145496);
bufferbuilder.addVertex(matrix4f, -100.0F, -100.0F, 100.0F).setUv(0.0F, 16.0F).setColor(-14145496);
bufferbuilder.addVertex(matrix4f, 100.0F, -100.0F, 100.0F).setUv(16.0F, 16.0F).setColor(-14145496);
bufferbuilder.addVertex(matrix4f, 100.0F, -100.0F, -100.0F).setUv(16.0F, 0.0F).setColor(-14145496);
}
try (MeshData meshdata = bufferbuilder.buildOrThrow()) {
gpubuffer = RenderSystem.getDevice()
.createBuffer(() -> "End sky vertex buffer", BufferType.VERTICES, BufferUsage.STATIC_WRITE, meshdata.vertexBuffer());
}
}
return gpubuffer;
}
public void renderEndSky() {
TextureManager texturemanager = Minecraft.getInstance().getTextureManager();
AbstractTexture abstracttexture = texturemanager.getTexture(END_SKY_LOCATION);
abstracttexture.setFilter(TriState.FALSE, false);
RenderSystem.AutoStorageIndexBuffer rendersystem$autostorageindexbuffer = RenderSystem.getSequentialBuffer(VertexFormat.Mode.QUADS);
GpuBuffer gpubuffer = rendersystem$autostorageindexbuffer.getBuffer(36);
GpuTexture gputexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
GpuTexture gputexture1 = Minecraft.getInstance().getMainRenderTarget().getDepthTexture();
try (RenderPass renderpass = RenderSystem.getDevice()
.createCommandEncoder()
.createRenderPass(gputexture, OptionalInt.empty(), gputexture1, OptionalDouble.empty())) {
renderpass.setPipeline(RenderPipelines.END_SKY);
renderpass.bindSampler("Sampler0", abstracttexture.getTexture());
renderpass.setVertexBuffer(0, this.endSkyBuffer);
renderpass.setIndexBuffer(gpubuffer, rendersystem$autostorageindexbuffer.type());
renderpass.drawIndexed(0, 36);
}
}
@Override
public void close() {
this.starBuffer.close();
this.topSkyBuffer.close();
this.bottomSkyBuffer.close();
this.endSkyBuffer.close();
}
}