Otazky

Kapitola 13 – 13.4. Osvětlení

metoda Terrain::genTexture odkazuje na funkci Terén::lehkýTerén, který, jak název napovídá, provádí osvětlení terénu pro zvýšení realismu scény. Protože jsme již vypočítali barvy textury terénu, zbývá už jen vypočítat faktor stínování, který určité oblasti ztmaví nebo zesvětlí v závislosti na jejich poloze vzhledem ke zdroji světla. V této části se budeme zabývat právě touto technikou. Možná vás zajímá, proč jsme se vůbec obtěžovali s osvětlením terénu, místo abychom to nechali udělat za nás na Direct3D. Existují tři výhody provádění výpočtů sami:

  • Šetříme paměť, protože nemusíme ukládat normály vrcholů.
  • Protože krajiny jsou statické a nebudeme přesouvat světelné zdroje, můžeme osvětlení vypočítat předem, čímž ušetříme čas, který by Direct3D jinak strávil výpočtem osvětlení krajiny v reálném čase.
  • Procvičíme si matematiku, naučíme se základní koncepty osvětlení a budeme pracovat s funkcemi Direct3D.

13.4.1. Přehled

Technika osvětlení, kterou použijeme k výpočtu tónů krajiny, patří k nejjednodušším a je známá jako difuzní osvětlení (difúzní osvětlení). Používáme paralelní zdroj světla, který popisujeme zadáním směru ke zdroji světla, který je opačný ke směru, kterým dopadají paprsky vyzařované zdrojem. Například pokud chceme, aby paprsky světla dopadaly svisle z oblohy dolů ve směru Světelné paprskySměr = (0, –1, 0), pak směr ke zdroji světla bude vektor směřující opačným směrem SměrKsvětlu = (0, 1, 0). Všimněte si, že používáme jednotkové vektory.

I když se určení směru paprsků vyzařovaných světelným zdrojem může zdát intuitivnější, určení směru světelného zdroje je vhodnější pro výpočet difúzního osvětlení.

Pak pro každý čtverec terénu vypočítáme úhel mezi vektorem světla a normálou povrchu čtverce.

Na obr. 13.7 je zřejmé, že čím větší je úhel, tím více je povrch čtverce natočen od zdroje světla a tím méně světla na povrch dopadá. Čím menší je úhel, tím více je povrch čtverce natočen ke zdroji světla a tím více světla přijímá. Všimněte si také, že pokud je úhel mezi vektorem osvětlení a kolmicí povrchu větší než 90 stupňů, povrch není vůbec osvětlen.

Obrázek 13.7. Úhel mezi vektorem osvětlení a normálou povrchu určuje, kolik světla povrch přijímá. Na obrázku (a) je úhel menší než 90 stupňů. Na obrázku (b) je úhel větší než 90 stupňů. V druhém případě povrch nepřijímá žádné světlo, protože světelné paprsky (vyzařované v opačném směru než je směr vektoru) dopadají na zadní stranu povrchu.

Pomocí úhlového vztahu mezi vektorem světla a normálou povrchu můžeme vypočítat faktor stínování v rozsahu [0, 1], který určuje, kolik světla povrch přijímá. Velké úhly jsou reprezentovány hodnotami blízkými nule. Když je barva vynásobena faktorem stínování blízkým nule, ztmavne, což je přesně to, co chceme. Na druhou stranu, malé úhly jsou reprezentovány hodnotami blízkými jedné a vynásobení tímto faktorem nemá téměř žádný vliv na jas barvy.

Přečtěte si více
Transplantace anthuria doma během kvetení: je možné to udělat s mužským štěstím, pokud otevírá pupeny, kdy a jak by se to mělo dělat? Dacha expert

13.4.2. Výpočet stínování čtverce

Směr ke zdroji světla je nám dán jako normalizovaný vektor . Pro výpočet úhlu mezi a normálou čtverce musíme nejprve získat . Jedná se o triviální problém, který se řeší pomocí vektorového součinu. Nejprve však musíme získat dva nenulové a nerovnoběžné vektory ležící ve stejné rovině jako čtverec. Na obr. 13.8 jsou tyto dva vektory označeny u a v:

Obr. 13.8. Výpočet dvou vektorů, které leží ve stejné rovině jako čtverec

Po získání u a v vypočítáme normálu čtverce N pomocí vzorce N = u × v. Vektor N bychom samozřejmě měli normalizovat:

Pro nalezení úhlu mezi a si pamatujte, že skalární součin dvou jednotkových vektorů v trojrozměrném prostoru se rovná kosinu úhlu mezi nimi:

Hodnoty koeficientů s bude v rozsahu [–1, 1]. Hodnoty s z rozsahu [–1, 0) odpovídají úhlům mezi 90 stupni a větším než 13.7 stupni a v tomto případě, jak je znázorněno na obr. 1, povrch nepřijímá světlo. Proto nahradíme jakékoli hodnoty z rozsahu [–0, 0) hodnotou XNUMX:

float cosinus = D3DXVec3Dot(&n, směrSvětla); pokud(cosinus < 0.0f) cosinus = 0.0f;

Nyní, když hodnoty s pro úhly větší než 90 stupňů se zavrhují, s se stává naším faktorem stínování s intervalem hodnot [0, 1], protože s rostoucím úhlem mezi a z 0 na 90 stupňů se hodnota s mění z 1 na 0. To je přesně funkce, kterou jsme potřebovali, jak je popsáno v kapitole 13.4.1.

Koeficient stínování pro jeden čtverec se vypočítá metodou Terrain::computeShadeJako parametry přijímá čísla řádků a sloupců identifikující čtverec krajiny a vektor určující směr k rovnoběžnému zdroji světla.

13.4.3. Stínování krajiny

Nyní, když víme, jak vystínovat jeden čtverec, můžeme vystínovat všechny čtverce v krajině. Jednoduše projdeme všechny čtverce v krajině, vypočítáme faktor stínování pro každý z nich a vynásobíme barvu odpovídajícího texelu výsledným faktorem. V důsledku toho čtverce, které dostávají málo světla, ztmavnou. Níže je uveden úryvek kódu, který je hlavní částí metody. Terén::lehkýTerén:

DWORD* imageData = (DWORD*)lockedRect.pBits; for(int i = 0; i < textureDesc.Height; i++) < for(int j = 0; j < textureDesc.Width; j++) < int index = i * lockedRect.Pitch / 4 + j; // Získá aktuální barvu buňky D3DXCOLOR c(imageData[index]); // Vystínuje aktuální buňku c *= computeShade(i, j, lightDirection);; // Uloží vystínovanou barvu imageData[index] = (D3DCOLOR)c; >>

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Back to top button