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
This commit is contained in:
scamiv
2026-01-20 21:43:25 +01:00
parent fd87b0e3f8
commit c9ea04abac
9 changed files with 688 additions and 30 deletions
@@ -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 {
</div>
</div>
<div class="sectionTitle">Shaders</div>
<div class="row">
<div class="label">Terrain Shader</div>
<select
.value=${live(String(terrainShaderIntFromId(terrainShaderId)))}
@change=${(e: Event) => {
const raw = (e.target as HTMLSelectElement).value;
const next = terrainShaderIdFromInt(Number.parseInt(raw, 10));
this.setSelectedTerrainShaderId(next);
}}
>
${TERRAIN_SHADERS.map(
(s) =>
html`<option value=${String(terrainShaderIntFromId(s.id))}>
${s.label}
</option>`,
)}
</select>
</div>
${terrainShader.options.map((opt) => this.renderOptionControl(opt))}
<div class="sectionTitle">Territory</div>
<div class="row">
<div class="label">Territory Shader</div>
<select