diff --git a/BlueMapCommon/webapp/public/lang/en.conf b/BlueMapCommon/webapp/public/lang/en.conf
index 31107a95..b3fbdfd9 100644
--- a/BlueMapCommon/webapp/public/lang/en.conf
+++ b/BlueMapCommon/webapp/public/lang/en.conf
@@ -83,6 +83,9 @@
light: "Light"
contrast: "Contrast"
}
+ chunkBorders: {
+ button: "Show chunk borders"
+ }
debug: {
button: "Debug"
}
diff --git a/BlueMapCommon/webapp/public/lang/nl.conf b/BlueMapCommon/webapp/public/lang/nl.conf
index b196b593..f79eb64b 100644
--- a/BlueMapCommon/webapp/public/lang/nl.conf
+++ b/BlueMapCommon/webapp/public/lang/nl.conf
@@ -83,6 +83,9 @@
light: "Licht"
contrast: "Contrast"
}
+ chunkBorders: {
+ button: "Laat chunk grenzen zien"
+ }
debug: {
button: "Debug"
}
diff --git a/BlueMapCommon/webapp/src/components/Menu/SettingsMenu.vue b/BlueMapCommon/webapp/src/components/Menu/SettingsMenu.vue
index 155f2e61..8cc6e45e 100644
--- a/BlueMapCommon/webapp/src/components/Menu/SettingsMenu.vue
+++ b/BlueMapCommon/webapp/src/components/Menu/SettingsMenu.vue
@@ -56,6 +56,8 @@
>{{lang.name}}
+ {{ $t("chunkBorders.button") }}
+
{{ $t("debug.button") }}
{{ $t("resetAllSettings.button") }}
@@ -105,6 +107,9 @@ name: "SettingsMenu",
}
},
methods: {
+ switchChunkBorders() {
+ this.$bluemap.setChunkBorders(!this.mapViewer.uniforms.chunkBorders.value);
+ },
switchDebug() {
this.$bluemap.setDebug(!this.appState.debug);
},
@@ -121,4 +126,4 @@ name: "SettingsMenu",
\ No newline at end of file
+
diff --git a/BlueMapCommon/webapp/src/js/BlueMapApp.js b/BlueMapCommon/webapp/src/js/BlueMapApp.js
index dc0ba1aa..27b70744 100644
--- a/BlueMapCommon/webapp/src/js/BlueMapApp.js
+++ b/BlueMapCommon/webapp/src/js/BlueMapApp.js
@@ -525,6 +525,10 @@ export class BlueMapApp {
this.appState.controls.state = "free";
}
+ setChunkBorders(chunkBorders) {
+ this.mapViewer.data.uniforms.chunkBorders.value = chunkBorders;
+ }
+
setDebug(debug) {
this.appState.debug = debug;
@@ -608,6 +612,7 @@ export class BlueMapApp {
this.setTheme(this.loadUserSetting("theme", this.appState.theme));
this.setScreenshotClipboard(this.loadUserSetting("screenshotClipboard", this.appState.screenshot.clipboard));
await setLanguage(this.loadUserSetting("lang", i18n.locale.value));
+ this.setChunkBorders(this.loadUserSetting("chunkBorders", this.mapViewer.data.uniforms.chunkBorders.value))
this.setDebug(this.loadUserSetting("debug", this.appState.debug));
alert(this.events, "Settings loaded!", "info");
@@ -629,6 +634,7 @@ export class BlueMapApp {
this.saveUserSetting("theme", this.appState.theme);
this.saveUserSetting("screenshotClipboard", this.appState.screenshot.clipboard);
this.saveUserSetting("lang", i18n.locale.value);
+ this.saveUserSetting("chunkBorders", this.mapViewer.data.uniforms.chunkBorders.value);
this.saveUserSetting("debug", this.appState.debug);
alert(this.events, "Settings saved!", "info");
diff --git a/BlueMapCommon/webapp/src/js/MapViewer.js b/BlueMapCommon/webapp/src/js/MapViewer.js
index c29bd9bd..868b4563 100644
--- a/BlueMapCommon/webapp/src/js/MapViewer.js
+++ b/BlueMapCommon/webapp/src/js/MapViewer.js
@@ -61,6 +61,7 @@ export class MapViewer {
ambientLight: { value: 0 },
skyColor: { value: new Color(0.5, 0.5, 1) },
voidColor: { value: new Color(0, 0, 0) },
+ chunkBorders: { value: false },
hiresTileMap: {
value: {
map: null,
diff --git a/BlueMapCommon/webapp/src/js/map/hires/HiresFragmentShader.js b/BlueMapCommon/webapp/src/js/map/hires/HiresFragmentShader.js
index 5fa5da16..e50c75d9 100644
--- a/BlueMapCommon/webapp/src/js/map/hires/HiresFragmentShader.js
+++ b/BlueMapCommon/webapp/src/js/map/hires/HiresFragmentShader.js
@@ -24,6 +24,7 @@
*/
import { ShaderChunk } from 'three';
+// language=GLSL
export const HIRES_FRAGMENT_SHADER = `
${ShaderChunk.logdepthbuf_pars_fragment}
@@ -31,6 +32,7 @@ ${ShaderChunk.logdepthbuf_pars_fragment}
#define texture texture2D
#endif
+uniform float distance;
uniform sampler2D textureImage;
uniform float sunlightStrength;
uniform float ambientLight;
@@ -38,9 +40,10 @@ uniform float animationFrameHeight;
uniform float animationFrameIndex;
uniform float animationInterpolationFrameIndex;
uniform float animationInterpolation;
+uniform bool chunkBorders;
varying vec3 vPosition;
-//varying vec3 vWorldPosition;
+varying vec3 vWorldPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 vColor;
@@ -68,6 +71,25 @@ void main() {
float light = mix(vBlocklight, max(vSunlight, vBlocklight), sunlightStrength);
color.rgb *= mix(ambientLight, 1.0, light / 15.0);
+ if (chunkBorders) {
+ vec4 lineColour = vec4(1.0, 0.0, 1.0, 0.4);
+ float lineInterval = 16.0;
+ float lineThickness = 0.125; //width of two Minecraft pixels
+ float offset = 0.5;
+
+ vec2 worldPos = vWorldPosition.xz;
+ worldPos += offset;
+ float x = abs(mod(worldPos.x, lineInterval) - offset);
+ float y = abs(mod(worldPos.y, lineInterval) - offset);
+ bool isChunkBorder = x < lineThickness || y < lineThickness;
+
+ //only show line on upwards facing surfaces
+ bool showChunkBorder = isChunkBorder && vNormal.y > 0.1;
+
+ float distFac = smoothstep(200.0, 600.0, distance);
+ color.rgb = mix(mix(color.rgb, lineColour.rgb, float(showChunkBorder) * lineColour.a), color.rgb, distFac);
+ }
+
gl_FragColor = color;
${ShaderChunk.logdepthbuf_fragment}
diff --git a/BlueMapCommon/webapp/src/js/map/hires/HiresVertexShader.js b/BlueMapCommon/webapp/src/js/map/hires/HiresVertexShader.js
index d919f420..ed15ccbf 100644
--- a/BlueMapCommon/webapp/src/js/map/hires/HiresVertexShader.js
+++ b/BlueMapCommon/webapp/src/js/map/hires/HiresVertexShader.js
@@ -33,6 +33,7 @@ attribute float sunlight;
attribute float blocklight;
varying vec3 vPosition;
+varying vec3 vWorldPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec3 vColor;
@@ -42,6 +43,8 @@ varying float vBlocklight;
void main() {
vPosition = position;
+ vec4 worldPos = modelMatrix * vec4(vPosition, 1);
+ vWorldPosition = worldPos.xyz;
vNormal = normal;
vUv = uv;
vColor = color;
diff --git a/BlueMapCommon/webapp/src/js/map/lowres/LowresFragmentShader.js b/BlueMapCommon/webapp/src/js/map/lowres/LowresFragmentShader.js
index 095d2b5a..da702b8a 100644
--- a/BlueMapCommon/webapp/src/js/map/lowres/LowresFragmentShader.js
+++ b/BlueMapCommon/webapp/src/js/map/lowres/LowresFragmentShader.js
@@ -24,6 +24,7 @@
*/
import { ShaderChunk } from 'three';
+// language=GLSL
export const LOWRES_FRAGMENT_SHADER = `
${ShaderChunk.logdepthbuf_pars_fragment}
@@ -51,6 +52,7 @@ uniform vec2 textureSize;
uniform float lod;
uniform float lodScale;
uniform vec3 voidColor;
+uniform bool chunkBorders;
varying vec3 vPosition;
varying vec3 vWorldPosition;
@@ -98,9 +100,10 @@ void main() {
float ao = 0.0;
float aoStrength = 0.0;
+ float distFac = smoothstep(200.0, 600.0, distance);
if(lod == 1.0) {
aoStrength = smoothstep(PI - 0.8, PI - 0.2, acos(-clamp(viewMatrix[1][2], 0.0, 1.0)));
- aoStrength *= 1.0 - smoothstep(200.0, 600.0, distance);
+ aoStrength *= 1.0 - distFac;
if (aoStrength > 0.0) {
const float r = 3.0;
@@ -123,6 +126,21 @@ void main() {
float light = mix(blockLight, 15.0, sunlightStrength);
color.rgb *= mix(ambientLight, 1.0, light / 15.0);
+ if (chunkBorders) {
+ vec4 lineColour = vec4(1.0, 0.0, 1.0, 0.4);
+ float lineInterval = 16.0;
+ float lineThickness = 0.125; //width of two Minecraft pixels
+ float offset = 0.5;
+
+ vec2 worldPos = vWorldPosition.xz;
+ worldPos += offset;
+ float x = abs(mod(worldPos.x, lineInterval) - offset);
+ float y = abs(mod(worldPos.y, lineInterval) - offset);
+ bool isChunkBorder = x < lineThickness || y < lineThickness;
+
+ color.rgb = mix(mix(color.rgb, lineColour.rgb, float(isChunkBorder) * lineColour.a), color.rgb, distFac);
+ }
+
vec3 adjustedVoidColor = adjustColor(voidColor);
//where there's transparency, there is void that needs to be coloured
color.rgb = mix(adjustedVoidColor, color.rgb, color.a);