GRK/cw 4/zadania 4.html
secret_dude a7bd7ecb75 master
2022-01-12 16:07:16 +01:00

101 lines
9.6 KiB
HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>zadania 4</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link rel="stylesheet" href="style.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h2 id="i-oświetlenie-phonga">I Oświetlenie Phonga</h2>
<h3 id="i.0.-jeżeli-nie-zrobiłeś-poprzednich-zadań-związanych-z-shaderami">I.0. (Jeżeli nie zrobiłeś poprzednich zadań związanych z shaderami)</h3>
<p>Obejrzyj pliki <strong>shader_4_1.vert</strong> i <strong>shader_4_1.frag</strong>. Zwróć uwagę w szczególności na zmienną <code>interpNormal</code>, przy uzyciu ktorej wektory normalne są przesyłane z <strong>vertex shaderze</strong> do <strong>fragment shadera</strong>. Pliki shader_4_2.vert i shader_4_2.frag na razie nie będą wykorzystywane</p>
<h3 id="i.1.-oblicz-we-fragment-shaderze-oświetlenie-obiektu-przy-użyciu-modelu-phonga-dla-światła-rozproszonego-diffuse">I.1. Oblicz we fragment shaderze oświetlenie obiektu przy użyciu modelu Phonga dla światła rozproszonego (<code>diffuse</code>):</h3>
<ol type="a">
<li>Przekaż źródło światła. Na razie przyjmiemy kierunkowy model oświetlenia, dlatego źródło będzie opisane jako wektor kierunkowy:</li>
</ol>
<ul>
<li><p>Prześlij do fragment shadera zmienna typu <code>uniform vec3</code> (nazwij ją np. <code>lightDir</code>), w której będzie się znajdować wektor kierunkowy:</p></li>
<li><p>Należy to zrobić podobnie do tego, jak przesyłana jest zmienna <code>objectColor</code>. Jedyna różnica będzie taka, ze kierunek padania światła nie zależy od obiektu, wiec wywołanie <code>glUniform3f</code> powinno pojawić się tylko raz, przed rysowaniem wszystkich obiektów.Wywołaj <code>glUseProgram(program)</code> przed przesłaniem zmiennej.</p></li>
<li><p>Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować)</p></li>
</ul>
<ol start="2" type="a">
<li>Oblicz natężenie w shaderze fragmentów:</li>
</ol>
<ul>
<li><p>znormalizuj wektor normalny przed użyciem go w obliczeniach (uśrednianie wektorów normalnych wierzchołków może spowodować, ze przestaje one być jednostkowe).</p></li>
<li><p>Natężenie to iloczyn skalarny wektora normalnego powierzchni i odwrotnego wektora kierunku padania światła. Skorzystaj z funkcji <code>dot</code>.</p></li>
<li><p>Natężenie nie może być ujemne. Przytnij natężenie do zera przy użyciu: <code>x = max(x, 0.0)</code></p></li>
</ul>
<ol start="3" type="a">
<li>Zastosuj obliczone natężenie aby zmodyfikować kolor obiektu:</li>
</ol>
<ul>
<li>Przemnóż kolor RGB fragmentu przez obliczone natężenie.</li>
</ul>
<h3 id="i.2.-dlaczego-oświetlenie-statku-nie-zmienia-się-podczas-jego-obracania">I.2. Dlaczego oświetlenie statku nie zmienia się podczas jego obracania?</h3>
<p>(Wektory normalne są w układzie lokalnym modelu, a wektor padania światła w układzie świata)</p>
<p>Należy wykonać transformacje wektorów normalnych do przestrzeni świata:</p>
<ul>
<li><p>Prześlij macierz modelu rysowanego obiektu (<em>model Matrix</em>) jako osobna zmienna do vertex shadera (<code>uniform mat4</code>).</p></li>
<li><p>Przemnóż przez te macierz wektor normalny wierzchołka przed przeslaniem go do fragment shadera.</p></li>
<li><p>Współrzędna <strong>w</strong> dopisana do wektora przed mnożeniem przez macierz powinna być ustawiona na 0. Wynika to z tego, ze w przypadku transformacji wektorów reprezentujących kierunki w przestrzeni, nie chcemy dokonywać translacji - np. wektor normalny do powierzchni zależy od orientacji obiektu, ale nie od jego pozycji (przesunięcia) w przestrzeni świata.</p></li>
</ul>
<h3 id="i.3.-uzupełnił-model-o-czynnik-światła-odbitego-specular.-w-tym-celu">I.3. Uzupełnił model o czynnik światła odbitego (<code>specular</code>). W tym celu:</h3>
<ol type="a">
<li>Potrzebny będzie wektor od rysowanego fragmentu do pozycji kamery:</li>
</ol>
<ul>
<li><p>Wyślij pozycje kamery (<code>cameraPos</code>) jako kolejna zmienna do fragment shadera.</p></li>
<li><p>Podobnie jak wektory normalne prześlij z vertex do fragment shadera pozycje wierzchołków (<code>vertexPosition</code>) w przestrzeni świata (czyli pomnożone przez macierz <strong>modelMatrix</strong>). Pamiętaj, ze tym razem wektory reprezentują punkty, a nie kierunki - współrzędna <strong>w</strong> przed mnożeniem musi być ustawiona na 1. W wyniku rasteryzacji otrzymamy w shaderze fragmentu jego pozycję (nazywaną pozycją fragmentu)</p></li>
<li><p>Oblicz wektor <strong>V</strong> (<em>view direction</em>) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.</p></li>
</ul>
<ol start="2" type="a">
<li>Oblicz natężenie światła odbitego we <em>fragment shaderze</em>:</li>
</ol>
<ul>
<li><p>Oblicz wektor kierunku odbicia światła <strong>R</strong> przy użyciu funkcji <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/reflect.xhtml"><code>reflect</code></a>. Pamiętaj, żeby przesłać do funkcji odwrócony wektor kierunku światła.</p></li>
<li><p>Oblicz natężenie: iloczyn skalarny <strong>V</strong> i <strong>R</strong>, przycięty do zera ( <code>max(...,0.0)</code> ), a następnie podniesiony do wysokiej potęgi (np. 8, 50, 1000), która jest miara połyskliwości powierzchni</p></li>
</ul>
<ol start="3" type="a">
<li>Ustal ostateczny kolor piksela na <code>objectColor * diffuse + vec3(1.0) * specular</code>. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.</li>
</ol>
<h3 id="i.4.-stwórz-układ-planetarny---jedna-nieruchoma-kule-na-środku-słonce-i-kilka-orbitujących-wokół-niej-planet.">I.4. Stwórz układ planetarny - jedna nieruchoma kule na środku (Słonce) i kilka orbitujących wokół niej planet.</h3>
<p>Niech przynajmniej jedna planeta ma księżyce.</p>
<h3 id="i.5.-w-układzie-planetarnym-obiektem-oświetlającym-powinno-być-słońce-dlatego-zamień-oświetlenie-kierunkowe-na-punktowe">I.5. W układzie planetarnym obiektem oświetlającym powinno być słońce, dlatego zamień oświetlenie kierunkowe na punktowe:</h3>
<ul>
<li><p>Zamiast przesyłać (w <code>lightDir</code>) kierunek światła, prześlij pozycję słońca do fragment shadera (taką jak ustawiłeś w punkcie powyżej) jako uniform vec3 (nazwij go <code>lightPos</code>).</p></li>
<li><p>Oblicz kierunek światła odejmując od pozycji fragmentu pozycję światła, znormalizuj wynik. Zapisz wynik w zmiennej <code>lightDir</code>.</p></li>
<li><p>Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny</p></li>
</ul>
<h3 id="i.6.-źródło-światła-znajduje-się-wewnątrz-kuli-która-reprezentuje-słońce-dlatego-jest-czarna.-by-to-naprawić-utwórz-osobny-shader-który-będzie-odpowiadać-za-renderowanie-słońca.">I.6. Źródło światła znajduje się wewnątrz kuli, która reprezentuje słońce, dlatego jest czarna. By to naprawić utwórz osobny shader, który będzie odpowiadać za renderowanie słońca.</h3>
<p>Celem tego zadania jest stworzenie shadera (<strong>shader_4_sun.vert</strong>_ i <strong>shader_4_sun.frag</strong>), który będzie odpowiadał wyłącznie za rysowanie słońca. Poprzednie shadery (<strong>shader_4_1.vert</strong>_ i <strong>shader_4_1.frag</strong>) nadal mają rysować pozostałe obiekty. a) zainicjalizuj <em>program</em> (shadery): - Pliki <strong>shader_4_sun.vert</strong> i <strong>shader_4_sun.frag</strong> są identyczne jak <strong>4_1</strong> przed zmianami, będą punktem wyjścia dla <em>shadera</em> słońca.</p>
<ul>
<li>Utwórz zmienną globalną <code>GLuint programSun</code> na adres shadera słońca. Stwórz <em>program</em> za pomocą <code>shaderLoader.CreateProgram</code> analogicznie jak tworzy się <code>program</code> z <strong>shader_4_1.vert</strong> i <strong>shader_4_1.frag</strong> (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów <strong>shader_4_sun.vert</strong> i <strong>shader_4_sun.frag</strong>).</li>
</ul>
<ol start="2" type="a">
<li>W skomplikowanym projekcie różne typy obiektów rysuje się przy użyciu różnych shaderów, zate potrzebna jest w programie architektura, która na to pozwala. Ustaw odpowiedni <em>program</em> (shadery) do rysowania słońca:</li>
</ol>
<ul>
<li>funkcja <code>drawObject</code> korzysta z globalnej zmiennej <code>program</code>, żeby wskazywać shadery do rysowania. Dodaj argument do funkcji, który będziesz przekazywać adres <em>programu</em>, który ma być wykorzystany do rysowania.</li>
<li>dodaj odpowiedni <em>program</em> w wywołaniach <code>drawObject</code></li>
</ul>
<h3 id="i.7.-zmień-shader-słońca-na-bardziej-realistyczny.">I.7.* Zmień shader słońca na bardziej realistyczny.</h3>
<p>Na poniższym obrazku jest zdjęcie słońca. jest ono ciemniejsze na brzegach spróbuj uzyskać podobny efekt. Przydadzą się wektory z poprzednich punktów, jak wektor normalny i wektor <strong>V</strong>.</p>
<p><img src="https://wi-images.condecdn.net/image/DEGypMQdE59/crop/1020/f/sunmeta.jpg" /></p>
</body>
</html>