From 3e2bf1eddbc0537393feb6a2899d0567481511eb Mon Sep 17 00:00:00 2001 From: LabyStudio Date: Thu, 5 May 2022 01:27:08 +0200 Subject: [PATCH] implement biome color --- src/js/net/minecraft/client/Minecraft.js | 4 + .../client/gui/widgets/GuiKeyButton.js | 4 +- .../minecraft/client/render/BlockRenderer.js | 74 ++++++++++-------- .../minecraft/client/render/GrassColorizer.js | 35 +++++++++ .../minecraft/client/render/Tessellator.js | 7 ++ src/js/net/minecraft/client/world/World.js | 8 +- .../net/minecraft/client/world/block/Block.js | 4 + .../client/world/block/type/BlockGrass.js | 16 ++++ .../client/world/block/type/BlockLeave.js | 11 +++ src/resources/misc/grasscolor.png | Bin 0 -> 9480 bytes src/resources/terrain/terrain.png | Bin 7566 -> 7495 bytes src/start.js | 16 +--- 12 files changed, 127 insertions(+), 52 deletions(-) create mode 100644 src/js/net/minecraft/client/render/GrassColorizer.js create mode 100644 src/resources/misc/grasscolor.png diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index a3f930d..6100609 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -13,6 +13,7 @@ import Block from "./world/block/Block.js"; import BoundingBox from "../util/BoundingBox.js"; import {BlockRegistry} from "./world/block/BlockRegistry.js"; import FontRenderer from "./render/gui/FontRenderer.js"; +import GrassColorizer from "./render/GrassColorizer.js"; export default class Minecraft { @@ -59,6 +60,9 @@ export default class Minecraft { // Create font renderer this.fontRenderer = new FontRenderer(this); + // Grass colorizer + this.grassColorizer = new GrassColorizer(this); + // Update window size this.window.updateWindowSize(); diff --git a/src/js/net/minecraft/client/gui/widgets/GuiKeyButton.js b/src/js/net/minecraft/client/gui/widgets/GuiKeyButton.js index a1131f3..b4a34a4 100644 --- a/src/js/net/minecraft/client/gui/widgets/GuiKeyButton.js +++ b/src/js/net/minecraft/client/gui/widgets/GuiKeyButton.js @@ -4,6 +4,8 @@ export default class GuiKeyButton extends GuiButton { constructor(name, key, x, y, width, height, callback) { super(name + ": " + key, x, y, width, height, _ => callback(this.key)); + + this.name = name; this.listening = false; } @@ -14,7 +16,7 @@ export default class GuiKeyButton extends GuiButton { keyTyped(key) { if (this.listening) { - this.string = name + ": " + key; + this.string = this.name + ": " + key; this.listening = false; this.key = key; this.callback(); diff --git a/src/js/net/minecraft/client/render/BlockRenderer.js b/src/js/net/minecraft/client/render/BlockRenderer.js index 696101d..51d931c 100644 --- a/src/js/net/minecraft/client/render/BlockRenderer.js +++ b/src/js/net/minecraft/client/render/BlockRenderer.js @@ -60,79 +60,85 @@ export default class BlockRenderer { minV = 1 - minV; maxV = 1 - maxV; + // Get color multiplier + let color = block.getColor(world, x, y, z, face); + let red = (color >> 16 & 255) / 255.0; + let green = (color >> 8 & 255) / 255.0; + let blue = (color & 255) / 255.0; + // Classic lightning if (!ambientOcclusion) { let level = world === null ? 15 : world.getTotalLightAt(minX + face.x, minY + face.y, minZ + face.z); let brightness = 0.9 / 15.0 * level + 0.1; - let color = brightness * face.getShading(); - this.tessellator.setColor(color, color, color); + let shade = brightness * face.getShading(); + this.tessellator.setColor(red * shade, green * shade, blue * shade); } // Set opacity of block (Using alpha channel in texture right now) // this.tessellator.setAlpha(1 - block.getTransparency()); // Add face to tessellator - this.addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV); + this.addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red, green, blue); } - addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV) { + addFace(world, face, ambientOcclusion, minX, minY, minZ, maxX, maxY, maxZ, minU, minV, maxU, maxV, red = 1, green = 1, blue = 1) { if (face === EnumBlockFace.BOTTOM) { - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, minV); - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, minV); - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue); } if (face === EnumBlockFace.TOP) { - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, maxV); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, maxV, red, green, blue); } if (face === EnumBlockFace.NORTH) { - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV); - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue); } if (face === EnumBlockFace.SOUTH) { - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, minU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, maxU, maxV); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, minU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, maxU, maxV, red, green, blue); } if (face === EnumBlockFace.WEST) { - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, maxU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV); - this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, maxU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV, red, green, blue); } if (face === EnumBlockFace.EAST) { - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, minU, maxV); - this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, minU, maxV, red, green, blue); + this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV, red, green, blue); } } - addBlockCorner(world, face, ambientOcclusion, x, y, z, u, v) { + addBlockCorner(world, face, ambientOcclusion, x, y, z, u, v, red, green, blue) { // Smooth lightning if (ambientOcclusion) { - this.setAverageColor(world, face, x, y, z); + this.setAverageBrightness(world, face, x, y, z, red, green, blue); } this.tessellator.addVertexWithUV(x, y, z, u, v); } - setAverageColor(world, face, x, y, z) { + setAverageBrightness(world, face, x, y, z, red = 1, green = 1, blue = 1) { // Get the average light level of all 4 blocks at this corner let lightLevelAtThisCorner = this.getAverageLightLevelAt(world, x, y, z); // Convert light level from [0 - 15] to [0.1 - 1.0] let brightness = 0.9 / 15.0 * lightLevelAtThisCorner + 0.1; - let color = brightness * face.getShading(); + let shading = brightness * face.getShading(); - // Set color with shading - this.tessellator.setColorRGB(color, color, color); + // Transform brightness of edge + this.tessellator.setColor(red * shading, green * shading, blue * shading); } getAverageLightLevelAt(world, x, y, z) { diff --git a/src/js/net/minecraft/client/render/GrassColorizer.js b/src/js/net/minecraft/client/render/GrassColorizer.js new file mode 100644 index 0000000..8569416 --- /dev/null +++ b/src/js/net/minecraft/client/render/GrassColorizer.js @@ -0,0 +1,35 @@ +export default class GrassColorizer { + + constructor(minecraft) { + this.texture = minecraft.resources["misc/grasscolor.png"]; + + this.bitMap = this.createBitMap(this.texture); + } + + getColor(temperature, humidity) { + humidity *= temperature; + + let x = Math.floor((1.0 - temperature) * 255); + let y = Math.floor((1.0 - humidity) * 255); + + let index = (x + y * this.texture.width) * 4 + if (index >= this.bitMap.length) { + return -65281; + } + + let red = this.bitMap[index]; + let green = this.bitMap[index + 1]; + let blue = this.bitMap[index + 2]; + + return red << 16 | green << 8 | blue; + } + + createBitMap(img) { + let canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height); + return canvas.getContext('2d').getImageData(0, 0, img.width, img.height).data; + } + +} \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/Tessellator.js b/src/js/net/minecraft/client/render/Tessellator.js index f2b1997..e45f224 100644 --- a/src/js/net/minecraft/client/render/Tessellator.js +++ b/src/js/net/minecraft/client/render/Tessellator.js @@ -36,6 +36,13 @@ export default class Tessellator { this.setAlpha(alpha); } + multiplyColor(red, green, blue, alpha = 1) { + this.red *= red; + this.green *= green; + this.blue *= blue; + this.alpha *= alpha; + } + setAlpha(alpha) { this.alpha = alpha; } diff --git a/src/js/net/minecraft/client/world/World.js b/src/js/net/minecraft/client/world/World.js index 9e48afe..2c5a853 100644 --- a/src/js/net/minecraft/client/world/World.js +++ b/src/js/net/minecraft/client/world/World.js @@ -485,8 +485,12 @@ export default class World { return MathHelper.calculateCelestialAngle(this.time, partialTicks); } - getTemperature(x, z) { - return 1.24; + getTemperature(x, y, z) { + return 0.75; // TODO implement biomes + } + + getHumidity(x, y, z) { + return 0.85; // TODO implement biomes } getSkyColor(x, z, partialTicks) { diff --git a/src/js/net/minecraft/client/world/block/Block.js b/src/js/net/minecraft/client/world/block/Block.js index 4636959..cfa1a5e 100644 --- a/src/js/net/minecraft/client/world/block/Block.js +++ b/src/js/net/minecraft/client/world/block/Block.js @@ -48,6 +48,10 @@ export default class Block { return typeId === 0 || !Block.getById(typeId).isSolid(); } + getColor(world, x, y, z, face) { + return 0xffffff; + } + getLightValue() { return 0; } diff --git a/src/js/net/minecraft/client/world/block/type/BlockGrass.js b/src/js/net/minecraft/client/world/block/type/BlockGrass.js index 7e59dbb..c099c03 100644 --- a/src/js/net/minecraft/client/world/block/type/BlockGrass.js +++ b/src/js/net/minecraft/client/world/block/type/BlockGrass.js @@ -10,6 +10,22 @@ export default class BlockGrass extends Block { this.sound = Block.sounds.grass; } + getColor(world, x, y, z, face) { + // Only top face has a biome color + if (face !== EnumBlockFace.TOP) { + return 0xFFFFFF; + } + + // Inventory items have a default color + if (world === null) { + return 0x7cbd6b; + } + + let temperature = world.getTemperature(x, y, z); + let humidity = world.getHumidity(x, y, z); + return world.minecraft.grassColorizer.getColor(temperature, humidity); + } + getTextureForFace(face) { switch (face) { case EnumBlockFace.TOP: diff --git a/src/js/net/minecraft/client/world/block/type/BlockLeave.js b/src/js/net/minecraft/client/world/block/type/BlockLeave.js index 3be1dac..a07e067 100644 --- a/src/js/net/minecraft/client/world/block/type/BlockLeave.js +++ b/src/js/net/minecraft/client/world/block/type/BlockLeave.js @@ -9,6 +9,17 @@ export default class BlockLeave extends Block { this.sound = Block.sounds.grass; } + getColor(world, x, y, z, face) { + // Inventory items have a default color + if (world === null) { + return 0 << 16 | 255 << 8 | 0; + } + + let temperature = world.getTemperature(x, y, z); + let humidity = world.getHumidity(x, y, z); + return world.minecraft.grassColorizer.getColor(temperature, humidity); + } + getOpacity() { return 0.3; } diff --git a/src/resources/misc/grasscolor.png b/src/resources/misc/grasscolor.png new file mode 100644 index 0000000000000000000000000000000000000000..95de06853a915c7c6297ad80c4d5ec4618f5ee1c GIT binary patch literal 9480 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 literal 0 HcmV?d00001 diff --git a/src/resources/terrain/terrain.png b/src/resources/terrain/terrain.png index 91c9555ae466acd85cfdb3cf46e34b909782e828..a530bfef1dfe7e0bdb1f8ab57c01d5a888d10bb0 100644 GIT binary patch delta 6326 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 delta 6397 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 LNkvXXu0mjf_2lI8 diff --git a/src/start.js b/src/start.js index 7439910..c0a9dbb 100644 --- a/src/start.js +++ b/src/start.js @@ -2,21 +2,6 @@ import Minecraft from './js/net/minecraft/client/Minecraft.js'; let resources = []; -// Browser test function -function isES6() { - try { - Function("() => {};"); - return true; - } catch (exception) { - return false; - } -} - -// Test for browser support -if (!isES6()) { - alert("Your browser isn't supported! Please use another one."); -} - // Script loader function loadScripts(scripts) { let total = scripts.length; @@ -71,6 +56,7 @@ function updatePreStatus(message) { // Load textures loadTexture([ + "misc/grasscolor.png", "gui/font.png", "gui/gui.png", "gui/background.png",