First basic support for lowres changes

This commit is contained in:
Lukas Rieger (Blue) 2022-08-08 21:31:28 +02:00
parent 3d37231109
commit d12c48275f
No known key found for this signature in database
GPG Key ID: 2D09EC5ED2687FF2
7 changed files with 152 additions and 19 deletions

View File

@ -291,7 +291,7 @@ export class MapViewer {
this.renderer.render(this.map.lowresTileManager.scene, this.camera); this.renderer.render(this.map.lowresTileManager.scene, this.camera);
this.renderer.clearDepth(); this.renderer.clearDepth();
if (this.controlsManager.distance < 2000) { if (this.controlsManager.distance < 1000) {
this.renderer.render(this.map.hiresTileManager.scene, this.camera); this.renderer.render(this.map.hiresTileManager.scene, this.camera);
} }
} }

115
src/map/LowresTileLoader.js Normal file
View File

@ -0,0 +1,115 @@
/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
import {pathFromCoords} from "../util/Utils";
import {
TextureLoader,
Mesh,
PlaneBufferGeometry,
VertexColors,
FrontSide,
ShaderMaterial,
NearestFilter,
ClampToEdgeWrapping,
NearestMipMapLinearFilter,
RepeatWrapping,
} from "three";
export class LowresTileLoader {
constructor(tilePath, vertexShader, fragmentShader, tileCacheHash = 0, layer = 0) {
Object.defineProperty( this, 'isLowresTileLoader', { value: true } );
this.tilePath = tilePath;
this.layer = layer;
this.tileCacheHash = tileCacheHash;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.textureLoader = new TextureLoader();
this.geometry = new PlaneBufferGeometry(
500, 500,
100, 100
);
this.geometry.deleteAttribute('normal');
this.geometry.deleteAttribute('uv');
this.geometry.rotateX(-Math.PI / 2);
this.geometry.translate(250, 0, 250);
}
load = (tileX, tileZ) => {
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.png';
return new Promise((resolve, reject) => {
this.textureLoader.load(tileUrl + '?' + this.tileCacheHash,
texture => {
texture.anisotropy = 1;
texture.generateMipmaps = false;
texture.magFilter = NearestFilter;
texture.minFilter = texture.generateMipmaps ? NearestMipMapLinearFilter : NearestFilter;
texture.wrapS = ClampToEdgeWrapping;
texture.wrapT = ClampToEdgeWrapping;
texture.flipY = false;
texture.flatShading = true;
let material = new ShaderMaterial({
uniforms: {
textureImage: {
type: 't',
value: texture
}
},
vertexShader: this.vertexShader,
fragmentShader: this.fragmentShader,
transparent: false,
depthWrite: true,
depthTest: true,
vertexColors: VertexColors,
side: FrontSide,
wireframe: false,
});
let object = new Mesh(this.geometry, material);
if (this.layer) object.layers.set(this.layer);
let tileSize = {x:500, z:500};
let translate = {x:0, z:0};
let scale = {x:1, z:1};
object.position.set(tileX * tileSize.x + translate.x, 0, tileZ * tileSize.z + translate.z);
object.scale.set(scale.x, 1, scale.z);
object.userData.tileUrl = tileUrl;
object.updateMatrixWorld(true);
resolve(object);
},
undefined,
reject
);
});
}
}

View File

