mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:50:42 +00:00
Update terrain shader parameters
- Modified terrain shader parameters in GroundTruthData for better rendering. - Added new user-configurable settings for water effects in TerrainShaderRegistry. - Enhanced terrain compute shaders to incorporate water depth and blur adjustments. - Refactored shader logic to improve water color blending and depth calculations
This commit is contained in:
@@ -101,8 +101,8 @@ export class GroundTruthData {
|
||||
|
||||
private territoryShaderParams0 = new Float32Array(4);
|
||||
private territoryShaderParams1 = new Float32Array(4);
|
||||
private terrainShaderParams0 = new Float32Array([0.0, 2.5, 0.6, 0.7]);
|
||||
private terrainShaderParams1 = new Float32Array([0.0, 0.9, 0.6, 0.05]);
|
||||
private terrainShaderParams0 = new Float32Array([0.0, 2.5, 1.0, 0.0]);
|
||||
private terrainShaderParams1 = new Float32Array([0.6, 0.0, 0.0, 0.0]);
|
||||
|
||||
private paletteMaxSmallId = 0;
|
||||
private ownerIndexWidth = 1;
|
||||
|
||||
@@ -63,6 +63,15 @@ export const TERRAIN_SHADERS: TerrainShaderDefinition[] = [
|
||||
max: 5,
|
||||
step: 0.25,
|
||||
},
|
||||
{
|
||||
kind: "range",
|
||||
key: "settings.webgpu.terrain.improvedLite.waterBlurStrength",
|
||||
label: "Water Blur Strength",
|
||||
defaultValue: 1,
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.05,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -97,6 +106,33 @@ export const TERRAIN_SHADERS: TerrainShaderDefinition[] = [
|
||||
max: 6,
|
||||
step: 0.25,
|
||||
},
|
||||
{
|
||||
kind: "range",
|
||||
key: "settings.webgpu.terrain.improvedHeavy.waterDepthStrength",
|
||||
label: "Water Depth Strength",
|
||||
defaultValue: 0.35,
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.05,
|
||||
},
|
||||
{
|
||||
kind: "range",
|
||||
key: "settings.webgpu.terrain.improvedHeavy.waterDepthCurve",
|
||||
label: "Water Depth Curve",
|
||||
defaultValue: 2,
|
||||
min: 0.5,
|
||||
max: 4,
|
||||
step: 0.25,
|
||||
},
|
||||
{
|
||||
kind: "range",
|
||||
key: "settings.webgpu.terrain.improvedHeavy.waterDepthBlur",
|
||||
label: "Water Depth Blur",
|
||||
defaultValue: 0.6,
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 0.05,
|
||||
},
|
||||
{
|
||||
kind: "range",
|
||||
key: "settings.webgpu.terrain.improvedHeavy.lightingStrength",
|
||||
@@ -153,9 +189,9 @@ export function buildTerrainShaderParams(
|
||||
},
|
||||
shaderId: TerrainShaderId,
|
||||
): { shaderPath: string; params0: Float32Array; params1: Float32Array } {
|
||||
const shorelineMixLand = 0.6;
|
||||
const shorelineMixWater = 0.7;
|
||||
const specularStrength = 0.05;
|
||||
const waterDepthStrengthDefault = 0.4;
|
||||
const waterDepthCurveDefault = 2;
|
||||
const waterDepthBlurDefault = 0.6;
|
||||
|
||||
if (shaderId === "improved-lite") {
|
||||
const noiseStrength = userSettings.getFloat(
|
||||
@@ -166,14 +202,17 @@ export function buildTerrainShaderParams(
|
||||
"settings.webgpu.terrain.improvedLite.blendWidth",
|
||||
5,
|
||||
);
|
||||
|
||||
const waterBlurStrength = userSettings.getFloat(
|
||||
"settings.webgpu.terrain.improvedLite.waterBlurStrength",
|
||||
1,
|
||||
);
|
||||
const params0 = new Float32Array([
|
||||
noiseStrength,
|
||||
blendWidth,
|
||||
shorelineMixLand,
|
||||
shorelineMixWater,
|
||||
waterBlurStrength,
|
||||
0,
|
||||
]);
|
||||
const params1 = new Float32Array([0, 0, 0, specularStrength]);
|
||||
const params1 = new Float32Array([0, 0, 0, 0]);
|
||||
return {
|
||||
shaderPath: "compute/terrain-compute-improved-lite.wgsl",
|
||||
params0,
|
||||
@@ -194,6 +233,18 @@ export function buildTerrainShaderParams(
|
||||
"settings.webgpu.terrain.improvedHeavy.blendWidth",
|
||||
4.5,
|
||||
);
|
||||
const waterDepthStrength = userSettings.getFloat(
|
||||
"settings.webgpu.terrain.improvedHeavy.waterDepthStrength",
|
||||
0.35,
|
||||
);
|
||||
const waterDepthCurve = userSettings.getFloat(
|
||||
"settings.webgpu.terrain.improvedHeavy.waterDepthCurve",
|
||||
2,
|
||||
);
|
||||
const waterDepthBlur = userSettings.getFloat(
|
||||
"settings.webgpu.terrain.improvedHeavy.waterDepthBlur",
|
||||
0.6,
|
||||
);
|
||||
const lightingStrength = userSettings.getFloat(
|
||||
"settings.webgpu.terrain.improvedHeavy.lightingStrength",
|
||||
0.3,
|
||||
@@ -206,14 +257,14 @@ export function buildTerrainShaderParams(
|
||||
const params0 = new Float32Array([
|
||||
noiseStrength,
|
||||
blendWidth,
|
||||
shorelineMixLand,
|
||||
shorelineMixWater,
|
||||
waterDepthStrength,
|
||||
waterDepthCurve,
|
||||
]);
|
||||
const params1 = new Float32Array([
|
||||
detailNoiseStrength,
|
||||
lightingStrength,
|
||||
cavityStrength,
|
||||
specularStrength,
|
||||
waterDepthBlur,
|
||||
]);
|
||||
return {
|
||||
shaderPath: "compute/terrain-compute-improved-heavy.wgsl",
|
||||
@@ -225,9 +276,9 @@ export function buildTerrainShaderParams(
|
||||
const params0 = new Float32Array([
|
||||
0,
|
||||
2.5,
|
||||
shorelineMixLand,
|
||||
shorelineMixWater,
|
||||
waterDepthStrengthDefault,
|
||||
waterDepthCurveDefault,
|
||||
]);
|
||||
const params1 = new Float32Array([0, 0, 0, specularStrength]);
|
||||
const params1 = new Float32Array([waterDepthBlurDefault, 0, 0, 0]);
|
||||
return { shaderPath: "compute/terrain-compute.wgsl", params0, params1 };
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ struct TerrainParams {
|
||||
plainsBaseColor: vec4f, // Plains base RGB (magnitude 0)
|
||||
highlandBaseColor: vec4f, // Highland base RGB (magnitude 10)
|
||||
mountainBaseColor: vec4f, // Mountain base RGB (magnitude 20)
|
||||
tuning0: vec4f, // x=noiseStrength, y=blendWidth, z=shoreMixLand, w=shoreMixWater
|
||||
tuning1: vec4f, // x=detailNoise, y=lightingStrength, z=cavityStrength, w=specularStrength
|
||||
tuning0: vec4f, // x=noiseStrength, y=blendWidth, z=waterDepthStrength, w=waterDepthCurve
|
||||
tuning1: vec4f, // x=detailNoise, y=lightingStrength, z=cavityStrength, w=waterDepthBlur
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> params: TerrainParams;
|
||||
@@ -34,10 +34,9 @@ fn clampCoord(coord: vec2i, dims: vec2u) -> vec2i {
|
||||
return vec2i(clamp(coord.x, 0, maxX), clamp(coord.y, 0, maxY));
|
||||
}
|
||||
|
||||
fn sampleMagnitude(coord: vec2i, dims: vec2u) -> f32 {
|
||||
fn sampleTerrainData(coord: vec2i, dims: vec2u) -> u32 {
|
||||
let c = clampCoord(coord, dims);
|
||||
let data = textureLoad(terrainDataTex, c, 0).x;
|
||||
return f32(data & MAGNITUDE_MASK);
|
||||
return textureLoad(terrainDataTex, c, 0).x;
|
||||
}
|
||||
|
||||
fn computeLandColor(
|
||||
@@ -69,14 +68,6 @@ fn computeLandColor(
|
||||
return clamp(land + vec3f(noiseBias), vec3f(0.0), vec3f(1.0));
|
||||
}
|
||||
|
||||
fn computeWaterColor(mag: f32, noise: f32, noiseStrength: f32) -> vec3f {
|
||||
let depth = clamp(mag / 10.0, 0.0, 1.0);
|
||||
var water = mix(params.shorelineWaterColor.rgb, params.waterColor.rgb, depth);
|
||||
let noiseBias = (noise - 0.5) * noiseStrength;
|
||||
water = clamp(water + vec3f(noiseBias), vec3f(0.0), vec3f(1.0));
|
||||
return water;
|
||||
}
|
||||
|
||||
@compute @workgroup_size(8, 8)
|
||||
fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
let x = i32(globalId.x);
|
||||
@@ -99,18 +90,31 @@ fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
let noiseFine = hash21(vec2u(texCoord) * 3u + vec2u(17u, 29u));
|
||||
let noiseStrength = max(params.tuning0.x, 0.0);
|
||||
let blendWidth = max(params.tuning0.y, 0.1);
|
||||
let shoreMixLand = clamp(params.tuning0.z, 0.0, 1.0);
|
||||
let shoreMixWater = clamp(params.tuning0.w, 0.0, 1.0);
|
||||
let waterDepthStrength = clamp(params.tuning0.z, 0.0, 1.0);
|
||||
let waterDepthCurve = max(params.tuning0.w, 0.1);
|
||||
let detailNoiseStrength = max(params.tuning1.x, 0.0);
|
||||
let lightingStrength = clamp(params.tuning1.y, 0.0, 1.0);
|
||||
let cavityStrength = clamp(params.tuning1.z, 0.0, 1.0);
|
||||
let specularStrength = max(params.tuning1.w, 0.0);
|
||||
let waterDepthBlur = clamp(params.tuning1.w, 0.0, 1.0);
|
||||
let shoreMixLand = 0.6;
|
||||
let shoreMixWater = 0.55;
|
||||
let specularStrength = 0.05;
|
||||
|
||||
let hC = mag / 31.0;
|
||||
let hL = sampleMagnitude(texCoord + vec2i(-1, 0), dims) / 31.0;
|
||||
let hR = sampleMagnitude(texCoord + vec2i(1, 0), dims) / 31.0;
|
||||
let hD = sampleMagnitude(texCoord + vec2i(0, -1), dims) / 31.0;
|
||||
let hU = sampleMagnitude(texCoord + vec2i(0, 1), dims) / 31.0;
|
||||
let dataL = sampleTerrainData(texCoord + vec2i(-1, 0), dims);
|
||||
let dataR = sampleTerrainData(texCoord + vec2i(1, 0), dims);
|
||||
let dataD = sampleTerrainData(texCoord + vec2i(0, -1), dims);
|
||||
let dataU = sampleTerrainData(texCoord + vec2i(0, 1), dims);
|
||||
|
||||
let magL = f32(dataL & MAGNITUDE_MASK);
|
||||
let magR = f32(dataR & MAGNITUDE_MASK);
|
||||
let magD = f32(dataD & MAGNITUDE_MASK);
|
||||
let magU = f32(dataU & MAGNITUDE_MASK);
|
||||
|
||||
let hL = magL / 31.0;
|
||||
let hR = magR / 31.0;
|
||||
let hD = magD / 31.0;
|
||||
let hU = magU / 31.0;
|
||||
|
||||
let dx = hR - hL;
|
||||
let dy = hU - hD;
|
||||
@@ -146,7 +150,37 @@ fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
|
||||
color = vec4f(land, 1.0);
|
||||
} else {
|
||||
var water = computeWaterColor(mag, noise, noiseStrength * 0.6);
|
||||
var sum = mag;
|
||||
var count = 1.0;
|
||||
if ((dataL & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + magL;
|
||||
count = count + 1.0;
|
||||
}
|
||||
if ((dataR & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + magR;
|
||||
count = count + 1.0;
|
||||
}
|
||||
if ((dataD & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + magD;
|
||||
count = count + 1.0;
|
||||
}
|
||||
if ((dataU & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + magU;
|
||||
count = count + 1.0;
|
||||
}
|
||||
|
||||
let avgMag = sum / count;
|
||||
let smoothMag = mix(mag, avgMag, waterDepthBlur);
|
||||
let depth01 = clamp(smoothMag / 10.0, 0.0, 1.0);
|
||||
let depth = clamp(pow(depth01, waterDepthCurve), 0.0, 1.0);
|
||||
let depthColor = mix(
|
||||
params.shorelineWaterColor.rgb,
|
||||
params.waterColor.rgb,
|
||||
depth,
|
||||
);
|
||||
var water = mix(params.waterColor.rgb, depthColor, waterDepthStrength);
|
||||
let noiseBias = (noise - 0.5) * (noiseStrength * 0.6);
|
||||
water = clamp(water + vec3f(noiseBias), vec3f(0.0), vec3f(1.0));
|
||||
|
||||
if (isShoreline) {
|
||||
water = mix(water, params.shorelineWaterColor.rgb, shoreMixWater);
|
||||
|
||||
@@ -5,8 +5,7 @@ struct TerrainParams {
|
||||
plainsBaseColor: vec4f, // Plains base RGB (magnitude 0)
|
||||
highlandBaseColor: vec4f, // Highland base RGB (magnitude 10)
|
||||
mountainBaseColor: vec4f, // Mountain base RGB (magnitude 20)
|
||||
tuning0: vec4f, // x=noiseStrength, y=blendWidth, z=shoreMixLand, w=shoreMixWater
|
||||
tuning1: vec4f, // unused in lite
|
||||
tuning0: vec4f, // x=noiseStrength, y=blendWidth, z=waterBlurStrength, w=unused
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> params: TerrainParams;
|
||||
@@ -28,6 +27,12 @@ fn hash21(p: vec2u) -> f32 {
|
||||
return f32(n & 0x00ffffffu) / 16777215.0;
|
||||
}
|
||||
|
||||
fn clampCoord(coord: vec2i, dims: vec2u) -> vec2i {
|
||||
let maxX = i32(dims.x) - 1;
|
||||
let maxY = i32(dims.y) - 1;
|
||||
return vec2i(clamp(coord.x, 0, maxX), clamp(coord.y, 0, maxY));
|
||||
}
|
||||
|
||||
fn computeLandColor(mag: f32, noise: f32, noiseStrength: f32, blendWidth: f32) -> vec3f {
|
||||
let plainsG = max(params.plainsBaseColor.g - (2.0 * mag) / 255.0, 0.0);
|
||||
let plains = vec3f(params.plainsBaseColor.r, plainsG, params.plainsBaseColor.b);
|
||||
@@ -52,14 +57,6 @@ fn computeLandColor(mag: f32, noise: f32, noiseStrength: f32, blendWidth: f32) -
|
||||
return clamp(land + vec3f(noiseBias), vec3f(0.0), vec3f(1.0));
|
||||
}
|
||||
|
||||
fn computeWaterColor(mag: f32, noise: f32, noiseStrength: f32) -> vec3f {
|
||||
let depth = clamp(mag / 10.0, 0.0, 1.0);
|
||||
var water = mix(params.shorelineWaterColor.rgb, params.waterColor.rgb, depth);
|
||||
let noiseBias = (noise - 0.5) * noiseStrength;
|
||||
water = clamp(water + vec3f(noiseBias), vec3f(0.0), vec3f(1.0));
|
||||
return water;
|
||||
}
|
||||
|
||||
@compute @workgroup_size(8, 8)
|
||||
fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
let x = i32(globalId.x);
|
||||
@@ -81,8 +78,8 @@ fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
let noise = hash21(vec2u(texCoord));
|
||||
let noiseStrength = max(params.tuning0.x, 0.0);
|
||||
let blendWidth = max(params.tuning0.y, 0.1);
|
||||
let shoreMixLand = clamp(params.tuning0.z, 0.0, 1.0);
|
||||
let shoreMixWater = clamp(params.tuning0.w, 0.0, 1.0);
|
||||
let waterDepthBlur = clamp(params.tuning0.z, 0.0, 1.0);
|
||||
let shoreMixLand = 0.6;
|
||||
var color: vec4f;
|
||||
|
||||
if (isLand) {
|
||||
@@ -92,10 +89,44 @@ fn main(@builtin(global_invocation_id) globalId: vec3<u32>) {
|
||||
}
|
||||
color = vec4f(land, 1.0);
|
||||
} else {
|
||||
var water = computeWaterColor(mag, noise, noiseStrength * 0.6);
|
||||
if (isShoreline) {
|
||||
water = mix(water, params.shorelineWaterColor.rgb, shoreMixWater);
|
||||
color = vec4f(params.shorelineWaterColor.rgb, 1.0);
|
||||
textureStore(terrainTex, texCoord, color);
|
||||
return;
|
||||
}
|
||||
|
||||
var sum = mag;
|
||||
var count = 1.0;
|
||||
let dataL = textureLoad(terrainDataTex, clampCoord(texCoord + vec2i(-1, 0), dims), 0).x;
|
||||
if ((dataL & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + f32(dataL & MAGNITUDE_MASK);
|
||||
count = count + 1.0;
|
||||
}
|
||||
let dataR = textureLoad(terrainDataTex, clampCoord(texCoord + vec2i(1, 0), dims), 0).x;
|
||||
if ((dataR & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + f32(dataR & MAGNITUDE_MASK);
|
||||
count = count + 1.0;
|
||||
}
|
||||
let dataD = textureLoad(terrainDataTex, clampCoord(texCoord + vec2i(0, -1), dims), 0).x;
|
||||
if ((dataD & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + f32(dataD & MAGNITUDE_MASK);
|
||||
count = count + 1.0;
|
||||
}
|
||||
let dataU = textureLoad(terrainDataTex, clampCoord(texCoord + vec2i(0, 1), dims), 0).x;
|
||||
if ((dataU & (1u << IS_LAND_BIT)) == 0u) {
|
||||
sum = sum + f32(dataU & MAGNITUDE_MASK);
|
||||
count = count + 1.0;
|
||||
}
|
||||
|
||||
let avgMag = sum / count;
|
||||
let smoothMag = mix(mag, avgMag, waterDepthBlur);
|
||||
let magClamped = min(smoothMag, 10.0);
|
||||
let adjustment = (1.0 - magClamped) / 255.0;
|
||||
let water = vec3f(
|
||||
max(params.waterColor.r + adjustment, 0.0),
|
||||
max(params.waterColor.g + adjustment, 0.0),
|
||||
max(params.waterColor.b + adjustment, 0.0),
|
||||
);
|
||||
color = vec4f(water, 1.0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user