VulkanShader_1.21.10-0.0.4-alpha.jar
Download file
package net.vulkanmod.render.sky;
import com.mojang.blaze3d.opengl.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.VertexFormat.class_5596;
import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import net.minecraft.class_1011;
import net.minecraft.class_243;
import net.minecraft.class_287;
import net.minecraft.class_289;
import net.minecraft.class_290;
import net.minecraft.class_2960;
import net.minecraft.class_310;
import net.minecraft.class_3298;
import net.minecraft.class_3300;
import net.minecraft.class_3532;
import net.minecraft.class_4063;
import net.minecraft.class_638;
import net.minecraft.class_9801;
import net.vulkanmod.render.PipelineManager;
import net.vulkanmod.render.VBO;
import net.vulkanmod.vulkan.Renderer;
import net.vulkanmod.vulkan.VRenderSystem;
import net.vulkanmod.vulkan.shader.GraphicsPipeline;
import net.vulkanmod.vulkan.util.ColorUtil;
import org.apache.commons.lang3.Validate;
import org.joml.Matrix4fStack;
public class CloudRenderer {
private static final class_2960 TEXTURE_LOCATION = class_2960.method_60656("textures/environment/clouds.png");
private static final int DIR_NEG_Y_BIT = 1;
private static final int DIR_POS_Y_BIT = 2;
private static final int DIR_NEG_X_BIT = 4;
private static final int DIR_POS_X_BIT = 8;
private static final int DIR_NEG_Z_BIT = 16;
private static final int DIR_POS_Z_BIT = 32;
private static final byte Y_BELOW_CLOUDS = 0;
private static final byte Y_ABOVE_CLOUDS = 1;
private static final byte Y_INSIDE_CLOUDS = 2;
private static final int CELL_WIDTH = 12;
private static final int CELL_HEIGHT = 4;
private CloudGrid cloudGrid;
private int prevCloudX;
private int prevCloudZ;
private byte prevCloudY;
private class_4063 prevCloudsType;
private boolean generateClouds;
private VBO cloudBuffer;
public CloudRenderer() {
this.loadTexture();
}
public void loadTexture() {
this.cloudGrid = createCloudGrid(TEXTURE_LOCATION);
}
public void renderClouds(class_638 level, float ticks, float partialTicks, double camX, double camY, double camZ) {
Optional<Integer> optional = level.method_8597().comp_4037();
if (!optional.isEmpty()) {
class_310 minecraft = class_310.method_1551();
int cloudHeight = (Integer)optional.get();
double timeOffset = (double)((ticks + partialTicks) * 0.03F);
double centerX = camX + timeOffset;
double centerZ = camZ + (double)3.96F;
double centerY = (double)((float)cloudHeight - (float)camY + 0.33F);
int centerCellX = (int)Math.floor(centerX / (double)12.0F);
int centerCellZ = (int)Math.floor(centerZ / (double)12.0F);
byte yState;
if (centerY < (double)-4.0F) {
yState = 0;
} else if (centerY > (double)0.0F) {
yState = 1;
} else {
yState = 2;
}
if (centerCellX != this.prevCloudX || centerCellZ != this.prevCloudZ || minecraft.field_1690.method_1632() != this.prevCloudsType || this.prevCloudY != yState || this.cloudBuffer == null) {
this.prevCloudX = centerCellX;
this.prevCloudZ = centerCellZ;
this.prevCloudsType = minecraft.field_1690.method_1632();
this.prevCloudY = yState;
this.generateClouds = true;
}
if (this.generateClouds) {
this.generateClouds = false;
if (this.cloudBuffer != null) {
this.cloudBuffer.close();
}
this.resetBuffer();
class_9801 cloudsMesh = this.buildClouds(class_289.method_1348(), centerCellX, centerCellZ, centerY);
if (cloudsMesh == null) {
return;
}
this.cloudBuffer = new VBO(true);
this.cloudBuffer.upload(cloudsMesh);
}
if (this.cloudBuffer != null) {
float xTranslation = (float)(centerX - (double)(centerCellX * 12));
float yTranslation = (float)centerY;
float zTranslation = (float)(centerZ - (double)(centerCellZ * 12));
Renderer.getInstance().getMainPass().rebindMainTarget();
Matrix4fStack poseStack = RenderSystem.getModelViewStack();
poseStack.pushMatrix();
poseStack.translate(-xTranslation, yTranslation, -zTranslation);
VRenderSystem.applyModelViewMatrix(poseStack);
VRenderSystem.calculateMVP();
VRenderSystem.setModelOffset(-xTranslation, 0.0F, -zTranslation);
class_243 cloudColor = class_243.method_24457(level.method_23785(partialTicks));
VRenderSystem.setShaderColor((float)cloudColor.field_1352, (float)cloudColor.field_1351, (float)cloudColor.field_1350, 0.8F);
GraphicsPipeline pipeline = PipelineManager.getCloudsPipeline();
VRenderSystem.enableBlend();
VRenderSystem.blendFuncSeparate(770, 771, 1, 0);
VRenderSystem.enableDepthTest();
VRenderSystem.depthFunc(515);
GlStateManager._enableDepthTest();
GlStateManager._depthMask(true);
GlStateManager._colorMask(true, true, true, true);
GlStateManager._disablePolygonOffset();
VRenderSystem.setPolygonModeGL(6914);
VRenderSystem.setPrimitiveTopologyGL(4);
boolean fastClouds = this.prevCloudsType == class_4063.field_18163;
boolean insideClouds = yState == 2;
boolean disableCull = insideClouds || fastClouds && centerY <= (double)0.0F;
if (disableCull) {
VRenderSystem.disableCull();
} else {
VRenderSystem.enableCull();
}
if (!fastClouds) {
VRenderSystem.colorMask(false, false, false, false);
this.cloudBuffer.bind(pipeline);
this.cloudBuffer.draw();
VRenderSystem.colorMask(true, true, true, true);
}
this.cloudBuffer.bind(pipeline);
this.cloudBuffer.draw();
poseStack.popMatrix();
VRenderSystem.enableCull();
VRenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
VRenderSystem.setModelOffset(0.0F, 0.0F, 0.0F);
}
}
}
public void resetBuffer() {
if (this.cloudBuffer != null) {
this.cloudBuffer.close();
this.cloudBuffer = null;
}
}
private class_9801 buildClouds(class_289 tesselator, int centerCellX, int centerCellZ, double cloudY) {
float upFaceBrightness = 1.0F;
float xDirBrightness = 0.9F;
float downFaceBrightness = 0.7F;
float zDirBrightness = 0.8F;
class_287 bufferBuilder = tesselator.method_60827(class_5596.field_27382, class_290.field_1576);
int cloudRange = Math.min((Integer)class_310.method_1551().field_1690.method_71270().method_41753(), 128) * 16;
int renderDistance = class_3532.method_15386((float)cloudRange / 12.0F);
boolean insideClouds = this.prevCloudY == 2;
if (this.prevCloudsType == class_4063.field_18164) {
for(int cellX = -renderDistance; cellX < renderDistance; ++cellX) {
for(int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) {
int cellIdx = this.cloudGrid.getWrappedIdx(centerCellX + cellX, centerCellZ + cellZ);
byte renderFaces = this.cloudGrid.renderFaces[cellIdx];
int baseColor = this.cloudGrid.pixels[cellIdx];
float x = (float)(cellX * 12);
float z = (float)(cellZ * 12);
if ((renderFaces & 2) != 0 && cloudY <= (double)0.0F) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 1.0F);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 12.0F, color);
}
if ((renderFaces & 1) != 0 && cloudY >= (double)-4.0F) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 0.7F);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 12.0F, color);
}
if ((renderFaces & 8) != 0 && (x < 1.0F || insideClouds)) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 0.9F);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 0.0F, color);
}
if ((renderFaces & 4) != 0 && (x > -1.0F || insideClouds)) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 0.9F);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 12.0F, color);
}
if ((renderFaces & 32) != 0 && (z < 1.0F || insideClouds)) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 0.8F);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 12.0F, color);
}
if ((renderFaces & 16) != 0 && (z > -1.0F || insideClouds)) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 0.8F);
putVertex(bufferBuilder, x + 12.0F, 4.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 0.0F, 4.0F, z + 0.0F, color);
}
}
}
} else {
for(int cellX = -renderDistance; cellX < renderDistance; ++cellX) {
for(int cellZ = -renderDistance; cellZ < renderDistance; ++cellZ) {
int cellIdx = this.cloudGrid.getWrappedIdx(centerCellX + cellX, centerCellZ + cellZ);
byte renderFaces = this.cloudGrid.renderFaces[cellIdx];
int baseColor = this.cloudGrid.pixels[cellIdx];
float x = (float)(cellX * 12);
float z = (float)(cellZ * 12);
if ((renderFaces & 1) != 0) {
int color = ColorUtil.ARGB.multiplyRGB(baseColor, 1.0F);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 12.0F, color);
putVertex(bufferBuilder, x + 0.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 0.0F, color);
putVertex(bufferBuilder, x + 12.0F, 0.0F, z + 12.0F, color);
}
}
}
}
return bufferBuilder.method_60794();
}
private static void putVertex(class_287 bufferBuilder, float x, float y, float z, int color) {
bufferBuilder.method_22912(x, y, z).method_39415(color);
}
private static CloudGrid createCloudGrid(class_2960 textureLocation) {
class_3300 resourceManager = class_310.method_1551().method_1478();
try {
class_3298 resource = resourceManager.getResourceOrThrow(textureLocation);
InputStream inputStream = resource.method_14482();
CloudGrid var8;
try {
class_1011 image = class_1011.method_4309(inputStream);
int width = image.method_4307();
int height = image.method_4323();
Validate.isTrue(width == height, "Image width and height must be the same", new Object[0]);
int[] pixels = image.method_48463();
var8 = new CloudGrid(pixels, width);
} catch (Throwable var10) {
if (inputStream != null) {
try {
inputStream.close();
} catch (Throwable var9) {
var10.addSuppressed(var9);
}
}
throw var10;
}
if (inputStream != null) {
inputStream.close();
}
return var8;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static class CloudGrid {
final int width;
final int[] pixels;
final byte[] renderFaces;
CloudGrid(int[] pixels, int width) {
this.pixels = pixels;
this.width = width;
this.renderFaces = this.computeRenderFaces();
}
byte[] computeRenderFaces() {
byte[] renderFaces = new byte[this.pixels.length];
for(int z = 0; z < this.width; ++z) {
for(int x = 0; x < this.width; ++x) {
int idx = this.getIdx(x, z);
int pixel = this.pixels[idx];
if (hasColor(pixel)) {
byte faces = 3;
int adjPixel = this.getTexelWrapped(x - 1, z);
if (pixel != adjPixel) {
faces = (byte)(faces | 4);
}
adjPixel = this.getTexelWrapped(x + 1, z);
if (pixel != adjPixel) {
faces = (byte)(faces | 8);
}
adjPixel = this.getTexelWrapped(x, z - 1);
if (pixel != adjPixel) {
faces = (byte)(faces | 16);
}
adjPixel = this.getTexelWrapped(x, z + 1);
if (pixel != adjPixel) {
faces = (byte)(faces | 32);
}
renderFaces[idx] = faces;
}
}
}
return renderFaces;
}
int getTexelWrapped(int x, int z) {
if (x < 0) {
x = this.width - 1;
}
if (x > this.width - 1) {
x = 0;
}
if (z < 0) {
z = this.width - 1;
}
if (z > this.width - 1) {
z = 0;
}
return this.pixels[this.getIdx(x, z)];
}
int getWrappedIdx(int x, int z) {
x = Math.floorMod(x, this.width);
z = Math.floorMod(z, this.width);
return this.getIdx(x, z);
}
int getIdx(int x, int z) {
return z * this.width + x;
}
private static boolean hasColor(int pixel) {
return (pixel >> 24 & 255) > 1;
}
}
}
Download file