@ -39,6 +39,7 @@ import {
import {alert, dispatchEvent, generateCacheHash, hashTile, stringToImage, vecArrToObj} from "../util/Utils"; import {alert, dispatchEvent, generateCacheHash, hashTile, stringToImage, vecArrToObj} from "../util/Utils";
import {TileManager} from "./TileManager"; import {TileManager} from "./TileManager";
import {TileLoader} from "./TileLoader"; import {TileLoader} from "./TileLoader";
import {LowresTileLoader} from "./LowresTileLoader";
export class Map { export class Map {
@ -114,8 +115,8 @@ export class Map {
this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures); this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures);
this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}hires/`, this.hiresMaterial, this.data.hires, tileCacheHash), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events); this.hiresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}tiles/0/`, this.hiresMaterial, this.data.hires, tileCacheHash), this.onTileLoad("hires"), this.onTileUnload("hires"), this.events);
this.lowresTileManager = new TileManager(new Scene(), new TileLoader(`${this.data.dataUrl}lowres/`, this.lowresMaterial, this.data.lowres, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events); this.lowresTileManager = new TileManager(new Scene(), new LowresTileLoader(`${this.data.dataUrl}tiles/1/`, lowresVertexShader, lowresFragmentShader, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
this.hiresTileManager.scene.autoUpdate = false; this.hiresTileManager.scene.autoUpdate = false;
this.lowresTileManager.scene.autoUpdate = false; this.lowresTileManager.scene.autoUpdate = false;

View File

@ -34,7 +34,7 @@ export class TileManager {
/** /**
* @param scene {THREE.Scene} * @param scene {THREE.Scene}
* @param tileLoader {TileLoader} * @param tileLoader {TileLoader | LowresTileLoader}
* @param onTileLoad {function(Tile)} * @param onTileLoad {function(Tile)}
* @param onTileUnload {function(Tile)} * @param onTileUnload {function(Tile)}
* @param events {EventTarget} * @param events {EventTarget}
@ -197,7 +197,7 @@ export class TileManager {
if (error.target && error.target.status === 404) return; if (error.target && error.target.status === 404) return;
if (error.type && error.type === "abort") return; if (error.type && error.type === "abort") return;
alert(this.events, "Failed to load tile: " + error, "warning"); //alert(this.events, "Failed to load tile: " + error.type, "warning");
}) })
.finally(() => { .finally(() => {
this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED); this.tileMap.setTile(tile.x - this.centerTile.x + TileManager.tileMapHalfSize, tile.z - this.centerTile.y + TileManager.tileMapHalfSize, TileMap.LOADED);

View File

@ -39,9 +39,10 @@ struct TileMap {
vec2 pos; vec2 pos;
}; };
uniform float sunlightStrength; //uniform float sunlightStrength;
uniform float ambientLight; //uniform float ambientLight;
uniform TileMap hiresTileMap; //uniform TileMap hiresTileMap;
uniform sampler2D textureImage;
varying vec3 vPosition; varying vec3 vPosition;
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
@ -52,15 +53,25 @@ varying float vDistance;
void main() { void main() {
//discard if hires tile is loaded at that position //discard if hires tile is loaded at that position
if (vDistance < 1900.0 && texture(hiresTileMap.map, ((vWorldPosition.xz - hiresTileMap.translate) / hiresTileMap.scale - hiresTileMap.pos) / hiresTileMap.size + 0.5).r >= 1.0) discard; //if (vDistance < 1900.0 && texture(hiresTileMap.map, ((vWorldPosition.xz - hiresTileMap.translate) / hiresTileMap.scale - hiresTileMap.pos) / hiresTileMap.size + 0.5).r >= 1.0) discard;
vec4 color = vec4(vColor, 1.0); //vec4 color = vec4(vColor, 1.0);
float diff = max(dot(vNormal, vec3(0.3637, 0.7274, 0.5819)), 0.0) * 0.3 + 0.7; //float diff = max(dot(vNormal, vec3(0.3637, 0.7274, 0.5819)), 0.0) * 0.3 + 0.7;
color *= diff; //color *= diff;
color *= mix(sunlightStrength, 1.0, ambientLight); //color *= mix(sunlightStrength, 1.0, ambientLight);
//vec4 color = vec4(0.3637, 0.7274, 0.5819, 1.0);
vec4 color = texture(textureImage, vec2(vPosition.x / 500.0, vPosition.z / 1000.0));
float height = texture(textureImage, vec2(vPosition.x / 500.0, (vPosition.z + 500.0) / 1000.0)).b * 255.0;
float heightX = texture(textureImage, vec2((vPosition.x + 1.0) / 500.0, (vPosition.z + 500.0) / 1000.0)).b * 255.0;
float heightZ = texture(textureImage, vec2(vPosition.x / 500.0, (vPosition.z + 501.0) / 1000.0)).b * 255.0;
float diff = (height - heightX) + (height - heightZ);
color.rgb += clamp(diff * 0.04, -0.2, 0.04);
gl_FragColor = color; gl_FragColor = color;
${ShaderChunk.logdepthbuf_fragment} ${ShaderChunk.logdepthbuf_fragment}

View File

@ -28,6 +28,8 @@ export const LOWRES_VERTEX_SHADER = `
#include <common> #include <common>
${ShaderChunk.logdepthbuf_pars_vertex} ${ShaderChunk.logdepthbuf_pars_vertex}
uniform sampler2D textureImage;
varying vec3 vPosition; varying vec3 vPosition;
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
varying vec3 vNormal; varying vec3 vNormal;
@ -36,14 +38,18 @@ varying vec3 vColor;
varying float vDistance; varying float vDistance;
void main() { void main() {
vec4 worldPos = modelMatrix * vec4(position, 1); vPosition = position;
vec4 color = texture(textureImage, vec2(position.x / 500.0, (position.z + 500.0) / 1000.0));
vPosition.y += color.b * 255.0;
vec4 worldPos = modelMatrix * vec4(vPosition, 1);
vec4 viewPos = viewMatrix * worldPos; vec4 viewPos = viewMatrix * worldPos;
vPosition = position;
vWorldPosition = worldPos.xyz; vWorldPosition = worldPos.xyz;
vNormal = normal; //vNormal = normal;
vUv = uv; //vUv = uv;
vColor = color; //vColor = color;
vDistance = -viewPos.z; vDistance = -viewPos.z;
gl_Position = projectionMatrix * viewPos; gl_Position = projectionMatrix * viewPos;

View File

@ -374,7 +374,7 @@ export const softClamp = (value, min, max, stiffness) => {
} }
export const vecArrToObj = (val, useZ = false) => { export const vecArrToObj = (val, useZ = false) => {
if (val.length >= 2) { if (val && val.length >= 2) {
if (useZ) return {x: val[0], z: val[1]}; if (useZ) return {x: val[0], z: val[1]};
return {x: val[0], y: val[1]}; return {x: val[0], y: val[1]};
} }