Úloha 039: Generování terénu

Vytvořte program, který bude generovat a vykreslovat (fraktální) terén. Uživatel by měl mít možnost nastavit počet iterací algoritmu a hladkost/hrubost výsledku. Při této úloze byste si měli mimo jiné vyzkoušet práci s 3D daty a naučit se něco nového o procedurálních metodách v počítačové grafice.

Screenshot starší verze projektu 039terrain:
Terrain aplikace

Princip

Algoritmus začíná se čtyřmi vrcholy umístěnými v rozích čtverce. Doprostřed čtverce se přidá nový bod, jehož výška se dopočte jako průměr výšek těchto čtyř bodů ("diamond step"). Pro přidání bodu je potřeba mřížku s vrcholy zjemnit, v důsledku čehož se nám objeví další čtyři nové vrcholy. Jejich výšky opět vypočteme jako průměr výšek (zde 3, v dalších iteracích typicky 4) sousedících bodů ("square step"). Metodu rekurzivně/iterativně aplikujeme na (nejmenší) čtverečky vzniklé mřížky. Princip algoritmu je ilustrován na obrázku.

Tímto způsobem bychom pouze interpolovali výšky krajních vrcholů počáteční mřížky a výsledná plocha by byla hladká. Proto k výšce každého nově přidaného vrcholu přidáme náhodné posunutí. Rozsah hodnot, kterých náhodné číslo nabývá, je klesající (případně nerostoucí) s číslem iterace algoritmu a určuje hladkost terénu. Vzorec můžete použít vlastní nebo převzít některý z uvedené literatury.

Kroky algoritmu

Literatura

Další informace lze najít například zde:

  • přesnější popis metody, teoretický úvod, vzorce - Moderní Počítačová Grafika, autoři Žára, Beneš, Sochor, Felkel, nakladatelství Computer Press, 2004 (8.1.5 Náhodné fraktály, sekce Brownův pohyb a Metoda náhodného přesouvání středního bodu)
  • Artificial Terrain Generation
  • Fractal landscape on Wikipedia
Je možné implementovat i jiné netriviální metody (individuální hodnocení v mezích současného hodnocení), např.:

Implementace

Jako kostru aplikace použijte projekt 039terrain z repository grcis (GIT). Budete hlavně přepisovat metodu Regenerate(), která se vyvolává při změně parametrů terénu a stisku tlačítka "Regenerate terrain".
Připravena je třída SceneBrep, do které můžete snadno přidávat nové vrcholy (AddVertex()), jejich normály (SetNormal()), texturové souřadnice (SetTxtCoord()) a případně barvy (SetColor(), viz metoda Render()); jejich použití je ilustrováno v glControl1_Load(). Vykreslení dat ze třídy SceneBrep a jednoduchá kamera jsou implementovány v metodách Render() a SetCamera() a pro úspěšné odevzdání není nutné (ale ani zakázané) je měnit - stačí vygenerovaná data převést na trojúhelníkovou síť. Konverze dat ze SceneBrep a jejich nahrání na grafickou kartu je v metodě PrepareData(). Pomocná knihovna pro nahrávání textur je v souboru TexLib.cs. Před implementací se zamyslete, jestli při řešení použijete rekurzi nebo iteraci.

Reakce na tlačítko "Regenerate terrain:" je potřeba zachovávat spojitost terénu při pouhé změně počtu iterací! Tj. reagujte na tlačítko "Regenerate terrain" tak, že přegenerujte celý model od základů pouze v případě zmeny "roughness" anebo při explicitním stisku tlačítka ve formuláři (to poznáte tak, že se ani jeden parametr nezměnil), jinak - při změně "iterations" - dogenerujte zbylé úrovně resp. nejjemnější úrovně zrušte. Terén by neměl při změně počtu iterací divoce poskakovat, jen se lehce zjemňovat..

Režim vznášedla ("hovercraft")

Volitelně (za další body navíc) můžete zkusit implementovat interaktivní prolétávání nad terénem v dopravním prostředku typu vznášedlo. Vznášedlo má omezenou pohyblivost ve vertikálním směru, v podstatě kopíruje terén (létá v nějaké výšce nad ním). Pohyb v půdorysu by měl uživatel řídit z klávesnice (šipky nebo "WASD") nebo myší. Můžete dokonce implementovat směr pohledu částečně nezávislý na pohybu - vznášedlo může mít velkou translační setrvačnost, ale otáčet kolem svislé osy může být snadnější. Výška letu nad terénem, parametry akcelerace, setrvačnost, vliv gravitace, plynulejší pohyb nad hrbolatým terénem (vyhlazení výškové funkce terénu) - to vše můžete implementovat dle zájmu. Upozorněte na to v dokumentaci, abych to nezapomněl vyzkoušet a přidělit Vám body navíc.

Simulace letu vznášedla by měla přijít do metody Simulate (double time). Jako u jiných úloh, čas je zadáván v sekundách a úkolem volání této funkce je "dosimulovat" pohyb od minulého volání až do daného času. Simulace se vždy volá bezprostředně před vykreslením 3D scény.

Co odevzdat

Jako řešení úlohy posílejte mailem modifikovaný zdrojový soubor Terrain.cs. Pokud jste vymysleli nebo použili jinou než výše popsanou metodu, doplňte ji krátkým průvodním textem. To samé platí pro zajímavá rozšíření, ať si jich všimnu. Pokud něco nefunguje úplně dobře, ale dali jste si s tím práci, zmiňte to. Můžete poslat i hezký screenshot nebo odkaz na galerii.

Termín

Odevzdat do: 28. 2. 2023

Body

Až 26b + bonus podle přibližného rozpisu:

  • 10b - základní generování neotexturovaného/jednobarevného terénu s nastavením hladkosti/hrubosti a počtu iterací (při změně počtu iterací se zjemní/zhrubne existující terén, negeneruje se úplně nový, maximální počet iterací je omezen jen pamětí). Alespoň nějaké normály. Nastavení rozměrů pohoří (jednotek na stranu a na výšku).
  • 4b - inicializace výškové mapy z PNG (např. rozměrů 2×2, 3×3, až 33×33).
  • 2b - korektní normály ve vrcholech, vedoucí k pěknému stínování.
  • 2b - základní netriviální texturování terénu.
  • 3 až 8b - prolétávání nad terénem jako alternativní zobrazení ("režim vznášedla").
  • bonus - za zajímavé řešení, rozšíření (tvorba sopek (jen) z některých vrcholků obracením jejich špiček, asymetrie údolí a pohoří, dynamické nastavení úrovně vody, atd.), hezké vykreslení (více textur, vodní hladina, průhledná vodní hladina, atd.).

Projekt

Visual Studio projekt: 039terrain

Zdrojový soubor

Modifikujte a odevzdejte soubor: Terrain.cs
V příslušném parametru funkce Form1.InitParams() vraťte své celé jméno!
Nezapomeňte na krátký průvodní text, ovládání vznášedla...


Copyright (C) 2011-2022 J.Pelikán, J.Beneš last change: 2022-10-27 14:54:14 +0200 (Thu, 27 Oct 2022)