From c9ea04abacc6b8629c0bdf78488d4f1e9f1c3ef6 Mon Sep 17 00:00:00 2001
From: scamiv <6170744+scamiv@users.noreply.github.com>
Date: Tue, 20 Jan 2026 21:43:25 +0100
Subject: [PATCH] Add improved terrain compute shaders with lite and heavy
variants
- Add terrain-compute-improved-lite.wgsl and terrain-compute-improved-heavy.wgsl
- Create TerrainShaderRegistry.ts for shader management
- Refactor TerrainComputePass to support dynamic shader switching
- Update TerritoryRenderer, TerritoryLayer, and GroundTruthData for new shader integration
- Enhance WebGPUDebugOverlay with additional debugging capabilities
---
src/client/graphics/layers/TerritoryLayer.ts | 26 ++
.../graphics/layers/WebGPUDebugOverlay.ts | 55 ++++-
.../graphics/webgpu/TerritoryRenderer.ts | 37 +++
.../webgpu/compute/TerrainComputePass.ts | 66 +++--
.../graphics/webgpu/core/GroundTruthData.ts | 29 ++-
.../webgpu/render/TerrainShaderRegistry.ts | 233 ++++++++++++++++++
.../terrain-compute-improved-heavy.wgsl | 167 +++++++++++++
.../terrain-compute-improved-lite.wgsl | 103 ++++++++
.../shaders/compute/terrain-compute.wgsl | 2 +
9 files changed, 688 insertions(+), 30 deletions(-)
create mode 100644 src/client/graphics/webgpu/render/TerrainShaderRegistry.ts
create mode 100644 src/client/graphics/webgpu/shaders/compute/terrain-compute-improved-heavy.wgsl
create mode 100644 src/client/graphics/webgpu/shaders/compute/terrain-compute-improved-lite.wgsl
diff --git a/src/client/graphics/layers/TerritoryLayer.ts b/src/client/graphics/layers/TerritoryLayer.ts
index f2a2c93b5..94b27d886 100644
--- a/src/client/graphics/layers/TerritoryLayer.ts
+++ b/src/client/graphics/layers/TerritoryLayer.ts
@@ -11,6 +11,10 @@ import {
} from "../../InputHandler";
import { FrameProfiler } from "../FrameProfiler";
import { TransformHandler } from "../TransformHandler";
+import {
+ buildTerrainShaderParams,
+ readTerrainShaderId,
+} from "../webgpu/render/TerrainShaderRegistry";
import {
buildTerritoryPostSmoothingParams,
readTerritoryPostSmoothingId,
@@ -43,6 +47,7 @@ export class TerritoryLayer implements Layer {
private lastPaletteSignature: string | null = null;
private lastDefensePostsSignature: string | null = null;
+ private lastTerrainShaderSignature: string | null = null;
private lastTerritoryShaderSignature: string | null = null;
private lastPreSmoothingSignature: string | null = null;
private lastPostSmoothingSignature: string | null = null;
@@ -87,6 +92,7 @@ export class TerritoryLayer implements Layer {
this.refreshPaletteIfNeeded();
this.refreshDefensePostsIfNeeded();
+ this.applyTerrainShaderSettings();
this.applyTerritoryShaderSettings();
this.applyTerritorySmoothingSettings();
@@ -124,6 +130,7 @@ export class TerritoryLayer implements Layer {
this.territoryRenderer = renderer;
this.territoryRenderer.setAlternativeView(this.alternativeView);
this.territoryRenderer.setHighlightedOwnerId(this.hoveredOwnerSmallId);
+ this.applyTerrainShaderSettings(true);
this.applyTerritoryShaderSettings(true);
this.applyTerritorySmoothingSettings(true);
this.territoryRenderer.markAllDirty();
@@ -335,6 +342,25 @@ export class TerritoryLayer implements Layer {
this.territoryRenderer.setTerritoryShaderParams(params0, params1);
}
+ private applyTerrainShaderSettings(force: boolean = false) {
+ if (!this.territoryRenderer) {
+ return;
+ }
+
+ const terrainId = readTerrainShaderId(this.userSettings);
+ const { shaderPath, params0, params1 } = buildTerrainShaderParams(
+ this.userSettings,
+ terrainId,
+ );
+ const signature = `${shaderPath}:${Array.from(params0).join(",")}:${Array.from(params1).join(",")}`;
+ if (!force && signature === this.lastTerrainShaderSignature) {
+ return;
+ }
+ this.lastTerrainShaderSignature = signature;
+ this.territoryRenderer.setTerrainShader(shaderPath);
+ this.territoryRenderer.setTerrainShaderParams(params0, params1);
+ }
+
private applyTerritorySmoothingSettings(force: boolean = false) {
if (!this.territoryRenderer) {
return;
diff --git a/src/client/graphics/layers/WebGPUDebugOverlay.ts b/src/client/graphics/layers/WebGPUDebugOverlay.ts
index cf60eee5a..908d31ce4 100644
--- a/src/client/graphics/layers/WebGPUDebugOverlay.ts
+++ b/src/client/graphics/layers/WebGPUDebugOverlay.ts
@@ -4,6 +4,13 @@ import { live } from "lit/directives/live.js";
import { EventBus } from "../../../core/EventBus";
import { UserSettings } from "../../../core/game/UserSettings";
import { WebGPUComputeMetricsEvent } from "../../InputHandler";
+import {
+ TERRAIN_SHADER_KEY,
+ TERRAIN_SHADERS,
+ terrainShaderIdFromInt,
+ terrainShaderIntFromId,
+ TerrainShaderOption,
+} from "../webgpu/render/TerrainShaderRegistry";
import {
TERRITORY_POST_SMOOTHING,
TERRITORY_POST_SMOOTHING_KEY,
@@ -21,9 +28,12 @@ import {
TERRITORY_SHADERS,
territoryShaderIdFromInt,
territoryShaderIntFromId,
+ TerritoryShaderOption,
} from "../webgpu/render/TerritoryShaderRegistry";
import { Layer } from "./Layer";
+type ShaderOption = TerrainShaderOption | TerritoryShaderOption;
+
@customElement("webgpu-debug-overlay")
export class WebGPUDebugOverlay extends LitElement implements Layer {
@property({ type: Object })
@@ -186,6 +196,18 @@ export class WebGPUDebugOverlay extends LitElement implements Layer {
this.requestUpdate();
}
+ private selectedTerrainShaderId() {
+ const selected = this.userSettings.getInt(TERRAIN_SHADER_KEY, 0);
+ return terrainShaderIdFromInt(selected);
+ }
+
+ private setSelectedTerrainShaderId(
+ id: "classic" | "improved-lite" | "improved-heavy",
+ ) {
+ this.userSettings.setInt(TERRAIN_SHADER_KEY, terrainShaderIntFromId(id));
+ this.requestUpdate();
+ }
+
private selectedPreSmoothingId() {
const selected = this.userSettings.getInt(TERRITORY_PRE_SMOOTHING_KEY, 0);
return territoryPreSmoothingIdFromInt(selected);
@@ -212,9 +234,7 @@ export class WebGPUDebugOverlay extends LitElement implements Layer {
this.requestUpdate();
}
- private renderOptionControl(
- option: (typeof TERRITORY_SHADERS)[number]["options"][number],
- ) {
+ private renderOptionControl(option: ShaderOption) {
if (option.kind === "boolean") {
const enabled = this.userSettings.get(option.key, option.defaultValue);
return html`
@@ -289,6 +309,10 @@ export class WebGPUDebugOverlay extends LitElement implements Layer {
const shaderId = this.selectedShaderId();
const shader =
TERRITORY_SHADERS.find((s) => s.id === shaderId) ?? TERRITORY_SHADERS[0];
+ const terrainShaderId = this.selectedTerrainShaderId();
+ const terrainShader =
+ TERRAIN_SHADERS.find((s) => s.id === terrainShaderId) ??
+ TERRAIN_SHADERS[0];
const preId = this.selectedPreSmoothingId();
const pre =
TERRITORY_PRE_SMOOTHING.find((s) => s.id === preId) ??
@@ -315,6 +339,31 @@ export class WebGPUDebugOverlay extends LitElement implements Layer {
+
Shaders
+
+
+
Terrain Shader
+
+
+
+ ${terrainShader.options.map((opt) => this.renderOptionControl(opt))}
+
+ Territory
+
Territory Shader