Feat: Add advanced rendering controls and validation for foliage settings

This commit is contained in:
2026-05-02 10:53:10 +02:00
parent db94b70c6a
commit 25a0abeed4
2 changed files with 142 additions and 0 deletions

View File

@@ -19021,6 +19021,125 @@ export function App({ store, draftStorage = null, initialStatusMessage }: AppPro
/>
</label>
<div className="form-section">
<div className="label">Foliage</div>
<label className="form-field form-field--toggle">
<span className="label">Enabled</span>
<input
type="checkbox"
checked={advancedRendering.foliage.enabled}
onChange={(event) =>
applyAdvancedRenderingFoliageEnabled(
event.currentTarget.checked
)
}
/>
</label>
<div className="vector-inputs vector-inputs--two">
<label className="form-field">
<span className="label">Density</span>
<input
className="text-input"
type="number"
min={MIN_FOLIAGE_QUALITY_DENSITY_MULTIPLIER}
max={MAX_FOLIAGE_QUALITY_DENSITY_MULTIPLIER}
step="0.05"
value={
advancedRenderingFoliageDensityMultiplierDraft
}
onChange={(event) =>
setAdvancedRenderingFoliageDensityMultiplierDraft(
event.currentTarget.value
)
}
onBlur={
applyAdvancedRenderingFoliageDensityMultiplier
}
onKeyDown={(event) =>
handleDraftVectorKeyDown(
event,
applyAdvancedRenderingFoliageDensityMultiplier
)
}
onKeyUp={(event) =>
handleNumberInputKeyUp(
event,
applyAdvancedRenderingFoliageDensityMultiplier
)
}
onPointerUp={(event) =>
handleNumberInputPointerUp(
event,
applyAdvancedRenderingFoliageDensityMultiplier
)
}
/>
</label>
<label className="form-field">
<span className="label">Distance</span>
<input
className="text-input"
type="number"
min={
MIN_FOLIAGE_QUALITY_MAX_DISTANCE_MULTIPLIER
}
max={
MAX_FOLIAGE_QUALITY_MAX_DISTANCE_MULTIPLIER
}
step="0.05"
value={
advancedRenderingFoliageMaxDistanceMultiplierDraft
}
onChange={(event) =>
setAdvancedRenderingFoliageMaxDistanceMultiplierDraft(
event.currentTarget.value
)
}
onBlur={
applyAdvancedRenderingFoliageMaxDistanceMultiplier
}
onKeyDown={(event) =>
handleDraftVectorKeyDown(
event,
applyAdvancedRenderingFoliageMaxDistanceMultiplier
)
}
onKeyUp={(event) =>
handleNumberInputKeyUp(
event,
applyAdvancedRenderingFoliageMaxDistanceMultiplier
)
}
onPointerUp={(event) =>
handleNumberInputPointerUp(
event,
applyAdvancedRenderingFoliageMaxDistanceMultiplier
)
}
/>
</label>
</div>
<label className="form-field">
<span className="label">Shadows</span>
<select
className="select-input"
value={advancedRendering.foliage.shadows}
onChange={(event) =>
applyAdvancedRenderingFoliageShadows(
event.currentTarget
.value as FoliageQualityShadowMode
)
}
>
{FOLIAGE_QUALITY_SHADOW_MODES.map((shadowMode) => (
<option key={shadowMode} value={shadowMode}>
{formatFoliageQualityShadowModeLabel(shadowMode)}
</option>
))}
</select>
</label>
</div>
{!advancedRendering.enabled ? null : (
<>
<div className="form-section">

View File

@@ -1713,6 +1713,13 @@ describe("validateSceneDocument", () => {
density: Number.NaN,
sourceSize: 0,
samples: 0
},
foliage: {
...document.world.advancedRendering.foliage,
enabled: "yes",
densityMultiplier: 3,
maxDistanceMultiplier: 0,
shadows: "close"
}
} as any;
@@ -1852,6 +1859,22 @@ describe("validateSceneDocument", () => {
code: "invalid-advanced-rendering-god-rays-samples",
path: "world.advancedRendering.godRays.samples"
}),
expect.objectContaining({
code: "invalid-foliage-quality-enabled",
path: "world.advancedRendering.foliage.enabled"
}),
expect.objectContaining({
code: "invalid-foliage-quality-density-multiplier",
path: "world.advancedRendering.foliage.densityMultiplier"
}),
expect.objectContaining({
code: "invalid-foliage-quality-max-distance-multiplier",
path: "world.advancedRendering.foliage.maxDistanceMultiplier"
}),
expect.objectContaining({
code: "invalid-foliage-quality-shadows",
path: "world.advancedRendering.foliage.shadows"
}),
expect.objectContaining({
code: "invalid-advanced-rendering-fog-path",
path: "world.advancedRendering.fogPath"