mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
feat: allow to render ocean heightmap
This commit is contained in:
parent
52e3088763
commit
cd45ad91fd
17 changed files with 207 additions and 89 deletions
|
|
@ -1310,9 +1310,9 @@
|
||||||
<td>Line style</td>
|
<td>Line style</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="styleHeightmapCurve">
|
<select id="styleHeightmapCurve">
|
||||||
<option value="0" selected>Curved</option>
|
<option value="curveBasisClosed" selected>Curved</option>
|
||||||
<option value="1">Linear</option>
|
<option value="curveLinear">Linear</option>
|
||||||
<option value="2">Rectangular</option>
|
<option value="curveStep">Rectangular</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
6
main.js
6
main.js
|
|
@ -92,16 +92,19 @@ let fogging = viewbox
|
||||||
let ruler = viewbox.append("g").attr("id", "ruler").style("display", "none");
|
let ruler = viewbox.append("g").attr("id", "ruler").style("display", "none");
|
||||||
let debug = viewbox.append("g").attr("id", "debug");
|
let debug = viewbox.append("g").attr("id", "debug");
|
||||||
|
|
||||||
// lake and coast groups
|
|
||||||
lakes.append("g").attr("id", "freshwater");
|
lakes.append("g").attr("id", "freshwater");
|
||||||
lakes.append("g").attr("id", "salt");
|
lakes.append("g").attr("id", "salt");
|
||||||
lakes.append("g").attr("id", "sinkhole");
|
lakes.append("g").attr("id", "sinkhole");
|
||||||
lakes.append("g").attr("id", "frozen");
|
lakes.append("g").attr("id", "frozen");
|
||||||
lakes.append("g").attr("id", "lava");
|
lakes.append("g").attr("id", "lava");
|
||||||
lakes.append("g").attr("id", "dry");
|
lakes.append("g").attr("id", "dry");
|
||||||
|
|
||||||
coastline.append("g").attr("id", "sea_island");
|
coastline.append("g").attr("id", "sea_island");
|
||||||
coastline.append("g").attr("id", "lake_island");
|
coastline.append("g").attr("id", "lake_island");
|
||||||
|
|
||||||
|
terrs.append("g").attr("id", "oceanHeights");
|
||||||
|
terrs.append("g").attr("id", "landHeights");
|
||||||
|
|
||||||
labels.append("g").attr("id", "states");
|
labels.append("g").attr("id", "states");
|
||||||
labels.append("g").attr("id", "addedLabels");
|
labels.append("g").attr("id", "addedLabels");
|
||||||
|
|
||||||
|
|
@ -135,7 +138,6 @@ fogging
|
||||||
.attr("filter", "url(#splotch)");
|
.attr("filter", "url(#splotch)");
|
||||||
|
|
||||||
// assign events separately as not a viewbox child
|
// assign events separately as not a viewbox child
|
||||||
scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => editUnits());
|
|
||||||
legend
|
legend
|
||||||
.on("mousemove", () => tip("Drag to change the position. Click to hide the legend"))
|
.on("mousemove", () => tip("Drag to change the position. Click to hide the legend"))
|
||||||
.on("click", () => clearLegend());
|
.on("click", () => clearLegend());
|
||||||
|
|
|
||||||
|
|
@ -736,4 +736,46 @@ export function resolveVersionConflicts(version) {
|
||||||
.style("display", "none");
|
.style("display", "none");
|
||||||
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
vignette.append("rect").attr("x", 0).attr("y", 0).attr("width", "100%").attr("height", "100%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version < 1.96) {
|
||||||
|
// v1.96 added ocean rendering for heightmap
|
||||||
|
terrs.selectAll("*").remove();
|
||||||
|
|
||||||
|
const opacity = terrs.attr("opacity");
|
||||||
|
const filter = terrs.attr("filter");
|
||||||
|
const scheme = terrs.attr("scheme");
|
||||||
|
const terracing = terrs.attr("terracing");
|
||||||
|
const skip = terrs.attr("skip");
|
||||||
|
const relax = terrs.attr("relax");
|
||||||
|
|
||||||
|
const curveTypes = {0: "curveBasisClosed", 1: "curveLinear", 2: "curveStep"};
|
||||||
|
const curve = curveTypes[terrs.attr("curve")] || "curveBasisClosed";
|
||||||
|
|
||||||
|
terrs.attr("scheme", null).attr("terracing", null).attr("skip", null).attr("relax", null).attr("curve", null);
|
||||||
|
|
||||||
|
terrs
|
||||||
|
.append("g")
|
||||||
|
.attr("id", "oceanHeights")
|
||||||
|
.attr("data-render", 0)
|
||||||
|
.attr("opacity", opacity)
|
||||||
|
.attr("filter", filter)
|
||||||
|
.attr("scheme", scheme)
|
||||||
|
.attr("terracing", 0)
|
||||||
|
.attr("skip", 0)
|
||||||
|
.attr("relax", 1)
|
||||||
|
.attr("curve", curve);
|
||||||
|
terrs
|
||||||
|
.append("g")
|
||||||
|
.attr("id", "landHeights")
|
||||||
|
.attr("opacity", opacity)
|
||||||
|
.attr("scheme", scheme)
|
||||||
|
.attr("filter", filter)
|
||||||
|
.attr("terracing", terracing)
|
||||||
|
.attr("skip", skip)
|
||||||
|
.attr("relax", relax)
|
||||||
|
.attr("curve", curve)
|
||||||
|
.attr("mask", "url(#land)");
|
||||||
|
|
||||||
|
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -468,10 +468,10 @@ async function parseLoadedData(data) {
|
||||||
|
|
||||||
{
|
{
|
||||||
// add custom heightmap color scheme if any
|
// add custom heightmap color scheme if any
|
||||||
const scheme = terrs.attr("scheme");
|
const oceanScheme = terrs.select("#oceanHeights").attr("scheme");
|
||||||
if (!(scheme in heightmapColorSchemes)) {
|
const landScheme = terrs.select("#landHeights").attr("scheme");
|
||||||
addCustomColorScheme(scheme);
|
if (!(oceanScheme in heightmapColorSchemes)) addCustomColorScheme(oceanScheme);
|
||||||
}
|
if (!(landScheme in heightmapColorSchemes)) addCustomColorScheme(landScheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -188,92 +188,134 @@ function restoreLayers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleHeight(event) {
|
function toggleHeight(event) {
|
||||||
if (customization === 1) {
|
if (customization === 1) return tip("You cannot turn off the layer when heightmap is in edit mode", false, "error");
|
||||||
tip("You cannot turn off the layer when heightmap is in edit mode", false, "error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!terrs.selectAll("*").size()) {
|
const children = terrs.selectAll("#oceanHeights > *, #landHeights > *");
|
||||||
|
if (!children.size()) {
|
||||||
turnButtonOn("toggleHeight");
|
turnButtonOn("toggleHeight");
|
||||||
drawHeightmap();
|
drawHeightmap();
|
||||||
if (event && isCtrlClick(event)) editStyle("terrs");
|
if (event && isCtrlClick(event)) editStyle("terrs");
|
||||||
} else {
|
} else {
|
||||||
if (event && isCtrlClick(event)) {
|
if (event && isCtrlClick(event)) return editStyle("terrs");
|
||||||
editStyle("terrs");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
turnButtonOff("toggleHeight");
|
turnButtonOff("toggleHeight");
|
||||||
terrs.selectAll("*").remove();
|
children.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawHeightmap() {
|
function drawHeightmap() {
|
||||||
TIME && console.time("drawHeightmap");
|
TIME && console.time("drawHeightmap");
|
||||||
terrs.selectAll("*").remove();
|
|
||||||
|
|
||||||
const {cells, vertices} = pack;
|
const ocean = terrs.select("#oceanHeights");
|
||||||
const n = cells.i.length;
|
const land = terrs.select("#landHeights");
|
||||||
|
|
||||||
|
ocean.selectAll("*").remove();
|
||||||
|
land.selectAll("*").remove();
|
||||||
|
|
||||||
|
const paths = new Array(101);
|
||||||
|
|
||||||
|
// ocean cells
|
||||||
|
const renderOceanCells = Boolean(+ocean.attr("data-render"));
|
||||||
|
if (renderOceanCells) {
|
||||||
|
const {cells, vertices} = grid;
|
||||||
const used = new Uint8Array(cells.i.length);
|
const used = new Uint8Array(cells.i.length);
|
||||||
const paths = new Array(101).fill("");
|
|
||||||
|
|
||||||
const scheme = getColorScheme(terrs.attr("scheme"));
|
const skip = +ocean.attr("skip") + 1 || 1;
|
||||||
const terracing = terrs.attr("terracing") / 10; // add additional shifted darker layer for pseudo-3d effect
|
const relax = +ocean.attr("relax") || 0;
|
||||||
const skip = +terrs.attr("skip") + 1;
|
|
||||||
const simplification = +terrs.attr("relax");
|
|
||||||
|
|
||||||
switch (+terrs.attr("curve")) {
|
let currentLayer = 0;
|
||||||
case 0:
|
const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]);
|
||||||
lineGen.curve(d3.curveBasisClosed);
|
for (const i of heights) {
|
||||||
break;
|
const h = cells.h[i];
|
||||||
case 1:
|
if (h > currentLayer) currentLayer += skip;
|
||||||
lineGen.curve(d3.curveLinear);
|
if (h < currentLayer) continue;
|
||||||
break;
|
if (currentLayer >= 20) break;
|
||||||
case 2:
|
if (used[i]) continue; // already marked
|
||||||
lineGen.curve(d3.curveStep);
|
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
||||||
break;
|
if (!onborder) continue;
|
||||||
default:
|
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
||||||
lineGen.curve(d3.curveBasisClosed);
|
const chain = connectVertices(cells, vertices, vertex, h, used);
|
||||||
|
if (chain.length < 3) continue;
|
||||||
|
const points = simplifyLine(chain, relax).map(v => vertices.p[v]);
|
||||||
|
if (!paths[h]) paths[h] = "";
|
||||||
|
paths[h] += round(lineGen(points));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// land cells
|
||||||
|
{
|
||||||
|
const {cells, vertices} = pack;
|
||||||
|
const used = new Uint8Array(cells.i.length);
|
||||||
|
|
||||||
|
const skip = +land.attr("skip") + 1 || 1;
|
||||||
|
const relax = +land.attr("relax") || 0;
|
||||||
|
|
||||||
let currentLayer = 20;
|
let currentLayer = 20;
|
||||||
const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]);
|
const heights = cells.i.sort((a, b) => cells.h[a] - cells.h[b]);
|
||||||
for (const i of heights) {
|
for (const i of heights) {
|
||||||
const h = cells.h[i];
|
const h = cells.h[i];
|
||||||
if (h > currentLayer) currentLayer += skip;
|
if (h > currentLayer) currentLayer += skip;
|
||||||
if (currentLayer > 100) break; // no layers possible with height > 100
|
|
||||||
if (h < currentLayer) continue;
|
if (h < currentLayer) continue;
|
||||||
|
if (currentLayer > 100) break; // no layers possible with height > 100
|
||||||
if (used[i]) continue; // already marked
|
if (used[i]) continue; // already marked
|
||||||
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
const onborder = cells.c[i].some(n => cells.h[n] < h);
|
||||||
if (!onborder) continue;
|
if (!onborder) continue;
|
||||||
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
const vertex = cells.v[i].find(v => vertices.c[v].some(i => cells.h[i] < h));
|
||||||
const chain = connectVertices(vertex, h);
|
const chain = connectVertices(cells, vertices, vertex, h, used);
|
||||||
if (chain.length < 3) continue;
|
if (chain.length < 3) continue;
|
||||||
const points = simplifyLine(chain).map(v => vertices.p[v]);
|
const points = simplifyLine(chain, relax).map(v => vertices.p[v]);
|
||||||
|
if (!paths[h]) paths[h] = "";
|
||||||
paths[h] += round(lineGen(points));
|
paths[h] += round(lineGen(points));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
terrs
|
// render paths
|
||||||
|
for (const h of d3.range(0, 101)) {
|
||||||
|
const group = h < 20 ? ocean : land;
|
||||||
|
const scheme = getColorScheme(group.attr("scheme"));
|
||||||
|
|
||||||
|
if (h === 0 && renderOceanCells) {
|
||||||
|
// draw base ocean layer
|
||||||
|
group
|
||||||
.append("rect")
|
.append("rect")
|
||||||
.attr("x", 0)
|
.attr("x", 0)
|
||||||
.attr("y", 0)
|
.attr("y", 0)
|
||||||
.attr("width", graphWidth)
|
.attr("width", graphWidth)
|
||||||
.attr("height", graphHeight)
|
.attr("height", graphHeight)
|
||||||
.attr("fill", scheme(0.8)); // draw base layer
|
.attr("fill", scheme(1));
|
||||||
for (const i of d3.range(20, 101)) {
|
}
|
||||||
if (paths[i].length < 10) continue;
|
|
||||||
const color = getColor(i, scheme);
|
if (h === 20) {
|
||||||
if (terracing)
|
// draw base land layer
|
||||||
terrs
|
group
|
||||||
|
.append("rect")
|
||||||
|
.attr("x", 0)
|
||||||
|
.attr("y", 0)
|
||||||
|
.attr("width", graphWidth)
|
||||||
|
.attr("height", graphHeight)
|
||||||
|
.attr("fill", scheme(0.8));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paths[h] && paths[h].length >= 10) {
|
||||||
|
const curve = group.attr("curve") || "curveBasisClosed";
|
||||||
|
lineGen.curve(d3[curve]);
|
||||||
|
const terracing = group.attr("terracing") / 10 || 0; // shifted darker layer for pseudo-3d effect
|
||||||
|
const color = getColor(h, scheme);
|
||||||
|
|
||||||
|
if (terracing && h >= 20) {
|
||||||
|
land
|
||||||
.append("path")
|
.append("path")
|
||||||
.attr("d", paths[i])
|
.attr("d", paths[h])
|
||||||
.attr("transform", "translate(.7,1.4)")
|
.attr("transform", "translate(.7,1.4)")
|
||||||
.attr("fill", d3.color(color).darker(terracing))
|
.attr("fill", d3.color(color).darker(terracing))
|
||||||
.attr("data-height", i);
|
.attr("data-height", h);
|
||||||
terrs.append("path").attr("d", paths[i]).attr("fill", color).attr("data-height", i);
|
}
|
||||||
|
group.append("path").attr("d", paths[h]).attr("fill", color).attr("data-height", h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect vertices to chain
|
// connect vertices to chain
|
||||||
function connectVertices(start, h) {
|
function connectVertices(cells, vertices, start, h, used) {
|
||||||
|
const n = cells.i.length;
|
||||||
const chain = []; // vertices chain to form a path
|
const chain = []; // vertices chain to form a path
|
||||||
for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
|
for (let i = 0, current = start; i === 0 || (current !== start && i < 20000); i++) {
|
||||||
const prev = chain[chain.length - 1]; // previous vertex in chain
|
const prev = chain[chain.length - 1]; // previous vertex in chain
|
||||||
|
|
@ -295,7 +337,7 @@ function drawHeightmap() {
|
||||||
return chain;
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
function simplifyLine(chain) {
|
function simplifyLine(chain, simplification) {
|
||||||
if (!simplification) return chain;
|
if (!simplification) return chain;
|
||||||
const n = simplification + 1; // filter each nth element
|
const n = simplification + 1; // filter each nth element
|
||||||
return chain.filter((d, i) => i % n === 0);
|
return chain.filter((d, i) => i % n === 0);
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 2,
|
"skip": 2,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "url(#blur3)",
|
"filter": "url(#blur3)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 0,
|
"skip": 0,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 6,
|
"terracing": 6,
|
||||||
"skip": 0,
|
"skip": 0,
|
||||||
"relax": 2,
|
"relax": 2,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "",
|
"filter": "",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -286,13 +286,24 @@
|
||||||
"href": "./images/pattern1.png",
|
"href": "./images/pattern1.png",
|
||||||
"opacity": 0.2
|
"opacity": 0.2
|
||||||
},
|
},
|
||||||
"#terrs": {
|
"#terrs > #oceanHeights": {
|
||||||
"opacity": null,
|
"data-render": 0,
|
||||||
|
"opacity": 1,
|
||||||
|
"scheme": "bright",
|
||||||
|
"terracing": 0,
|
||||||
|
"skip": 0,
|
||||||
|
"relax": 1,
|
||||||
|
"curve": "curveBasisClosed",
|
||||||
|
"filter": null,
|
||||||
|
"mask": null
|
||||||
|
},
|
||||||
|
"#terrs > #landHeights": {
|
||||||
|
"opacity": 1,
|
||||||
"scheme": "bright",
|
"scheme": "bright",
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,9 @@
|
||||||
"terracing": 2,
|
"terracing": 2,
|
||||||
"skip": 1,
|
"skip": 1,
|
||||||
"relax": 2,
|
"relax": 2,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "url(#filter-grayscale)",
|
"filter": "url(#filter-grayscale)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 10,
|
"terracing": 10,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "url(#turbulence)",
|
"filter": "url(#turbulence)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "url(#blur3)",
|
"filter": "url(#blur3)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 10,
|
"skip": 10,
|
||||||
"relax": 0,
|
"relax": 0,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "url(#blurFilter)",
|
"filter": "url(#blurFilter)",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 2,
|
"skip": 2,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": "",
|
"filter": "",
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,9 @@
|
||||||
"terracing": 0,
|
"terracing": 0,
|
||||||
"skip": 5,
|
"skip": 5,
|
||||||
"relax": 1,
|
"relax": 1,
|
||||||
"curve": 0,
|
"curve": "curveBasisClosed",
|
||||||
|
"skipOcean": 0,
|
||||||
|
"relaxOcean": 1,
|
||||||
"filter": null,
|
"filter": null,
|
||||||
"mask": "url(#land)"
|
"mask": "url(#land)"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// version and caching control
|
// version and caching control
|
||||||
const version = "1.95.04"; // generator version, update each time
|
const version = "1.96.00"; // generator version, update each time
|
||||||
|
|
||||||
{
|
{
|
||||||
document.title += " v" + version;
|
document.title += " v" + version;
|
||||||
|
|
@ -28,6 +28,7 @@ const version = "1.95.04"; // generator version, update each time
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<strong>Latest changes:</strong>
|
<strong>Latest changes:</strong>
|
||||||
|
<li>Ability to render ocean heightmap</li>
|
||||||
<li>Vignette visual layer and vignette styling options</li>
|
<li>Vignette visual layer and vignette styling options</li>
|
||||||
<li>Ability to define custom heightmap color scheme</li>
|
<li>Ability to define custom heightmap color scheme</li>
|
||||||
<li>New style preset Night and new heightmap color schemes</li>
|
<li>New style preset Night and new heightmap color schemes</li>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue