mirror of
https://github.com/BlueMap-Minecraft/BlueMapWeb.git
synced 2025-02-19 19:31:41 +01:00
Finalize new lowres tiles implementation
This commit is contained in:
parent
d12c48275f
commit
d9ffe6453f
@ -27,7 +27,7 @@ import {Map} from "./map/Map";
|
||||
import {SkyboxScene} from "./skybox/SkyboxScene";
|
||||
import {ControlsManager} from "./controls/ControlsManager";
|
||||
import Stats from "./util/Stats";
|
||||
import {alert, dispatchEvent, elementOffset, generateCacheHash, htmlToElement} from "./util/Utils";
|
||||
import {alert, dispatchEvent, elementOffset, generateCacheHash, htmlToElement, softClamp} from "./util/Utils";
|
||||
import {TileManager} from "./map/TileManager";
|
||||
import {HIRES_VERTEX_SHADER} from "./map/hires/HiresVertexShader";
|
||||
import {HIRES_FRAGMENT_SHADER} from "./map/hires/HiresFragmentShader";
|
||||
@ -177,7 +177,14 @@ export class MapViewer {
|
||||
this.raycaster.setFromCamera(normalizedScreenPos, this.camera);
|
||||
|
||||
// check Object3D interactions
|
||||
let intersects = this.raycaster.intersectObjects([this.map.hiresTileManager.scene, this.map.lowresTileManager.scene, this.markers], true);
|
||||
/*
|
||||
const intersectScenes = [this.map.hiresTileManager.scene, this.markers];
|
||||
for (let i = 0; i < this.map.lowresTileManager.length; i++) {
|
||||
intersectScenes.push(this.map.lowresTileManager[i].scene);
|
||||
}
|
||||
*/
|
||||
|
||||
let intersects = this.raycaster.intersectObjects([this.map.hiresTileManager.scene, this.markers], true);
|
||||
let hit = null;
|
||||
let lowresHit = null;
|
||||
let hiresHit = null;
|
||||
@ -201,9 +208,11 @@ export class MapViewer {
|
||||
let parentRoot = object;
|
||||
while(parentRoot.parent) parentRoot = parentRoot.parent;
|
||||
|
||||
/*
|
||||
if (parentRoot === this.map.lowresTileManager.scene) {
|
||||
if (!lowresHit) lowresHit = intersects[i];
|
||||
}
|
||||
*/
|
||||
|
||||
if (parentRoot === this.map.hiresTileManager.scene) {
|
||||
if (!hiresHit) hiresHit = intersects[i];
|
||||
@ -216,9 +225,9 @@ export class MapViewer {
|
||||
})) return;
|
||||
}
|
||||
|
||||
if (parentRoot !== this.map.lowresTileManager.scene) {
|
||||
//if (parentRoot !== this.map.lowresTileManager.scene) {
|
||||
covered = true;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -288,8 +297,13 @@ export class MapViewer {
|
||||
//update uniforms
|
||||
this.data.uniforms.hiresTileMap.value.pos.copy(this.map.hiresTileManager.centerTile);
|
||||
|
||||
this.renderer.render(this.map.lowresTileManager.scene, this.camera);
|
||||
this.renderer.clearDepth();
|
||||
const highestLod = this.map.lowresTileManager.length - 1;
|
||||
for (let i = this.map.lowresTileManager.length - 1; i >= 0; i--) {
|
||||
if (i === highestLod || this.controlsManager.distance < 1000 * Math.pow(this.map.data.lowres.lodFactor, i + 1)) {
|
||||
this.renderer.render(this.map.lowresTileManager[i].scene, this.camera);
|
||||
this.renderer.clearDepth();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.controlsManager.distance < 1000) {
|
||||
this.renderer.render(this.map.hiresTileManager.scene, this.camera);
|
||||
@ -363,7 +377,9 @@ export class MapViewer {
|
||||
|
||||
this.tileCacheHash = newTileCacheHash;
|
||||
if (this.map) {
|
||||
this.map.lowresTileManager.tileLoader.tileCacheHash = this.tileCacheHash;
|
||||
for (let i = 0; i < this.map.lowresTileManager.length; i++) {
|
||||
this.map.lowresTileManager[i].tileLoader.tileCacheHash = this.tileCacheHash;
|
||||
}
|
||||
this.map.hiresTileManager.tileLoader.tileCacheHash = this.tileCacheHash;
|
||||
}
|
||||
}
|
||||
|
@ -83,6 +83,9 @@ export class MapControls {
|
||||
|
||||
this.lastTap = -1;
|
||||
this.lastTapCenter = null;
|
||||
|
||||
this.minDistance = 5;
|
||||
this.maxDistance = 100000;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +167,7 @@ export class MapControls {
|
||||
this.keyZoom.update(delta, map);
|
||||
this.touchZoom.update(delta, map);
|
||||
|
||||
this.manager.distance = softClamp(this.manager.distance, 5, 10000, 0.8);
|
||||
this.manager.distance = softClamp(this.manager.distance, this.minDistance, this.maxDistance, 0.8);
|
||||
|
||||
// max angle for current distance
|
||||
let maxAngleForZoom = this.getMaxPerspectiveAngleForDistance(this.manager.distance);
|
||||
|
@ -33,34 +33,37 @@ import {
|
||||
NearestFilter,
|
||||
ClampToEdgeWrapping,
|
||||
NearestMipMapLinearFilter,
|
||||
RepeatWrapping,
|
||||
Vector2
|
||||
} from "three";
|
||||
|
||||
export class LowresTileLoader {
|
||||
|
||||
constructor(tilePath, vertexShader, fragmentShader, tileCacheHash = 0, layer = 0) {
|
||||
constructor(tilePath, tileSettings, lod, vertexShader, fragmentShader, uniforms, tileCacheHash = 0, layer = 0) {
|
||||
Object.defineProperty( this, 'isLowresTileLoader', { value: true } );
|
||||
|
||||
this.tilePath = tilePath;
|
||||
this.tileSettings = tileSettings;
|
||||
this.lod = lod;
|
||||
this.layer = layer;
|
||||
this.tileCacheHash = tileCacheHash;
|
||||
|
||||
this.vertexShader = vertexShader;
|
||||
this.fragmentShader = fragmentShader;
|
||||
this.uniforms = uniforms;
|
||||
|
||||
this.textureLoader = new TextureLoader();
|
||||
this.geometry = new PlaneBufferGeometry(
|
||||
500, 500,
|
||||
100, 100
|
||||
tileSettings.tileSize.x + 1, tileSettings.tileSize.z + 1,
|
||||
Math.ceil(100 / (lod * 2)), Math.ceil(100 / (lod * 2))
|
||||
);
|
||||
this.geometry.deleteAttribute('normal');
|
||||
this.geometry.deleteAttribute('uv');
|
||||
this.geometry.rotateX(-Math.PI / 2);
|
||||
this.geometry.translate(250, 0, 250);
|
||||
this.geometry.translate(tileSettings.tileSize.x / 2 + 1, 0, tileSettings.tileSize.x / 2 + 1);
|
||||
}
|
||||
|
||||
load = (tileX, tileZ) => {
|
||||
let tileUrl = this.tilePath + pathFromCoords(tileX, tileZ) + '.png';
|
||||
let tileUrl = this.tilePath + this.lod + "/" + pathFromCoords(tileX, tileZ) + '.png';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.textureLoader.load(tileUrl + '?' + this.tileCacheHash,
|
||||
@ -76,6 +79,13 @@ export class LowresTileLoader {
|
||||
|
||||
let material = new ShaderMaterial({
|
||||
uniforms: {
|
||||
...this.uniforms,
|
||||
tileSize: {
|
||||
value: new Vector2(this.tileSettings.tileSize.x, this.tileSettings.tileSize.z)
|
||||
},
|
||||
textureSize: {
|
||||
value: new Vector2(texture.image.width, texture.image.height)
|
||||
},
|
||||
textureImage: {
|
||||
type: 't',
|
||||
value: texture
|
||||
@ -94,13 +104,12 @@ export class LowresTileLoader {
|
||||
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);
|
||||
const scale = Math.pow(this.tileSettings.lodFactor, this.lod - 1);
|
||||
object.position.set(tileX * this.tileSettings.tileSize.x * scale, 0, tileZ * this.tileSettings.tileSize.z * scale);
|
||||
object.scale.set(scale, 1, scale);
|
||||
|
||||
object.userData.tileUrl = tileUrl;
|
||||
object.userData.tileType = "lowres";
|
||||
|
||||
object.updateMatrixWorld(true);
|
||||
|
||||
|
@ -36,7 +36,7 @@ import {
|
||||
Vector3,
|
||||
VertexColors
|
||||
} from "three";
|
||||
import {alert, dispatchEvent, generateCacheHash, hashTile, stringToImage, vecArrToObj} from "../util/Utils";
|
||||
import {alert, dispatchEvent, generateCacheHash, getPixel, hashTile, stringToImage, vecArrToObj} from "../util/Utils";
|
||||
import {TileManager} from "./TileManager";
|
||||
import {TileLoader} from "./TileLoader";
|
||||
import {LowresTileLoader} from "./LowresTileLoader";
|
||||
@ -70,8 +70,8 @@ export class Map {
|
||||
},
|
||||
lowres: {
|
||||
tileSize: {x: 32, z: 32},
|
||||
scale: {x: 1, z: 1},
|
||||
translate: {x: 2, z: 2}
|
||||
lodFactor: 5,
|
||||
lodCount: 3
|
||||
}
|
||||
};
|
||||
|
||||
@ -86,7 +86,7 @@ export class Map {
|
||||
|
||||
/** @type {TileManager} */
|
||||
this.hiresTileManager = null;
|
||||
/** @type {TileManager} */
|
||||
/** @type {TileManager[]} */
|
||||
this.lowresTileManager = null;
|
||||
}
|
||||
|
||||
@ -116,10 +116,13 @@ export class Map {
|
||||
this.hiresMaterial = this.createHiresMaterial(hiresVertexShader, hiresFragmentShader, uniforms, textures);
|
||||
|
||||
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 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 = [];
|
||||
for (let i = 0; i < this.data.lowres.lodCount; i++) {
|
||||
this.lowresTileManager[i] = new TileManager(new Scene(), new LowresTileLoader(`${this.data.dataUrl}tiles/`, this.data.lowres, i + 1, lowresVertexShader, lowresFragmentShader, uniforms, tileCacheHash), this.onTileLoad("lowres"), this.onTileUnload("lowres"), this.events);
|
||||
this.lowresTileManager[i].scene.autoUpdate = false;
|
||||
}
|
||||
|
||||
alert(this.events, `Map '${this.data.id}' is loaded.`, "fine");
|
||||
});
|
||||
@ -158,8 +161,8 @@ export class Map {
|
||||
};
|
||||
this.data.lowres = {
|
||||
tileSize: {...this.data.lowres.tileSize, ...vecArrToObj(worldSettings.lowres.tileSize, true)},
|
||||
scale: {...this.data.lowres.scale, ...vecArrToObj(worldSettings.lowres.scale, true)},
|
||||
translate: {...this.data.lowres.translate, ...vecArrToObj(worldSettings.lowres.translate, true)}
|
||||
lodFactor: worldSettings.lowres.lodFactor !== undefined ? worldSettings.lowres.lodFactor : this.data.lowres.lodFactor,
|
||||
lodCount: worldSettings.lowres.lodCount !== undefined ? worldSettings.lowres.lodCount : this.data.lowres.lodCount
|
||||
};
|
||||
|
||||
alert(this.events, `Settings for map '${this.data.id}' loaded.`, "fine");
|
||||
@ -189,18 +192,21 @@ export class Map {
|
||||
loadMapArea(x, z, hiresViewDistance, lowresViewDistance) {
|
||||
if (!this.isLoaded) return;
|
||||
|
||||
let hiresX = Math.floor((x - this.data.hires.translate.x) / this.data.hires.tileSize.x);
|
||||
let hiresZ = Math.floor((z - this.data.hires.translate.z) / this.data.hires.tileSize.z);
|
||||
let hiresViewX = Math.floor(hiresViewDistance / this.data.hires.tileSize.x);
|
||||
let hiresViewZ = Math.floor(hiresViewDistance / this.data.hires.tileSize.z);
|
||||
|
||||
let lowresX = Math.floor((x - this.data.lowres.translate.x) / this.data.lowres.tileSize.x);
|
||||
let lowresZ = Math.floor((z - this.data.lowres.translate.z) / this.data.lowres.tileSize.z);
|
||||
let lowresViewX = Math.floor(lowresViewDistance / this.data.lowres.tileSize.x);
|
||||
let lowresViewZ = Math.floor(lowresViewDistance / this.data.lowres.tileSize.z);
|
||||
|
||||
const hiresX = Math.floor((x - this.data.hires.translate.x) / this.data.hires.tileSize.x);
|
||||
const hiresZ = Math.floor((z - this.data.hires.translate.z) / this.data.hires.tileSize.z);
|
||||
const hiresViewX = Math.floor(hiresViewDistance / this.data.hires.tileSize.x);
|
||||
const hiresViewZ = Math.floor(hiresViewDistance / this.data.hires.tileSize.z);
|
||||
this.hiresTileManager.loadAroundTile(hiresX, hiresZ, hiresViewX, hiresViewZ);
|
||||
this.lowresTileManager.loadAroundTile(lowresX, lowresZ, lowresViewX, lowresViewZ);
|
||||
|
||||
for (let i = 0; i < this.lowresTileManager.length; i++) {
|
||||
const lod = i + 1;
|
||||
const scale = Math.pow(this.data.lowres.lodFactor, lod - 1);
|
||||
const lowresX = Math.floor(x / (this.data.lowres.tileSize.x * scale));
|
||||
const lowresZ = Math.floor(z / (this.data.lowres.tileSize.z * scale));
|
||||
const lowresViewX = Math.floor(lowresViewDistance / this.data.lowres.tileSize.x);
|
||||
const lowresViewZ = Math.floor(lowresViewDistance / this.data.lowres.tileSize.z);
|
||||
this.lowresTileManager[i].loadAroundTile(lowresX, lowresZ, lowresViewX, lowresViewZ);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -332,8 +338,12 @@ export class Map {
|
||||
if (this.hiresTileManager) this.hiresTileManager.unload();
|
||||
this.hiresTileManager = null;
|
||||
|
||||
if (this.lowresTileManager) this.lowresTileManager.unload();
|
||||
this.lowresTileManager = null;
|
||||
if (this.lowresTileManager) {
|
||||
for (let i = 0; i < this.lowresTileManager.length; i++) {
|
||||
this.lowresTileManager[i].unload();
|
||||
}
|
||||
this.lowresTileManager = null;
|
||||
}
|
||||
|
||||
if (this.hiresMaterial) this.hiresMaterial.forEach(material => material.dispose());
|
||||
this.hiresMaterial = null;
|
||||
@ -364,23 +374,40 @@ export class Map {
|
||||
|
||||
let hiresTileHash = hashTile(Math.floor((x - this.data.hires.translate.x) / this.data.hires.tileSize.x), Math.floor((z - this.data.hires.translate.z) / this.data.hires.tileSize.z));
|
||||
let tile = this.hiresTileManager.tiles.get(hiresTileHash);
|
||||
if (!tile || !tile.model) {
|
||||
let lowresTileHash = hashTile(Math.floor((x - this.data.lowres.translate.x) / this.data.lowres.tileSize.x), Math.floor((z - this.data.lowres.translate.z) / this.data.lowres.tileSize.z));
|
||||
tile = this.lowresTileManager.tiles.get(lowresTileHash);
|
||||
}
|
||||
|
||||
if (!tile || !tile.model){
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
let intersects = this.raycaster.intersectObjects([tile.model]);
|
||||
if (intersects.length > 0) {
|
||||
return intersects[0].point.y;
|
||||
if (tile?.model) {
|
||||
try {
|
||||
let intersects = this.raycaster.intersectObjects([tile.model]);
|
||||
if (intersects.length > 0) {
|
||||
return intersects[0].point.y;
|
||||
}
|
||||
} catch (ignore) {
|
||||
//empty
|
||||
}
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.lowresTileManager.length; i++) {
|
||||
const lod = i + 1;
|
||||
const scale = Math.pow(this.data.lowres.lodFactor, lod - 1);
|
||||
const scaledTileSize = {
|
||||
x: this.data.lowres.tileSize.x * scale,
|
||||
z: this.data.lowres.tileSize.z * scale
|
||||
}
|
||||
const tileX = Math.floor(x / scaledTileSize.x);
|
||||
const tileZ = Math.floor(z / scaledTileSize.z);
|
||||
let lowresTileHash = hashTile(tileX, tileZ);
|
||||
tile = this.lowresTileManager[i].tiles.get(lowresTileHash);
|
||||
|
||||
if (!tile || !tile.model) continue;
|
||||
|
||||
const texture = tile.model.material.uniforms?.textureImage?.value?.image;
|
||||
if (texture == null) continue;
|
||||
|
||||
const color = getPixel(texture, x - tileX * scaledTileSize.x, z - tileZ * scaledTileSize.z + this.data.lowres.tileSize.z);
|
||||
return color[2];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
@ -60,7 +60,7 @@ export class Tile {
|
||||
return tileLoader.load(this.x, this.z)
|
||||
.then(model => {
|
||||
if (this.unloaded){
|
||||
model.geometry.dispose();
|
||||
Tile.disposeModel(model);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -77,11 +77,23 @@ export class Tile {
|
||||
if (this.model) {
|
||||
this.onUnload(this);
|
||||
|
||||
this.model.geometry.dispose();
|
||||
Tile.disposeModel(this.model);
|
||||
|
||||
this.model = null;
|
||||
}
|
||||
}
|
||||
|
||||
static disposeModel(model) {
|
||||
if (model.userData?.tileType === "hires") {
|
||||
model.geometry.dispose();
|
||||
}
|
||||
|
||||
else if (model.userData?.tileType === "lowres") {
|
||||
model.material.uniforms.textureImage.value.dispose();
|
||||
model.material.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
@ -79,6 +79,7 @@ export class TileLoader {
|
||||
object.scale.set(scale.x, 1, scale.z);
|
||||
|
||||
object.userData.tileUrl = tileUrl;
|
||||
object.userData.tileType = "hires";
|
||||
|
||||
object.updateMatrixWorld(true);
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
import {ClampToEdgeWrapping, LinearFilter, Texture} from "three";
|
||||
import {ClampToEdgeWrapping, LinearFilter, NearestFilter, Texture} from "three";
|
||||
|
||||
export class TileMap {
|
||||
|
||||
|
@ -39,41 +39,59 @@ struct TileMap {
|
||||
vec2 pos;
|
||||
};
|
||||
|
||||
//uniform float sunlightStrength;
|
||||
//uniform float ambientLight;
|
||||
//uniform TileMap hiresTileMap;
|
||||
uniform float sunlightStrength;
|
||||
uniform float ambientLight;
|
||||
uniform TileMap hiresTileMap;
|
||||
uniform sampler2D textureImage;
|
||||
uniform vec2 tileSize;
|
||||
uniform vec2 textureSize;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 vWorldPosition;
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vUv;
|
||||
varying vec3 vColor;
|
||||
varying float vDistance;
|
||||
|
||||
float metaToHeight(vec4 meta) {
|
||||
float heightUnsigned = meta.g * 65280.0 + meta.b * 255.0;
|
||||
if (heightUnsigned >= 32768.0) {
|
||||
return -(65535.0 - heightUnsigned);
|
||||
} else {
|
||||
return heightUnsigned;
|
||||
}
|
||||
}
|
||||
|
||||
float metaToLight(vec4 meta) {
|
||||
return meta.r * 255.0;
|
||||
}
|
||||
|
||||
vec2 posToColorUV(vec2 pos) {
|
||||
return vec2(pos.x / textureSize.x, min(pos.y, tileSize.y) / textureSize.y);
|
||||
}
|
||||
|
||||
vec2 posToMetaUV(vec2 pos) {
|
||||
return vec2(pos.x / textureSize.x, pos.y / textureSize.y + 0.5);
|
||||
}
|
||||
|
||||
void main() {
|
||||
//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 < 900.0 && texture(hiresTileMap.map, ((vWorldPosition.xz - hiresTileMap.translate) / hiresTileMap.scale - hiresTileMap.pos) / hiresTileMap.size + 0.5).r > 0.75) discard;
|
||||
|
||||
//vec4 color = vec4(vColor, 1.0);
|
||||
|
||||
//float diff = max(dot(vNormal, vec3(0.3637, 0.7274, 0.5819)), 0.0) * 0.3 + 0.7;
|
||||
//color *= diff;
|
||||
|
||||
//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));
|
||||
vec4 color = texture(textureImage, posToColorUV(vPosition.xz));
|
||||
vec4 meta = texture(textureImage, posToMetaUV(vPosition.xz));
|
||||
|
||||
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 height = metaToHeight(meta);
|
||||
|
||||
float heightX = metaToHeight(texture(textureImage, posToMetaUV(vPosition.xz + vec2(1.0, 0.0))));
|
||||
float heightZ = metaToHeight(texture(textureImage, posToMetaUV(vPosition.xz + vec2(0.0, 1.0))));
|
||||
float diff = (height - heightX) + (height - heightZ);
|
||||
|
||||
color.rgb += clamp(diff * 0.04, -0.2, 0.04);
|
||||
|
||||
float blockLight = metaToLight(meta);
|
||||
float light = mix(blockLight, 15.0, sunlightStrength);
|
||||
color.rgb *= mix(ambientLight, 1.0, light / 15.0);
|
||||
|
||||
gl_FragColor = color;
|
||||
|
||||
${ShaderChunk.logdepthbuf_fragment}
|
||||
}
|
||||
|
||||
`;
|
||||
|
@ -29,31 +29,41 @@ export const LOWRES_VERTEX_SHADER = `
|
||||
${ShaderChunk.logdepthbuf_pars_vertex}
|
||||
|
||||
uniform sampler2D textureImage;
|
||||
uniform vec2 tileSize;
|
||||
uniform vec2 textureSize;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 vWorldPosition;
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vUv;
|
||||
varying vec3 vColor;
|
||||
varying float vDistance;
|
||||
|
||||
float metaToHeight(vec4 meta) {
|
||||
float heightUnsigned = meta.g * 65280.0 + meta.b * 255.0;
|
||||
if (heightUnsigned >= 32768.0) {
|
||||
return -(65535.0 - heightUnsigned);
|
||||
} else {
|
||||
return heightUnsigned;
|
||||
}
|
||||
}
|
||||
|
||||
vec2 posToMetaUV(vec2 pos) {
|
||||
return vec2(pos.x / textureSize.x, pos.y / textureSize.y + 0.5);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vPosition = position;
|
||||
|
||||
vec4 color = texture(textureImage, vec2(position.x / 500.0, (position.z + 500.0) / 1000.0));
|
||||
vPosition.y += color.b * 255.0;
|
||||
vec4 meta = texture(textureImage, posToMetaUV(position.xz));
|
||||
vPosition.y += metaToHeight(meta);
|
||||
|
||||
vec4 worldPos = modelMatrix * vec4(vPosition, 1);
|
||||
vec4 viewPos = viewMatrix * worldPos;
|
||||
|
||||
vWorldPosition = worldPos.xyz;
|
||||
//vNormal = normal;
|
||||
//vUv = uv;
|
||||
//vColor = color;
|
||||
vDistance = -viewPos.z;
|
||||
|
||||
gl_Position = projectionMatrix * viewPos;
|
||||
|
||||
${ShaderChunk.logdepthbuf_vertex}
|
||||
}
|
||||
|
||||
`;
|
||||
|
@ -380,3 +380,13 @@ export const vecArrToObj = (val, useZ = false) => {
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
const pixel = document.createElement('canvas');
|
||||
pixel.width = 1;
|
||||
pixel.height = 1;
|
||||
const pixelContext = pixel.getContext('2d');
|
||||
|
||||
export const getPixel = (img, x, y) => {
|
||||
pixelContext.drawImage(img, x, y, 1, 1, 0, 0, 1, 1);
|
||||
return pixelContext.getImageData(0, 0, 1, 1).data;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user