Inspired by 2020's April Fools' 20w14infinite Snapshot, this mod brings endless randomly generated dimensions into Minecraft.
1package net.lerariemann.infinity.options;
2
3import com.mojang.blaze3d.platform.GlStateManager;
4import com.mojang.blaze3d.systems.RenderSystem;
5import net.fabricmc.api.EnvType;
6import net.fabricmc.api.Environment;
7import net.minecraft.client.MinecraftClient;
8import net.minecraft.client.gl.VertexBuffer;
9import net.minecraft.client.render.*;
10import net.minecraft.client.util.math.MatrixStack;
11import net.minecraft.client.world.ClientWorld;
12import net.minecraft.util.Identifier;
13import net.minecraft.util.math.MathHelper;
14import net.minecraft.util.math.RotationAxis;
15import net.minecraft.util.math.Vec3d;
16import net.minecraft.util.math.random.Random;
17import org.joml.Matrix4f;
18import org.joml.Vector3f;
19
20import java.awt.Color;
21
22@Environment(EnvType.CLIENT)
23public record SkyRenderer(InfinityOptions options, MinecraftClient client, ClientWorld world,
24 MatrixStack matrices, Tessellator tessellator, float tickDelta, Matrix4f projectionMatrix,
25 VertexBuffer lightSkyBuffer, VertexBuffer starsBuffer) {
26
27 public SkyRenderer(InfinityOptions options, MinecraftClient client, ClientWorld world,
28 MatrixStack matrices, float tickDelta, Matrix4f projectionMatrix,
29 VertexBuffer lightSkyBuffer, VertexBuffer starsBuffer) {
30 this(options, client, world, matrices, Tessellator.getInstance(), tickDelta, projectionMatrix, lightSkyBuffer, starsBuffer);
31 }
32
33 public static boolean testCameraCancels(Camera camera) {
34 CameraSubmersionType cameraSubmersionType = camera.getSubmersionType();
35 return (cameraSubmersionType == CameraSubmersionType.POWDER_SNOW
36 || cameraSubmersionType == CameraSubmersionType.LAVA);
37 }
38
39 public void render(Runnable fogCallback) {
40 if (testAndRenderNonOverworldySkies()) return;
41 setupOverworldySky();
42 renderAllCelestialBodies(fogCallback);
43 finish();
44 }
45
46 public boolean testAndRenderNonOverworldySkies() {
47 if (client.world!=null && client.world.getDimensionEffects().getSkyType() == DimensionEffects.SkyType.END) {
48 renderSkybox(new Identifier("textures/environment/end_sky.png"), 16.0f, 40, 255);
49 return true;
50 }
51 if (options.endSkyLike()) {
52 handleSkyBackground();
53 return true;
54 }
55 return client.world != null && client.world.getDimensionEffects().getSkyType() != DimensionEffects.SkyType.NORMAL;
56 }
57
58 public void setupOverworldySky() {
59 BackgroundRenderer.setFogBlack();
60 RenderSystem.depthMask(false);
61 handleSkyBackground();
62 handleFog();
63 matrices.push();
64 }
65 public void handleSkyBackground() {
66 String skyType = options.getSkyType();
67 if (skyType.equals("rainbow")) {
68 renderRainbowBackground();
69 }
70 else {
71 Vec3d vec3d = this.world.getSkyColor(client.gameRenderer.getCamera().getPos(), tickDelta);
72 renderSingleColorBackground((float)vec3d.x, (float)vec3d.y, (float)vec3d.z, 1.0f);
73 }
74 }
75 public void renderRainbowBackground() {
76 float main = world.getSkyAngle(tickDelta) * 2;
77 int color = Color.getHSBColor(main - (int)main, 1.0f, 1.0f).getRGB();
78 float f = MathHelper.clamp(MathHelper.cos(world.getSkyAngle(tickDelta) * ((float)Math.PI * 2)) * 2.0f + 0.5f, 0.0f, 1.0f);
79 renderSingleColorBackground(f * (float)(color >> 16 & 0xFF) / 255.0f, f * (float)(color >> 8 & 0xFF) / 255.0f, f * (float)(color & 0xFF) / 255.0f, 1.0f);
80 }
81 public void renderSingleColorBackground(float f, float g, float h, float a) {
82 RenderSystem.setShaderColor(f, g, h, a);
83 lightSkyBuffer.bind();
84 lightSkyBuffer.draw(matrices.peek().getPositionMatrix(), projectionMatrix, RenderSystem.getShader());
85 VertexBuffer.unbind();
86 }
87
88 public void handleFog() {
89 RenderSystem.enableBlend();
90 float[] fs = this.world.getDimensionEffects().getFogColorOverride(this.world.getSkyAngle(tickDelta), tickDelta);
91 if (fs != null && options().hasDawn()) handleSunriseFog(fs);
92 RenderSystem.blendFuncSeparate(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE, GlStateManager.SrcFactor.ONE, GlStateManager.DstFactor.ZERO);
93 }
94 public void handleSunriseFog(float[] fs) {
95 RenderSystem.setShader(GameRenderer::getPositionColorProgram);
96 RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
97
98 matrices.push();
99 matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90.0f));
100 float i = MathHelper.sin(this.world.getSkyAngleRadians(tickDelta)) < 0.0f ? 180.0f : 0.0f;
101 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(i - options.getSolarTilt()));
102
103 Matrix4f matrix4f = matrices.peek().getPositionMatrix();
104 BufferBuilder bufferBuilder = tessellator.getBuffer();
105 bufferBuilder.begin(VertexFormat.DrawMode.TRIANGLE_FAN, VertexFormats.POSITION_COLOR);
106 bufferBuilder.vertex(matrix4f, 0.0f, 100.0f, 0.0f).color(fs[0], fs[1], fs[2], fs[3]);
107 for (int n = 0; n <= 16; ++n) {
108 float o = (float)n * ((float)Math.PI * 2) / 16.0f;
109 float p = MathHelper.sin(o);
110 float q = MathHelper.cos(o);
111 bufferBuilder.vertex(matrix4f, p * 120.0f, q * 120.0f, -q * 40.0f * fs[3]).color(fs[0], fs[1], fs[2], 0.0f);
112 }
113 BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
114 matrices.pop();
115 }
116
117 public void renderAllCelestialBodies(Runnable fogCallback) {
118 float rain_alpha = 1.0f - this.world.getRainGradient(tickDelta);
119 RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, rain_alpha);
120
121 renderSun();
122 for (int i = 0; i < options.getNumMoons(); i++) {
123 renderMoon(i);
124 }
125 renderStars(fogCallback, rain_alpha);
126 }
127
128 public void finish() {
129 RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
130 RenderSystem.disableBlend();
131 RenderSystem.defaultBlendFunc();
132 matrices.pop();
133 RenderSystem.depthMask(true);
134 }
135
136 public void rotate_with_velocity(float v, float offset) {
137 matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((world.getSkyAngle(tickDelta) + offset) * 360.0f * v));
138 }
139
140 public void renderSun() {
141 renderSingleBody(
142 options.getSolarSize(),
143 options.getSolarTilt(),
144 0,
145 1,
146 0,
147 options.getSolarTint(),
148 options.getSolarTexture(),
149 true);
150 }
151 public void renderMoon(int i) {
152 renderSingleBody(
153 options.getLunarSize(i),
154 options.getLunarTiltY(i),
155 options.getLunarTiltZ(i),
156 options.getLunarVelocity(i),
157 options.getLunarOffset(i),
158 options.getLunarTint(i),
159 options.getLunarTexture(i),
160 false);
161 }
162
163 public void renderSingleBody(float size, float tilt_y, float tilt_z, float velocity, float offset, Vector3f tint, Identifier texture,
164 boolean sun) {
165 matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(tilt_y));
166 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(tilt_z));
167 rotate_with_velocity(velocity, offset);
168 if (sun) renderSun(matrices.peek().getPositionMatrix(), texture, size, 100.0f, tint);
169 else renderMoon(matrices.peek().getPositionMatrix(), texture, size, -100.0f, tint);
170 rotate_with_velocity(-1 * velocity, offset);
171 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-tilt_z));
172 matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-tilt_y));
173 }
174 public void renderSun(Matrix4f matrix4f2, Identifier texture, float k, float y, Vector3f tint) {
175 RenderSystem.setShader(GameRenderer::getPositionTexProgram);
176 RenderSystem.setShaderTexture(0, texture);
177 RenderSystem.setShaderColor(tint.x, tint.y, tint.z, 1.0f);
178 BufferBuilder bufferBuilder = tessellator.getBuffer();
179 bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
180 bufferBuilder.vertex(matrix4f2, -k, y, -k).texture(0.0f, 0.0f);
181 bufferBuilder.vertex(matrix4f2, k, y, -k).texture(1.0f, 0.0f);
182 bufferBuilder.vertex(matrix4f2, k, y, k).texture(1.0f, 1.0f);
183 bufferBuilder.vertex(matrix4f2, -k, y, k).texture(0.0f, 1.0f);
184 BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
185 }
186 public void renderMoon(Matrix4f matrix4f2, Identifier texture, float k, float y, Vector3f tint) {
187 float t, q, p, o;
188 if (!options.isMoonCustom()) {
189 int moon_phase = world.getMoonPhase();
190 int s = moon_phase % 4;
191 int m = moon_phase / 4 % 2;
192 t = (float)(s) / 4.0f;
193 o = (float)(m) / 2.0f;
194 p = (float)(s + 1) / 4.0f;
195 q = (float)(m + 1) / 2.0f;
196 }
197 else {
198 t = q = 1.0f;
199 p = o = 0.0f;
200 }
201 renderMoon(matrix4f2, texture, k, y, tint, t, q, p, o);
202 }
203 public void renderMoon(Matrix4f matrix4f2, Identifier texture, float k, float y, Vector3f tint, float t, float q, float p, float o) {
204 RenderSystem.setShader(GameRenderer::getPositionTexProgram);
205 RenderSystem.setShaderTexture(0, texture);
206 RenderSystem.setShaderColor(tint.x, tint.y, tint.z, 1.0f);
207 BufferBuilder bufferBuilder = tessellator.getBuffer();
208 bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE);
209 bufferBuilder.vertex(matrix4f2, -k, y, k).texture(p, q);
210 bufferBuilder.vertex(matrix4f2, k, y, k).texture(t, q);
211 bufferBuilder.vertex(matrix4f2, k, y, -k).texture(t, o);
212 bufferBuilder.vertex(matrix4f2, -k, y, -k).texture(p, o);
213 BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
214 }
215
216 public void renderStars(Runnable fogCallback, float rain_alpha) {
217 renderStars(options.getStellarTiltY(),
218 options.getStellarTiltZ(),
219 options.getStellarVelocity(),
220 0,
221 fogCallback, rain_alpha);
222 }
223 public void renderStars(float tilt_y, float tilt_z, float velocity, float offset,
224 Runnable fogCallback, float rain_alpha) {
225 matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(tilt_y));
226 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(tilt_z));
227 rotate_with_velocity(velocity, offset);
228 renderStars(matrices.peek().getPositionMatrix(), projectionMatrix, fogCallback, rain_alpha);
229 rotate_with_velocity(-1 * velocity, offset);
230 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-tilt_z));
231 matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-tilt_y));
232 }
233 public void renderStars(Matrix4f matrix4f2, Matrix4f projectionMatrix, Runnable fogCallback, float rain_alpha) {
234 float u = world.method_23787(tickDelta) * rain_alpha;
235 Vector3f color = options.getStellarColor();
236 if (u > 0.0f) {
237 RenderSystem.setShaderColor(u*color.x, u*color.y, u*color.z, u);
238 BackgroundRenderer.clearFog();
239 starsBuffer.bind();
240 starsBuffer.draw(matrix4f2, projectionMatrix, GameRenderer.getPositionProgram());
241 VertexBuffer.unbind();
242 fogCallback.run();
243 }
244 }
245 public float getStarBrightness(float tickDelta) {
246 float f = world.getSkyAngle(tickDelta);
247 float g = 1.0F - (MathHelper.cos(f * (float) (Math.PI * 2)) * 2.0F + 0.25F);
248 g = MathHelper.clamp(g, 0.0f, 1.0f);
249 float day = options.getDayStarBrightness();
250 float night = options.getNightStarBrightness();
251 return day + g*g*(night-day);
252 }
253
254 public void renderSkybox(Identifier texture, float copies, int brightness, int alpha) {
255 renderSkybox(texture, copies, brightness, brightness, brightness, alpha);
256 }
257 public void renderSkybox(Identifier texture, float copies, int r, int g, int b, int alpha) {
258 RenderSystem.enableBlend();
259 RenderSystem.depthMask(false);
260 RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
261 RenderSystem.setShaderTexture(0, texture);
262 Tessellator tessellator = Tessellator.getInstance();
263
264 for (int i = 0; i < 6; ++i) {
265 matrices.push();
266 if (i == 1) {
267 matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90.0f));
268 }
269 if (i == 2) {
270 matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-90.0f));
271 }
272 if (i == 3) {
273 matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180.0f));
274 }
275 if (i == 4) {
276 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(90.0f));
277 }
278 if (i == 5) {
279 matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(-90.0f));
280 }
281
282 Matrix4f matrix4f = matrices.peek().getPositionMatrix();
283 BufferBuilder bufferBuilder = tessellator.getBuffer();
284 bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
285 bufferBuilder.vertex(matrix4f, -100.0f, -100.0f, -100.0f).texture(0.0f, 0.0f).color(r, g, b, alpha);
286 bufferBuilder.vertex(matrix4f, -100.0f, -100.0f, 100.0f).texture(0.0f, copies).color(r, g, b, alpha);
287 bufferBuilder.vertex(matrix4f, 100.0f, -100.0f, 100.0f).texture(copies, copies).color(r, g, b, alpha);
288 bufferBuilder.vertex(matrix4f, 100.0f, -100.0f, -100.0f).texture(copies, 0.0f).color(r, g, b, alpha);
289 BufferRenderer.drawWithGlobalProgram(bufferBuilder.end());
290 matrices.pop();
291 }
292 RenderSystem.depthMask(true);
293 RenderSystem.disableBlend();
294 }
295}