implement biome color
This commit is contained in:
@@ -13,6 +13,7 @@ import Block from "./world/block/Block.js";
|
|||||||
import BoundingBox from "../util/BoundingBox.js";
|
import BoundingBox from "../util/BoundingBox.js";
|
||||||
import {BlockRegistry} from "./world/block/BlockRegistry.js";
|
import {BlockRegistry} from "./world/block/BlockRegistry.js";
|
||||||
import FontRenderer from "./render/gui/FontRenderer.js";
|
import FontRenderer from "./render/gui/FontRenderer.js";
|
||||||
|
import GrassColorizer from "./render/GrassColorizer.js";
|
||||||
|
|
||||||
export default class Minecraft {
|
export default class Minecraft {
|
||||||
|
|
||||||
@@ -59,6 +60,9 @@ export default class Minecraft {
|
|||||||
// Create font renderer
|
// Create font renderer
|
||||||
this.fontRenderer = new FontRenderer(this);
|
this.fontRenderer = new FontRenderer(this);
|
||||||
|
|
||||||
|
// Grass colorizer
|
||||||
|
this.grassColorizer = new GrassColorizer(this);
|
||||||
|
|
||||||
// Update window size
|
// Update window size
|
||||||
this.window.updateWindowSize();
|
this.window.updateWindowSize();
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ export default class GuiKeyButton extends GuiButton {
|
|||||||
|
|
||||||
constructor(name, key, x, y, width, height, callback) {
|
constructor(name, key, x, y, width, height, callback) {
|
||||||
super(name + ": " + key, x, y, width, height, _ => callback(this.key));
|
super(name + ": " + key, x, y, width, height, _ => callback(this.key));
|
||||||
|
|
||||||
|
this.name = name;
|
||||||
this.listening = false;
|
this.listening = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,7 +16,7 @@ export default class GuiKeyButton extends GuiButton {
|
|||||||
|
|
||||||
keyTyped(key) {
|
keyTyped(key) {
|
||||||
if (this.listening) {
|
if (this.listening) {
|
||||||
this.string = name + ": " + key;
|
this.string = this.name + ": " + key;
|
||||||
this.listening = false;
|
this.listening = false;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.callback();
|
this.callback();
|
||||||
|
|||||||
@@ -60,79 +60,85 @@ export default class BlockRenderer {
|
|||||||
minV = 1 - minV;
|
minV = 1 - minV;
|
||||||
maxV = 1 - maxV;
|
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
|
// Classic lightning
|
||||||
if (!ambientOcclusion) {
|
if (!ambientOcclusion) {
|
||||||
let level = world === null ? 15 : world.getTotalLightAt(minX + face.x, minY + face.y, minZ + face.z);
|
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 brightness = 0.9 / 15.0 * level + 0.1;
|
||||||
let color = brightness * face.getShading();
|
let shade = brightness * face.getShading();
|
||||||
this.tessellator.setColor(color, color, color);
|
this.tessellator.setColor(red * shade, green * shade, blue * shade);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set opacity of block (Using alpha channel in texture right now)
|
// Set opacity of block (Using alpha channel in texture right now)
|
||||||
// this.tessellator.setAlpha(1 - block.getTransparency());
|
// this.tessellator.setAlpha(1 - block.getTransparency());
|
||||||
|
|
||||||
// Add face to tessellator
|
// 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) {
|
if (face === EnumBlockFace.BOTTOM) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue);
|
||||||
}
|
}
|
||||||
if (face === EnumBlockFace.TOP) {
|
if (face === EnumBlockFace.TOP) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, maxV, red, green, blue);
|
||||||
}
|
}
|
||||||
if (face === EnumBlockFace.NORTH) {
|
if (face === EnumBlockFace.NORTH) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, minU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, minU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, maxU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, maxU, minV, red, green, blue);
|
||||||
}
|
}
|
||||||
if (face === EnumBlockFace.SOUTH) {
|
if (face === EnumBlockFace.SOUTH) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, maxU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, minU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, minU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, maxU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, maxU, maxV, red, green, blue);
|
||||||
}
|
}
|
||||||
if (face === EnumBlockFace.WEST) {
|
if (face === EnumBlockFace.WEST) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, maxZ, minU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, maxU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, minY, minZ, maxU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, minZ, maxU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, minX, maxY, maxZ, minU, minV, red, green, blue);
|
||||||
}
|
}
|
||||||
if (face === EnumBlockFace.EAST) {
|
if (face === EnumBlockFace.EAST) {
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, maxZ, maxU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, maxY, minZ, minU, minV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, minU, maxV);
|
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, minZ, minU, maxV, red, green, blue);
|
||||||
this.addBlockCorner(world, face, ambientOcclusion, maxX, minY, maxZ, maxU, maxV);
|
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
|
// Smooth lightning
|
||||||
if (ambientOcclusion) {
|
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);
|
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
|
// Get the average light level of all 4 blocks at this corner
|
||||||
let lightLevelAtThisCorner = this.getAverageLightLevelAt(world, x, y, z);
|
let lightLevelAtThisCorner = this.getAverageLightLevelAt(world, x, y, z);
|
||||||
|
|
||||||
// Convert light level from [0 - 15] to [0.1 - 1.0]
|
// Convert light level from [0 - 15] to [0.1 - 1.0]
|
||||||
let brightness = 0.9 / 15.0 * lightLevelAtThisCorner + 0.1;
|
let brightness = 0.9 / 15.0 * lightLevelAtThisCorner + 0.1;
|
||||||
let color = brightness * face.getShading();
|
let shading = brightness * face.getShading();
|
||||||
|
|
||||||
// Set color with shading
|
// Transform brightness of edge
|
||||||
this.tessellator.setColorRGB(color, color, color);
|
this.tessellator.setColor(red * shading, green * shading, blue * shading);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAverageLightLevelAt(world, x, y, z) {
|
getAverageLightLevelAt(world, x, y, z) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -36,6 +36,13 @@ export default class Tessellator {
|
|||||||
this.setAlpha(alpha);
|
this.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
multiplyColor(red, green, blue, alpha = 1) {
|
||||||
|
this.red *= red;
|
||||||
|
this.green *= green;
|
||||||
|
this.blue *= blue;
|
||||||
|
this.alpha *= alpha;
|
||||||
|
}
|
||||||
|
|
||||||
setAlpha(alpha) {
|
setAlpha(alpha) {
|
||||||
this.alpha = alpha;
|
this.alpha = alpha;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -485,8 +485,12 @@ export default class World {
|
|||||||
return MathHelper.calculateCelestialAngle(this.time, partialTicks);
|
return MathHelper.calculateCelestialAngle(this.time, partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTemperature(x, z) {
|
getTemperature(x, y, z) {
|
||||||
return 1.24;
|
return 0.75; // TODO implement biomes
|
||||||
|
}
|
||||||
|
|
||||||
|
getHumidity(x, y, z) {
|
||||||
|
return 0.85; // TODO implement biomes
|
||||||
}
|
}
|
||||||
|
|
||||||
getSkyColor(x, z, partialTicks) {
|
getSkyColor(x, z, partialTicks) {
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ export default class Block {
|
|||||||
return typeId === 0 || !Block.getById(typeId).isSolid();
|
return typeId === 0 || !Block.getById(typeId).isSolid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getColor(world, x, y, z, face) {
|
||||||
|
return 0xffffff;
|
||||||
|
}
|
||||||
|
|
||||||
getLightValue() {
|
getLightValue() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,22 @@ export default class BlockGrass extends Block {
|
|||||||
this.sound = Block.sounds.grass;
|
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) {
|
getTextureForFace(face) {
|
||||||
switch (face) {
|
switch (face) {
|
||||||
case EnumBlockFace.TOP:
|
case EnumBlockFace.TOP:
|
||||||
|
|||||||
@@ -9,6 +9,17 @@ export default class BlockLeave extends Block {
|
|||||||
this.sound = Block.sounds.grass;
|
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() {
|
getOpacity() {
|
||||||
return 0.3;
|
return 0.3;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 9.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.3 KiB |
+1
-15
@@ -2,21 +2,6 @@ import Minecraft from './js/net/minecraft/client/Minecraft.js';
|
|||||||
|
|
||||||
let resources = [];
|
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
|
// Script loader
|
||||||
function loadScripts(scripts) {
|
function loadScripts(scripts) {
|
||||||
let total = scripts.length;
|
let total = scripts.length;
|
||||||
@@ -71,6 +56,7 @@ function updatePreStatus(message) {
|
|||||||
|
|
||||||
// Load textures
|
// Load textures
|
||||||
loadTexture([
|
loadTexture([
|
||||||
|
"misc/grasscolor.png",
|
||||||
"gui/font.png",
|
"gui/font.png",
|
||||||
"gui/gui.png",
|
"gui/gui.png",
|
||||||
"gui/background.png",
|
"gui/background.png",
|
||||||
|
|||||||
Reference in New Issue
Block a user