lab 7 added
@ -1,92 +0,0 @@
|
||||
## Oświetlenie Phonga
|
||||
W trakcie tych zajęć zajmiemy się implementacją modelu oświetlenia Phonga. Na poprzednich zajęciach zbudowaliśmy układ słoneczny. Wykorzystamy go w trakcie tych zajęć. Jeżeli go zrobiłeś, to przekopiuj do `ex_5_1.hpp` kod z poprzednich zajęć. W przeciwnym wypadku wykorzystaj ten, który jest zaimplementowany w `ex_5_1.hpp`. W zadaniu będzie nam potrzebny statek latający przed kamerą, jak nie ma tego w Twojej scenie to skopiuj to z `ex_5_1.hpp`.
|
||||
|
||||
|
||||
## Zadanie - *diffuse*
|
||||
Oblicz we fragment shaderze oświetlenie obiektu przy użyciu modelu Phonga dla odbicia rozproszonego (*diffuse)
|
||||
1. Przekaż źródło światła. Na razie przyjmiemy kierunkowy model oświetlenia, dlatego źródło będzie opisane jako wektor kierunkowy:
|
||||
|
||||
- Prześlij do shadera fragmentów zmienna typu `uniform vec3` (nazwij ją np. `lightDir`), w której będzie się znajdować wektor kierunkowy.
|
||||
- Należy to zrobić podobnie do tego, jak przesyłany jest kolor.
|
||||
- Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować).
|
||||
|
||||
* Dodatkowo prześlij drugą zmienną `uniform vec3 lightColor`, w której umieścimy kolor światła. Prześlij tam wartości ze zmiennej `glm::vec3 lightColor`.
|
||||
|
||||
2. Oblicz natężenie w shaderze fragmentów:
|
||||
- prześlij normalne z shadera fragmentów do shadera wierzchołków
|
||||
- znormalizuj wektor normalny przed użyciem go w obliczeniach (uśrednianie wektorów normalnych wierzchołków może spowodować, że przestaje one być jednostkowe).
|
||||
|
||||
- Natężenie to iloczyn skalarny wektora normalnego powierzchni i odwrotnego wektora kierunku padania światła. Skorzystaj z funkcji `dot`.
|
||||
|
||||
- Natężenie nie może być ujemne. Przytnij natężenie do zera przy użyciu: `x = max(x, 0.0)`
|
||||
3. Zastosuj obliczone natężenie, aby zmodyfikować kolor obiektu:
|
||||
- Przemnóż kolor RGB fragmentu przez obliczone natężenie i przez kolor światła z `lightColor`.
|
||||
|
||||
## Zadanie - obsługa obrotów
|
||||
Dlaczego oświetlenie statku nie zmienia się podczas jego obracania?
|
||||
|
||||
(Wektory normalne są w układzie lokalnym modelu, a wektor padania światła w układzie świata)
|
||||
|
||||
Należy wykonać transformacje wektorów normalnych do przestrzeni świata:
|
||||
- Prześlij macierz modelu rysowanego obiektu (_model Matrix_) jako osobna zmienna do vertex shadera (`uniform mat4`).
|
||||
- Przemnóż przez te macierz wektor normalny wierzchołka przed przesłaniem go do shadera fragmentów.
|
||||
- Współrzędna **w** dopisana do wektora przed mnożeniem przez macierz powinna być ustawiona na 0. Wynika to z tego, że 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.
|
||||
|
||||
|
||||
## Zadanie - *specular*
|
||||
Uzupełnił model o czynnik odbicia zwierciadlanego (*specular*). W tym celu:
|
||||
|
||||
1. Potrzebny będzie wektor od rysowanego fragmentu do pozycji kamery:
|
||||
- Wyślij pozycje kamery (`cameraPos`) jako kolejna zmienna do fragment shadera.
|
||||
- Podobnie jak wektory normalne prześlij z vertex do fragment shadera pozycje wierzchołków (`vertexPosition`) w przestrzeni świata (czyli pomnożone przez macierz **modelMatrix**). Pamiętaj, że tym razem wektory reprezentują punkty, a nie kierunki - współrzędna **w** przed mnożeniem musi być ustawiona na 1. W wyniku rasteryzacji otrzymamy w shaderze fragmentu jego pozycję (nazywaną pozycją fragmentu)
|
||||
- Oblicz wektor **V** (_view direction_) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.
|
||||
|
||||
2. Oblicz natężenie światła odbitego we _fragment shaderze_:
|
||||
- Oblicz wektor kierunku odbicia światła **R** przy użyciu funkcji [`reflect`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/reflect.xhtml). Pamiętaj, żeby przesłać do funkcji odwrócony wektor kierunku światła.
|
||||
- Oblicz natężenie: iloczyn skalarny **V** i **R**, przycięty do zera ( `max(...,0.0)` ), a następnie podniesiony do wysokiej potęgi (np. 8, 50, 1000), która jest miara połyskliwości powierzchni.
|
||||
|
||||
3. Ustal ostateczny kolor piksela na `objectColor * diffuse + lightColor * specular`. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.
|
||||
|
||||
|
||||
## Zadanie - oświetlenie punktowe
|
||||
W układzie planetarnym obiektem oświetlającym powinno być słońce, dlatego zamień oświetlenie kierunkowe na punktowe:
|
||||
|
||||
- Zamiast przesyłać (w `lightDir`) 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 `lightPos`).
|
||||
- Oblicz kierunek światła odejmując od pozycji fragmentu pozycję światła, znormalizuj wynik. Zapisz wynik w zmiennej `lightDir`.
|
||||
- Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny.
|
||||
|
||||
## Zadanie - shader słońca
|
||||
Ź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.
|
||||
|
||||
Celem tego zadania jest stworzenie shadera (**shader_4_sun.vert**_ i **shader_4_sun.frag**), który będzie odpowiadał wyłącznie za rysowanie słońca. Poprzednie shadery (**shader_4_1.vert**_ i **shader_4_1.frag**) nadal mają rysować pozostałe obiekty. a) zainicjalizuj _program_ (shadery): - Pliki **shader_4_sun.vert** i **shader_4_sun.frag** są identyczne z 4_1** przed zmianami, będą punktem wyjścia dla _shadera_ słońca.
|
||||
|
||||
1. Utwórz zmienną globalną `GLuint programSun` na adres shadera słońca. Stwórz _program_ za pomocą `shaderLoader.CreateProgram` analogicznie jak tworzy się `program` z **shader_4_1.vert** i **shader_4_1.frag** (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów **shader_4_sun.vert** i **shader_4_sun.frag**).
|
||||
|
||||
2. 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 _program_ (shadery) do rysowania słońca:
|
||||
- funkcja `drawObject` korzysta z globalnej zmiennej `program`, żeby wskazywać shadery do rysowania. Dodaj argument do funkcji, który będziesz przekazywać adres _programu_, który ma być wykorzystany do rysowania.
|
||||
- dodaj odpowiedni _program_ w wywołaniach `drawObject`.
|
||||
|
||||
## Osłabienie światła, tone mapping
|
||||
### Zadanie - Osłabienie światła (attenuation)
|
||||
Światło pochodzące z punktowego źródła traci na sile wraz z dystansem. Wynika to z tego, że rozprasza się na większą powierzchnię.
|
||||
Dodaj ten efekt do shadera. Zamiast brać kolor światła bezpośrednio, podziel go przez kwadrat dystansu od źródła świata.
|
||||
|
||||
#### Tone mapping
|
||||
Przez obecną zmianę scena stała się ciemna. Wymaga to od nas zmiany 'koloru' światła na wartości dużo większe niż do tej pory. Jeśli teraz to zrobimy i przesadzimy w drugą stronę, otrzymamy efekt prześwietlenia. Wynika to z ograniczenia zakresu kolorów do $[0,1]$ (obsługą wyższych wartości nazywamy HDR). Rozwiązaniem jest pracowanie na wartościach powyżej 1 wykorzystanie *tone mappingu* do przeniesienia ich w zakres $[0,1]$. Istnieje wiele wzorów, które są wykorzystywane do tego, jeden z nich to:
|
||||
|
||||
$$C_{mapped} = 1-e^{-C * E},$$
|
||||
gdzie C to kolor sceny a E to parametr ekspozycji (z zakresu $(0,\infty)$, który może być dostosowany w zależności od jasności.
|
||||
### Zadanie - Tone mapping*
|
||||
Zwiększ siłę słońca przynajmniej stukrotnie. Zaimplementuj powyższą metodę tone mappingu i dodaj możliwość sterowania ekspozycją za pomocą klawiszy 1 i 2.
|
||||
|
||||
### Zadanie*
|
||||
Dodaj drugie źródło oświetlenia w postaci reflektora statku. Reflektor świeci tylko w określonym stożku,dlatego oprócz pozycji `spotPos` posiada również kierunek `spotDir` i kąt świecenia $\phi$. Po obliczeniu dla niego `lightDir` należy sprawdzić, czy iloczyn skalarny pomiędzy `lightDir` a `spodDir` jest większy niż $\cos\phi$ . Jeżeli nie jest, to stożek nie świeci w tym miejscu. Można ułatwić sobie implementację wielu źródeł światła poprzez przeniesienie obliczeń oświetlenia do funkcji, która przyjmuje kierunek światła i siłę naświetlenie.
|
||||
|
||||
Zwróć uwagę, że SpotDir to co innego niż light Dir w poprzednich zadaniach
|
||||
![](./img/spotlight.png)
|
||||
## Zmień shader słońca na bardziej realistyczny.
|
||||
### Zadanie*
|
||||
|
||||
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 **V**.
|
||||
|
||||
![](./img/sun.png)
|
@ -1,38 +0,0 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
in vec3 FragNormal;
|
||||
in vec4 vertexPosWorld;
|
||||
|
||||
uniform float exposition;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 viewDir = normalize(cameraPos - vertexPosWorld.xyz);
|
||||
vec3 normalizedNormal = normalize(FragNormal);
|
||||
|
||||
vec3 lightDir = normalize(lightPos - vertexPosWorld.xyz);
|
||||
|
||||
float diffuse = max(dot(normalizedNormal, lightDir), 0.0);
|
||||
|
||||
|
||||
vec3 normalizedViewDir = normalize(viewDir);
|
||||
vec3 reflectDir = reflect(-normalize(lightDir), normalizedNormal);
|
||||
float specular = pow(max(dot(normalizedViewDir, reflectDir), 0.0), 8.0);
|
||||
|
||||
//zad_6
|
||||
float distance = length(lightPos - vertexPosWorld.xyz);
|
||||
vec3 newLightColor = lightColor / distance;
|
||||
vec3 finalColor = newLightColor * (color * diffuse+specular);
|
||||
|
||||
finalColor = 1.0 - exp(-finalColor * exposition);
|
||||
|
||||
outColor = vec4(finalColor, 1.0);
|
||||
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec3 FragNormal;
|
||||
uniform mat4 modelMatrix;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
out vec3 viewDir;
|
||||
out vec4 vertexPosWorld;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
|
||||
vec4 transformedNormal = modelMatrix * vec4(vertexNormal, 0.0);
|
||||
FragNormal = normalize(transformedNormal.xyz);
|
||||
|
||||
vertexPosWorld = modelMatrix * vec4(vertexPosition, 1.0);
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 color;
|
||||
|
||||
in vec3 interpNormal;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
float rimIntensity = 0.5; // intensywnoϾ
|
||||
vec3 rimColor = vec3(1.0, 0.0, 0.0); // kolor rim
|
||||
float rim = dot(normalize(interpNormal), normalize(vec3(0.0, 0.0, 1.0))); // wektor (0, 0, 1) ¿eby na krawêdziach
|
||||
rim = 1 - pow(rim, 2); // jak szeroki jest ten rim
|
||||
|
||||
vec3 finalColor = color;
|
||||
|
||||
finalColor = mix(color, rimColor, rimIntensity * rim);
|
||||
|
||||
|
||||
out_color = vec4(finalColor, 1.0);
|
||||
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<!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 5</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;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
|
||||
<!--[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="oświetlenie-phonga">Oświetlenie Phonga</h2>
|
||||
<p>W trakcie tych zajęć zajmiemy się implementacją modelu oświetlenia Phonga. Na poprzednich zajęciach zbudowaliśmy układ słoneczny. Wykorzystamy go w trakcie tych zajęć. Jeżeli go zrobiłeś, to przekopiuj do <code>ex_5_1.hpp</code> kod z poprzednich zajęć. W przeciwnym wypadku wykorzystaj ten, który jest zaimplementowany w <code>ex_5_1.hpp</code>. W zadaniu będzie nam potrzebny statek latający przed kamerą, jak nie ma tego w Twojej scenie to skopiuj to z <code>ex_5_1.hpp</code>.</p>
|
||||
<h2 id="zadanie---diffuse">Zadanie - <em>diffuse</em></h2>
|
||||
<p>Oblicz we fragment shaderze oświetlenie obiektu przy użyciu modelu Phonga dla odbicia rozproszonego (*diffuse)</p>
|
||||
<p> 1. Przekaż źródło światła. Na razie przyjmiemy kierunkowy model oświetlenia, dlatego źródło będzie opisane jako wektor kierunkowy:</p>
|
||||
<ul>
|
||||
<li><p>Prześlij do shadera fragmentów 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łany jest kolor.</p></li>
|
||||
<li><p>Jako kierunek światła wybierz dowolny wektor jednostkowy. (Możesz wziąć dowolny niezerowy wektor następnie go znormalizować).</p></li>
|
||||
<li><p>Dodatkowo prześlij drugą zmienną <code>uniform vec3 lightColor</code>, w której umieścimy kolor światła. Prześlij tam wartości ze zmiennej <code>glm::vec3 lightColor</code>.</p></li>
|
||||
</ul>
|
||||
<ol start="2" type="1">
|
||||
<li>Oblicz natężenie w shaderze fragmentów:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li><p>prześlij normalne z shadera fragmentów do shadera wierzchołków</p></li>
|
||||
<li><p>znormalizuj wektor normalny przed użyciem go w obliczeniach (uśrednianie wektorów normalnych wierzchołków może spowodować, że 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="1">
|
||||
<li>Zastosuj obliczone natężenie, aby zmodyfikować kolor obiektu:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Przemnóż kolor RGB fragmentu przez obliczone natężenie i przez kolor światła z <code>lightColor</code>.</li>
|
||||
</ul>
|
||||
<h2 id="zadanie---obsługa-obrotów">Zadanie - obsługa obrotów</h2>
|
||||
<p>Dlaczego oświetlenie statku nie zmienia się podczas jego obracania?</p>
|
||||
<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: - Prześlij macierz modelu rysowanego obiektu (<em>model Matrix</em>) jako osobna zmienna do vertex shadera (<code>uniform mat4</code>).<br />
|
||||
- Przemnóż przez te macierz wektor normalny wierzchołka przed przesłaniem go do shadera fragmentów. - Współrzędna <strong>w</strong> dopisana do wektora przed mnożeniem przez macierz powinna być ustawiona na 0. Wynika to z tego, że 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>
|
||||
<h2 id="zadanie---specular">Zadanie - <em>specular</em></h2>
|
||||
<p>Uzupełnił model o czynnik odbicia zwierciadlanego (<em>specular</em>). W tym celu:</p>
|
||||
<ol type="1">
|
||||
<li>Potrzebny będzie wektor od rysowanego fragmentu do pozycji kamery:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Wyślij pozycje kamery (<code>cameraPos</code>) jako kolejna zmienna do fragment shadera.<br />
|
||||
</li>
|
||||
<li>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, że 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)</li>
|
||||
<li>Oblicz wektor <strong>V</strong> (<em>view direction</em>) jako znormalizowaną różnice pozycji kamery i pozycji fragmentu.</li>
|
||||
</ul>
|
||||
<ol start="2" type="1">
|
||||
<li>Oblicz natężenie światła odbitego we <em>fragment shaderze</em>:</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>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.</li>
|
||||
<li>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.</li>
|
||||
</ul>
|
||||
<ol start="3" type="1">
|
||||
<li>Ustal ostateczny kolor piksela na <code>objectColor * diffuse + lightColor * specular</code>. Oznacza to najprostszy przypadek, gdy kolor światła odbitego jest biały.</li>
|
||||
</ol>
|
||||
<h2 id="zadanie---oświetlenie-punktowe">Zadanie - oświetlenie punktowe</h2>
|
||||
<p>W układzie planetarnym obiektem oświetlającym powinno być słońce, dlatego zamień oświetlenie kierunkowe na punktowe:</p>
|
||||
<ul>
|
||||
<li>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>).</li>
|
||||
<li>Oblicz kierunek światła odejmując od pozycji światła pozycję fragmentu, znormalizuj wynik. Zapisz wynik w zmiennej <code>lightDir</code>.<br />
|
||||
</li>
|
||||
<li>Słońce będzie czarne, nie martw się tym, tylko spójrz na punkt następny.</li>
|
||||
</ul>
|
||||
<h2 id="zadanie---shader-słońca">Zadanie - shader słońca</h2>
|
||||
<p>Ź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.</p>
|
||||
<p>Celem tego zadania jest stworzenie shadera (<strong>shader_5_sun.vert</strong>_ i <strong>shader_5_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_5_1.frag</strong>) nadal mają rysować pozostałe obiekty. a) zainicjalizuj <em>program</em> (shadery): - Pliki <strong>shader_5_sun.vert</strong> i <strong>shader_5_sun.frag</strong> są identyczne z 5_1** przed zmianami, będą punktem wyjścia dla <em>shadera</em> słońca.</p>
|
||||
<ol type="1">
|
||||
<li><p>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_5_1.vert</strong> i <strong>shader_5_1.frag</strong> (parametry wejściowe to ścieżka do shadera wierzchołków i fragmentów <strong>shader_5_sun.vert</strong> i <strong>shader_5_sun.frag</strong>).</p></li>
|
||||
<li><p>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:</p></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>
|
||||
|
||||
|
||||
<h2 id="zadanie---osłabienie-światła-attenuation"> Zadanie - Zmień shader słońca na bardziej realistyczny </h2>
|
||||
|
||||
<p>Na poniższym obrazku jest zdjęcie słońca. Jest ono ciemniejsze na brzegach spróbuj uzyskać podobny efekt. Przydadzą się wektory normalnych i wektor <strong>V</strong> jak i funkcja mix.</p>
|
||||
<p><img src="./img/sun.png" /></p>
|
||||
|
||||
<h2 id="osłabienie-światła-tone-mapping">Osłabienie światła, tone mapping</h2>
|
||||
<h3 id="zadanie---osłabienie-światła-attenuation">Zadanie - Osłabienie światła (attenuation)</h3>
|
||||
<p>Światło pochodzące z punktowego źródła traci na sile wraz z dystansem. Wynika to z tego, że rozprasza się na większą powierzchnię. Dodaj ten efekt do shadera. Zamiast brać kolor światła bezpośrednio, podziel go przez kwadrat dystansu od źródła świata. Przed kwadratowaniem przemnoz diystans przez 10.0.</p>
|
||||
|
||||
<h4 id="tone-mapping">Tone mapping</h4>
|
||||
<p>Przez obecną zmianę scena stała się ciemna. Wymaga to od nas zmiany ‘koloru’ światła na wartości dużo większe niż do tej pory. Jeśli teraz to zrobimy i przesadzimy w drugą stronę, otrzymamy efekt prześwietlenia. Wynika to z ograniczenia zakresu kolorów do <span class="math inline">\([0,1]\)</span> (obsługą wyższych wartości nazywamy HDR). Rozwiązaniem jest pracowanie na wartościach powyżej 1 wykorzystanie <em>tone mappingu</em> do przeniesienia ich w zakres <span class="math inline">\([0,1]\)</span>. Istnieje wiele wzorów, które są wykorzystywane do tego, jeden z nich to:</p>
|
||||
<p><span class="math display">\[C_{mapped} = 1-e^{-C * E},\]</span> gdzie C to kolor sceny a E to parametr ekspozycji (z zakresu <span class="math inline">\((0,\infty)\)</span>, który może być dostosowany w zależności od jasności.
|
||||
|
||||
<h3 id="zadanie">Zadanie - Tone mapping</h3>
|
||||
Zwiększ siłę słońca przynajmniej stukrotnie. Zaimplementuj powyższą metodę tone mappingu i dodaj możliwość sterowania ekspozycją za pomocą klawiszy 1 i 2.</p>
|
||||
<h3 id="zadanie">Zadanie*</h3>
|
||||
<p>Dodaj drugie źródło oświetlenia w postaci reflektora statku. Reflektor świeci tylko w określonym stożku,dlatego oprócz pozycji <code>spotPos</code> posiada również kierunek <code>spotDir</code> i kąt świecenia <span class="math inline">\(\phi\)</span>. Po obliczeniu dla niego <code>lightDir</code> należy sprawdzić, czy iloczyn skalarny pomiędzy <code>lightDir</code> a <code>spodDir</code> jest większy niż <span class="math inline">\(\cos\phi\)</span> . Jeżeli nie jest, to stożek nie świeci w tym miejscu. Można ułatwić sobie implementację wielu źródeł światła poprzez przeniesienie obliczeń oświetlenia do funkcji, która przyjmuje kierunek światła i siłę naświetlenie.</p>
|
||||
Zwróć uwagę, że SpotDir to co innego niż light Dir w poprzednich zadaniach.
|
||||
<p><img src="./img/spotlight.png" /> </p>
|
||||
</body>
|
||||
</html>
|
197
cw 7/Zadania 7.html
Normal file
@ -0,0 +1,197 @@
|
||||
<!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 7</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;}
|
||||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||
div.sourceCode { margin: 1em 0; }
|
||||
pre.sourceCode { margin: 0; }
|
||||
@media screen {
|
||||
div.sourceCode { overflow: auto; }
|
||||
}
|
||||
@media print {
|
||||
pre > code.sourceCode { white-space: pre-wrap; }
|
||||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||
}
|
||||
pre.numberSource code
|
||||
{ counter-reset: source-line 0; }
|
||||
pre.numberSource code > span
|
||||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||
pre.numberSource code > span > a:first-child::before
|
||||
{ content: counter(source-line);
|
||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||
border: none; display: inline-block;
|
||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||
-khtml-user-select: none; -moz-user-select: none;
|
||||
-ms-user-select: none; user-select: none;
|
||||
padding: 0 4px; width: 4em;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||||
div.sourceCode
|
||||
{ }
|
||||
@media screen {
|
||||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||
}
|
||||
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||||
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||||
code span.at { color: #7d9029; } /* Attribute */
|
||||
code span.bn { color: #40a070; } /* BaseN */
|
||||
code span.bu { } /* BuiltIn */
|
||||
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||||
code span.ch { color: #4070a0; } /* Char */
|
||||
code span.cn { color: #880000; } /* Constant */
|
||||
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||||
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||||
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||||
code span.dt { color: #902000; } /* DataType */
|
||||
code span.dv { color: #40a070; } /* DecVal */
|
||||
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||||
code span.ex { } /* Extension */
|
||||
code span.fl { color: #40a070; } /* Float */
|
||||
code span.fu { color: #06287e; } /* Function */
|
||||
code span.im { } /* Import */
|
||||
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||||
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||||
code span.op { color: #666666; } /* Operator */
|
||||
code span.ot { color: #007020; } /* Other */
|
||||
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||||
code span.sc { color: #4070a0; } /* SpecialChar */
|
||||
code span.ss { color: #bb6688; } /* SpecialString */
|
||||
code span.st { color: #4070a0; } /* String */
|
||||
code span.va { color: #19177c; } /* Variable */
|
||||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||
</style>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="normal-mapping">Normal Mapping</h1>
|
||||
<p>W tej części będziemy dalej modyfikować shadery <strong>shader_5_tex</strong> poprzez implementację normal mappingu.</p>
|
||||
<p>Obliczenia dla map normalnych należy wykonywać w przestrzeni stycznych. Przestrzeń styczna jest wyliczana dla każdego punktu w obiekcie. Jej celem jest takie przekształcenie przestrzeni, żeby wektor normalny był wektorem jednostkowym (0,1,0).</p>
|
||||
<p>Do wyliczenia przestrzeni stycznej potrzebujemy dla każdego wierzchołka oprócz wektora normalnego wektor styczny i bistyczny (<em>tangent</em> i <em>bitangent</em>). Są one wyliczane przez bibliotekę <code>Assimp</code>.</p>
|
||||
<h3 id="wykonaj-kopię-shaderów-shader_4_tex.vert-shader_4_tex.frag">Wykonaj kopię shaderów shader_4_tex.vert shader_4_tex.frag</h3>
|
||||
<h3 id="przenieś-obliczenia-światła-do-przestrzeni-stycznej.">Przenieś obliczenia światła do przestrzeni stycznej.</h3>
|
||||
<ol type="1">
|
||||
<li><p>Oblicz macierz <strong>TBN</strong>.</p>
|
||||
<p>Macierz <strong>TBN</strong> to macierz 3x3 wyznaczana przez wektory <em>tangent</em>, <em>bitangent</em> i <em>normal</em>, służy do przenoszenia wektorów z przestrzeni świata do przestrzeni stycznej.</p>
|
||||
<ol type="1">
|
||||
<li>W <strong>vertex shaderze</strong> przekrztałć wektory <code>vertexNormal</code>, <code>vertexTangent</code> i <code>vertexBitangent</code> do przestrzeni świata (przemnóż macierz modelu przez te wektory, tak jak to robiliśmy wcześniej z wektorem normalnym, z uwzględnieniem zmiennej w=0) i zapisz wyniki odpowiednio w zmiennych <code>normal</code>, <code>tangent</code> i <code>bitangent</code>.
|
||||
<ol type="1">
|
||||
<li>Stwórz macierz 3x3 TBN jako transpose(mat3(tangent, bitangent, normal)). Macierz transponujemy, aby szybko uzyskać jej odwrotność (możemy tak zrobić przy założeniu, ze jest ortogonalna).</li>
|
||||
</ol></li>
|
||||
</ol></li>
|
||||
</ol>
|
||||
<ol start="2" type="1">
|
||||
<li>Przenieś wektor światła i wektor widoku do przestrzeni stycznych
|
||||
<ol type="1">
|
||||
<li><p>Musimy przekształcić wektor światła (L) i wektor widoku (V) do przestrzeni stycznych. Zrobimy to w vertex shaderze. W tym celu przenieś potrzebne dane dotyczące światła i kamery (uniformy <code>lightPos</code> i <code>cameraPos</code>) z <strong>fragment shadera</strong> do <strong>vertex shadera.</strong></p></li>
|
||||
<li><p>Oblicz wektor <code>viewDir</code> jako znormalizowana różnice <code>cameraPos</code> i <code>fragPos</code> (tu jeszcze działamy w przestrzeni świata). Analogicznie oblicz <code>lightDir</code> jako różnicę <code>lightPos</code> i <code>fragPos</code></p></li>
|
||||
<li><p>Przekształć wektory <code>viewDir</code> i <code>lightDir</code> do przestrzeni stycznej mnożąc je przez macierz <strong>TBN</strong>. Wynik zapisz w zmiennych<code>viewDirTS</code> i <code>lightDirTS</code> odpowiednio.</p></li>
|
||||
<li><p>Przekaż <code>viewDirTS</code> i <code>lightDirTS</code> do fragment shadera. (zadeklaruj je jako zmienne <code>out</code>)</p>
|
||||
<blockquote>
|
||||
<p>(Sufiks TS oznacza tangent space. Ważne jest, aby oznaczać (np. dopisując coś do nazwy zmiennej) w jakiej przestrzeni znajdują się używane wektory, tak aby poprawnie wykonywać obliczenia. Trzeba zawsze zwracać uwagę na to, w jakiej przestrzeni działamy.)</p>
|
||||
</blockquote></li>
|
||||
</ol></li>
|
||||
<li>Przekształć <strong>fragment shader</strong>, by obsługiwał <strong>tangent space</strong>
|
||||
<ol type="1">
|
||||
<li>Nie potrzebujemy już we <strong>fragment shaderze</strong> informacji na temat pozycji fragmentu i wektora normalnego geometrii, skasuj wiec zmienne przekazujące te wektory pomiędzy shaderami.</li>
|
||||
<li>wektora <code>lightDir</code> powinniśmy użyć wektora <code>lightDirTS</code> (należy go dodatkowo znormalizować), a jako wektor widoku V powinniśmy użyć wektora <code>viewDirTS</code> (również należy go znormalizować). Jako wektora N użyj na razie wektora vec3(0,0,1).</li>
|
||||
</ol></li>
|
||||
</ol>
|
||||
<p>Efekt finalny powinien wyglądać tak samo, jak przed jakąkolwiek zmianą. Następnym krokiem będzie wykorzystanie map normalnych.</p>
|
||||
<h3 id="wykorzystaj-normalmapy">Wykorzystaj normalmapy</h3>
|
||||
<ol type="1">
|
||||
<li>Chcemy wczytywać normalne z tekstury, w tym celu dodaj we <strong>fragment shaderze</strong> dodatkowy sampler do czytania map normalnych, nazwij go <code>normalSampler</code>. Pobierz z niego wektor normalny analogicznie, jak czytamy kolor zwykłej tekstury z samplera <code>textureSampler</code> i zapisz go w zmiennej <code>N</code>.
|
||||
<ol start="2" type="1">
|
||||
<li>Ponieważ w teksturze wartości są w przedziale <span class="math inline">\([0,1]\)</span>, musimy jeszcze przekształcić je do przedziału <span class="math inline">\([-1,1]\)</span>. W tym celu przemnóż wektor N przez 2 i odejmij 1. Na koniec warto jeszcze znormalizować wektor normalny, aby uniknąć błędów związanych z precyzja lub kompresja tekstury.</li>
|
||||
<li>Wczytaj pliki zawierające mapy normalnych w kodzie C++ W tym celu załaduj przy użyciu funkcji <code>Core::LoadTexture</code> mapy normalnych dla wszystkich modeli. Maja one taką samą nazwę jak zwykle tekstury, tyle że z suffiksem "_normals".</li>
|
||||
<li>Zmodyfikuj na koniec funkcje <code>drawObjectTexture</code>. Dodaj do niej nowy argument <code>GLuint normalmapId</code>, który będzie służył do przekazywania id tekstury zawierającej mapę normalnych. Przy użyciu funkcji <code>Core::SetActiveTexture</code> załaduj <code>normalmapId</code> jako <code>normalSampler</code> i ustaw jednostkę teksturowania nr 1. Argument odpowiadający za normalne w miejscach wywołania funkcji <code>drawObjectTexture</code>.</li>
|
||||
</ol></li>
|
||||
</ol>
|
||||
<h3 id="zadanie">Zadanie*</h3>
|
||||
<p>Ustaw mapy normalne do statku planety i księżyca (lub przynajmniej 3 obiektów, jeżeli rysujesz swoją scenę). Wykorzystaj multitexturing na statku, musisz w takim wypadku mieszać zarówno tekstury koloru i normalanych.</p>
|
||||
<h2 id="skybox">SkyBox</h2>
|
||||
<p>Cubemapy są specjalnym rodzajem tekstur. Zawieją one 6 tekstur, każda z niej odpowiada za inną ścianę sześcianu. Nie służy ona do teksturowania zwykłego sześcianu, pozwala ona bowiem próbkować po wektorze kierunku. To znaczy, możemy o tym myśleć jak o kostce, w której środku się znaleźliśmy, co obrazuje poniższy rysunek. W przeciwieństwie do zwykłych tekstur samplujemy ją nie za pomocą dwuwymiarowych współrzędnych UV, ale za pomocą wektora trójwymiarowego, który odpowiada kierunkowi promienia. <img src="./img/cubemaps_sampling.png" /> Jednym z zastosowań Cubemapy jest wyświetlanie skyboxa, czyli dalekiego tła dla sceny. Może to być na przykład rozgwieżdżone niebo z górami na horyzoncie albo obraz dalekiej galaktyki.</p>
|
||||
<h3 id="ładowanie-cubemapy">Ładowanie cubemapy</h3>
|
||||
<p>Cubemapę generujemy podobnie jak inne tekstury, ale przy bindowaniu należy podać <code>GL_TEXTURE_CUBE_MAP</code>.</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>glGenTextures(<span class="dv">1</span>, &textureID);</span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);</span></code></pre></div>
|
||||
<p>Skoro składa się ona z 6 tekstur, to należy każdą z nich załadować za pomocą <code>void glTexImage2D( GLenum target, ...)</code> <code>taget</code> wskazuje którą z tekstur ładujemy. Możliwe wartości rozpisane są w tabeli poniżej |Layer number|Texture target | Orientation| |—-|——————–:|———–:| |0|<code>GL_TEXTURE_CUBE_MAP_POSITIVE_X</code> | Right | |1|<code>GL_TEXTURE_CUBE_MAP_NEGATIVE_X</code>|Left| |2|<code>GL_TEXTURE_CUBE_MAP_POSITIVE_Y</code>|Top| |3|<code>GL_TEXTURE_CUBE_MAP_NEGATIVE_Y</code>|Bottom| |4|<code>GL_TEXTURE_CUBE_MAP_POSITIVE_Z</code>|Back| |5|<code>GL_TEXTURE_CUBE_MAP_NEGATIVE_Z</code>|Front|</p>
|
||||
<p>Możemy je ładować w pętli biorąc za kolejne targety <code>GL_TEXTURE_CUBE_MAP_POSITIVE_X+i</code>, ale należy pamiętać o powyższej kolejności. Poniższy kod ładuje do wszystkich 6 ścian tę samą teksturę, która znajduje się pod <code>filepath</code>.</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> w, h;</span>
|
||||
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="dt">unsigned</span> <span class="dt">char</span> *data; </span>
|
||||
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span>(<span class="dt">unsigned</span> <span class="dt">int</span> i = <span class="dv">0</span>; i < <span class="dv">6</span>; i++)</span>
|
||||
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>{</span>
|
||||
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a> <span class="dt">unsigned</span> <span class="dt">char</span>* image = SOIL_load_image(filepath, &w, &h, <span class="dv">0</span>, SOIL_LOAD_RGBA);</span>
|
||||
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a> glTexImage2D(</span>
|
||||
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a> GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, </span>
|
||||
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a> <span class="dv">0</span>, GL_RGBA, w, h, <span class="dv">0</span>, GL_RGBA, GL_UNSIGNED_BYTE, data</span>
|
||||
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a> );</span>
|
||||
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
|
||||
<p>Na koniec pozostaje ustawić parametry opisujące zachowanie tekstury:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);</span>
|
||||
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);</span>
|
||||
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);</span>
|
||||
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);</span>
|
||||
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); </span></code></pre></div>
|
||||
<h3 id="zadanie-1">Zadanie</h3>
|
||||
<p>Napisz funkcję, która będzie ładować cubmapę bazującą na tablicy 6 stringów i załaduj do niej tekstury z foldera <code>skybox</code>.</p>
|
||||
<h3 id="rysowanie-skyboxa">Rysowanie skyboxa</h3>
|
||||
<p>Skybox jest sześcianem, wewnątrz którego zamieszamy naszą scenę, przedstawia on dalekie tło, dzięki temu dostajemy iluzję głębi i przestrzeni. Do tego potrzebujemy narysować sześcian i narysować go odpowiednim shaderem. Rysowanie jest bardzo proste, polega wyłącznie na wyświetleniu koloru tekstury. Aby próbkować, teksturę potrzebujemy przesłać pozycję w przestrzeni modelu do shadera fragmentów.</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#</span><span class="er">version 430 core</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>layout(location = <span class="dv">0</span>) in vec3 vertexPosition;</span>
|
||||
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>uniform mat4 transformation;</span>
|
||||
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>out vec3 texCoord;</span>
|
||||
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main()</span>
|
||||
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>{</span>
|
||||
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a> texCoord = vertexPosition;</span>
|
||||
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a> gl_Position = transformation * vec4(vertexPosition, <span class="fl">1.0</span>);</span>
|
||||
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
|
||||
<blockquote>
|
||||
<p>shader_skybox.vert</p>
|
||||
</blockquote>
|
||||
<p>W shaderze fragmentów wystarczy odebrać pozycję i próbkować za jej pomocą teksturę.</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#</span><span class="er">version 430 core</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>uniform samplerCube skybox;</span>
|
||||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>in vec3 texCoord;</span>
|
||||
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>out vec4 out_color;</span>
|
||||
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> main()</span>
|
||||
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>{</span>
|
||||
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a> out_color = texture(skybox,texCoord);</span>
|
||||
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
|
||||
<blockquote>
|
||||
<p>shader_skybox.frag</p>
|
||||
</blockquote>
|
||||
<h3 id="zadanie-2">Zadanie</h3>
|
||||
<p>W modelach znajduje się <code>cube.obj</code>, załaduj go i narysuj shaderami <code>shader_skybox.vert</code> i <code>shader_skybox.vert</code>. Pamiętaj o przesłaniu macierzy transformacji i tekstury skyboxa. Aktywujemy ją za pomocą instrukcji:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode c++"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);</span></code></pre></div>
|
||||
<p>Skybox potencjalnie zasłania pewne obiekty, które są umieszczone trochę dalej. Wynika to z tego, że renderowanie go nadpisuje bufor głębokości. Dlatego narysuj cubemapę z wyłączonym testem głębokości na samym początku. Następnie włącz test głębokości dla reszty sceny. Dezaktywację wykonasz za pomocą instrukcji <code>glDisable(GL_DEPTH_TEST);</code>, natomiast aktywację za pomocą<code>glEnable(GL_DEPTH_TEST);</code>.</p>
|
||||
<p>Skybox reprezentuje obiekty, które są bardzo daleko. Tę iluzję możemy utracić, gdy kamera przysunie się zbyt blisko do skyboxa. Aby tego uniknąć, musimy tak umieścić skybox, by kamera zawsze była w jego środku. Przesuń skybox do pozycji kamery z użyciem macierzy translacji.</p>
|
||||
</body>
|
||||
</html>
|
148
cw 7/Zadania 7.md
Normal file
@ -0,0 +1,148 @@
|
||||
# Normal Mapping
|
||||
|
||||
W tej części będziemy dalej modyfikować shadery **shader_5_tex** poprzez implementację normal mappingu.
|
||||
|
||||
Obliczenia dla map normalnych należy wykonywać w przestrzeni stycznych. Przestrzeń styczna jest wyliczana dla każdego punktu w obiekcie. Jej celem jest takie przekształcenie przestrzeni, żeby wektor normalny był wektorem jednostkowym (0,1,0).
|
||||
|
||||
Do wyliczenia przestrzeni stycznej potrzebujemy dla każdego wierzchołka oprócz wektora normalnego wektor styczny i bistyczny (*tangent* i *bitangent*). Są one wyliczane przez bibliotekę `Assimp`.
|
||||
|
||||
### Wykonaj kopię shaderów shader_4_tex.vert shader_4_tex.frag
|
||||
|
||||
### Przenieś obliczenia światła do przestrzeni stycznej.
|
||||
|
||||
1) Oblicz macierz **TBN**.
|
||||
|
||||
Macierz **TBN** to macierz 3x3 wyznaczana przez wektory *tangent*, *bitangent* i *normal*, służy do przenoszenia wektorów z przestrzeni świata do przestrzeni stycznej.
|
||||
|
||||
1. W **vertex shaderze** przekrztałć wektory `vertexNormal`, `vertexTangent` i `vertexBitangent` do przestrzeni świata (przemnóż macierz modelu przez te wektory, tak jak to robiliśmy wcześniej z wektorem normalnym, z uwzględnieniem zmiennej w=0) i zapisz wyniki odpowiednio w zmiennych `normal`, `tangent` i `bitangent`.
|
||||
1. Stwórz macierz 3x3 TBN jako transpose(mat3(tangent, bitangent, normal)). Macierz transponujemy, aby szybko uzyskać jej odwrotność (możemy tak zrobić przy założeniu, ze jest ortogonalna).
|
||||
|
||||
2. Przenieś wektor światła i wektor widoku do przestrzeni stycznych
|
||||
1. Musimy przekształcić wektor światła (L) i wektor widoku (V) do przestrzeni stycznych. Zrobimy to w vertex shaderze. W tym celu przenieś potrzebne dane dotyczące światła i kamery (uniformy `lightPos` i `cameraPos`) z **fragment shadera** do **vertex shadera.**
|
||||
|
||||
2. Oblicz wektor `viewDir` jako znormalizowana różnice `cameraPos` i `fragPos` (tu jeszcze działamy w przestrzeni świata). Analogicznie oblicz `lightDir` jako różnicę `lightPos` i `fragPos`
|
||||
|
||||
3. Przekształć wektory `viewDir` i `lightDir` do przestrzeni stycznej mnożąc je przez macierz **TBN**. Wynik zapisz w zmiennych`viewDirTS` i `lightDirTS` odpowiednio.
|
||||
|
||||
4. Przekaż `viewDirTS` i `lightDirTS` do fragment shadera. (zadeklaruj je jako zmienne `out`)
|
||||
|
||||
> (Sufiks TS oznacza tangent space. Ważne jest, aby oznaczać (np. dopisując coś do nazwy zmiennej) w jakiej przestrzeni znajdują się używane wektory, tak aby poprawnie wykonywać obliczenia. Trzeba zawsze zwracać uwagę na to, w jakiej przestrzeni działamy.)
|
||||
|
||||
3. Przekształć **fragment shader**, by obsługiwał **tangent space**
|
||||
1. Nie potrzebujemy już we **fragment shaderze** informacji na temat pozycji fragmentu i wektora normalnego geometrii, skasuj wiec zmienne przekazujące te wektory pomiędzy shaderami.
|
||||
2. wektora `lightDir` powinniśmy użyć wektora `lightDirTS` (należy go dodatkowo znormalizować), a jako wektor widoku V powinniśmy użyć wektora `viewDirTS` (również należy go znormalizować). Jako wektora N użyj na razie wektora vec3(0,0,1).
|
||||
|
||||
Efekt finalny powinien wyglądać tak samo, jak przed jakąkolwiek zmianą. Następnym krokiem będzie wykorzystanie map normalnych.
|
||||
|
||||
### Wykorzystaj normalmapy
|
||||
|
||||
1. Chcemy wczytywać normalne z tekstury, w tym celu dodaj we **fragment shaderze** dodatkowy sampler do czytania map normalnych, nazwij go `normalSampler`. Pobierz z niego wektor normalny analogicznie, jak czytamy kolor zwykłej tekstury z samplera `textureSampler` i zapisz go w zmiennej `N`.
|
||||
2. Ponieważ w teksturze wartości są w przedziale $[0,1]$, musimy jeszcze przekształcić je do przedziału $[-1,1]$. W tym celu przemnóż wektor N przez 2 i odejmij 1.
|
||||
Na koniec warto jeszcze znormalizować wektor normalny, aby uniknąć błędów związanych z precyzja lub kompresja tekstury.
|
||||
3. Wczytaj pliki zawierające mapy normalnych w kodzie C++ W tym celu załaduj przy użyciu funkcji `Core::LoadTexture` mapy normalnych dla wszystkich modeli. Maja one taką samą nazwę jak zwykle tekstury, tyle że z suffiksem "_normals".
|
||||
4. Zmodyfikuj na koniec funkcje `drawObjectTexture`. Dodaj do niej nowy argument `GLuint normalmapId`, który będzie służył do przekazywania id tekstury zawierającej mapę normalnych. Przy użyciu funkcji `Core::SetActiveTexture` załaduj `normalmapId` jako `normalSampler` i ustaw jednostkę teksturowania nr 1.
|
||||
Argument odpowiadający za normalne w miejscach wywołania funkcji `drawObjectTexture`.
|
||||
|
||||
|
||||
### Zadanie*
|
||||
Ustaw mapy normalne do statku planety i księżyca (lub przynajmniej 3 obiektów, jeżeli rysujesz swoją scenę). Wykorzystaj multitexturing na statku, musisz w takim wypadku mieszać zarówno tekstury koloru i normalanych.
|
||||
|
||||
## SkyBox
|
||||
Cubemapy są specjalnym rodzajem tekstur. Zawieją one 6 tekstur, każda z niej odpowiada za inną ścianę sześcianu. Nie służy ona do teksturowania zwykłego sześcianu, pozwala ona bowiem próbkować po wektorze kierunku. To znaczy, możemy o tym myśleć jak o kostce, w której środku się znaleźliśmy, co obrazuje poniższy rysunek. W przeciwieństwie do zwykłych tekstur samplujemy ją nie za pomocą dwuwymiarowych współrzędnych UV, ale za pomocą wektora trójwymiarowego, który odpowiada kierunkowi promienia.
|
||||
![](./img/cubemaps_sampling.png)
|
||||
Jednym z zastosowań Cubemapy jest wyświetlanie skyboxa, czyli dalekiego tła dla sceny. Może to być na przykład rozgwieżdżone niebo z górami na horyzoncie albo obraz dalekiej galaktyki.
|
||||
|
||||
### Ładowanie cubemapy
|
||||
Cubemapę generujemy podobnie jak inne tekstury, ale przy bindowaniu należy podać `GL_TEXTURE_CUBE_MAP`.
|
||||
```C++
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
|
||||
```
|
||||
Skoro składa się ona z 6 tekstur, to należy każdą z nich załadować za pomocą `void glTexImage2D( GLenum target, ...)` `taget` wskazuje którą z tekstur ładujemy. Możliwe wartości rozpisane są w tabeli poniżej
|
||||
|Layer number|Texture target | Orientation|
|
||||
|----|--------------------:|-----------:|
|
||||
|0|`GL_TEXTURE_CUBE_MAP_POSITIVE_X` | Right |
|
||||
|1|`GL_TEXTURE_CUBE_MAP_NEGATIVE_X`|Left|
|
||||
|2|`GL_TEXTURE_CUBE_MAP_POSITIVE_Y`|Top|
|
||||
|3|`GL_TEXTURE_CUBE_MAP_NEGATIVE_Y`|Bottom|
|
||||
|4|`GL_TEXTURE_CUBE_MAP_POSITIVE_Z`|Back|
|
||||
|5|`GL_TEXTURE_CUBE_MAP_NEGATIVE_Z`|Front|
|
||||
|
||||
Możemy je ładować w pętli biorąc za kolejne targety `GL_TEXTURE_CUBE_MAP_POSITIVE_X+i`, ale należy pamiętać o powyższej kolejności. Poniższy kod ładuje do wszystkich 6 ścian tę samą teksturę, która znajduje się pod `filepath`.
|
||||
|
||||
```C++
|
||||
|
||||
int w, h;
|
||||
unsigned char *data;
|
||||
for(unsigned int i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned char* image = SOIL_load_image(filepath, &w, &h, 0, SOIL_LOAD_RGBA);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||
0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data
|
||||
);
|
||||
}
|
||||
```
|
||||
Na koniec pozostaje ustawić parametry opisujące zachowanie tekstury:
|
||||
```C++
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
```
|
||||
|
||||
### Zadanie
|
||||
Napisz funkcję, która będzie ładować cubmapę bazującą na tablicy 6 stringów i załaduj do niej tekstury z foldera `skybox`.
|
||||
|
||||
### Rysowanie skyboxa
|
||||
Skybox jest sześcianem, wewnątrz którego zamieszamy naszą scenę, przedstawia on dalekie tło, dzięki temu dostajemy iluzję głębi i przestrzeni. Do tego potrzebujemy narysować sześcian i narysować go odpowiednim shaderem. Rysowanie jest bardzo proste, polega wyłącznie na wyświetleniu koloru tekstury. Aby próbkować, teksturę potrzebujemy przesłać pozycję w przestrzeni modelu do shadera fragmentów.
|
||||
|
||||
```C++
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec3 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
texCoord = vertexPosition;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
||||
|
||||
```
|
||||
> shader_skybox.vert
|
||||
|
||||
W shaderze fragmentów wystarczy odebrać pozycję i próbkować za jej pomocą teksturę.
|
||||
|
||||
```C++
|
||||
#version 430 core
|
||||
|
||||
uniform samplerCube skybox;
|
||||
|
||||
in vec3 texCoord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = texture(skybox,texCoord);
|
||||
}
|
||||
|
||||
```
|
||||
> shader_skybox.frag
|
||||
|
||||
### Zadanie
|
||||
W modelach znajduje się `cube.obj`, załaduj go i narysuj shaderami `shader_skybox.vert` i `shader_skybox.vert`. Pamiętaj o przesłaniu macierzy transformacji i tekstury skyboxa. Aktywujemy ją za pomocą instrukcji:
|
||||
```C++
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
|
||||
```
|
||||
|
||||
Skybox potencjalnie zasłania pewne obiekty, które są umieszczone trochę dalej. Wynika to z tego, że renderowanie go nadpisuje bufor głębokości. Dlatego narysuj cubemapę z wyłączonym testem głębokości na samym początku. Następnie włącz test głębokości dla reszty sceny.
|
||||
Dezaktywację wykonasz za pomocą instrukcji `glDisable(GL_DEPTH_TEST);`, natomiast aktywację za pomocą`glEnable(GL_DEPTH_TEST);`.
|
||||
|
||||
Skybox reprezentuje obiekty, które są bardzo daleko. Tę iluzję możemy utracić, gdy kamera przysunie się zbyt blisko do skyboxa. Aby tego uniknąć, musimy tak umieścić skybox, by kamera zawsze była w jego środku. Przesuń skybox do pozycji kamery z użyciem macierzy translacji.
|
||||
|
BIN
cw 7/assimp-vc141-mt.dll
Normal file
BIN
cw 7/assimp-vc141-mtd.dll
Normal file
@ -20,10 +20,11 @@
|
||||
<ClCompile Include="src\SOIL\image_helper.c" />
|
||||
<ClCompile Include="src\SOIL\SOIL.c" />
|
||||
<ClCompile Include="src\SOIL\stb_image_aug.c" />
|
||||
<ClCompile Include="src\Texture.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Camera.h" />
|
||||
<ClInclude Include="src\ex_5_1.hpp" />
|
||||
<ClInclude Include="src\ex_7_1.hpp" />
|
||||
<ClInclude Include="src\objload.h" />
|
||||
<ClInclude Include="src\Render_Utils.h" />
|
||||
<ClInclude Include="src\Shader_Loader.h" />
|
||||
@ -33,19 +34,26 @@
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug.h" />
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug_c.h" />
|
||||
<ClInclude Include="src\SOIL\stb_image_aug.h" />
|
||||
<ClInclude Include="src\Texture.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="shaders\shader_5_1.frag" />
|
||||
<None Include="shaders\shader_5_1.vert" />
|
||||
<None Include="shaders\shader_5_1_tex.frag" />
|
||||
<None Include="shaders\shader_5_1_tex.vert" />
|
||||
<None Include="shaders\shader_5_sun.frag" />
|
||||
<None Include="shaders\shader_5_sun.vert" />
|
||||
<None Include="shaders\shader_5_tex.frag" />
|
||||
<None Include="shaders\shader_5_tex.vert" />
|
||||
<None Include="shaders\shader_skybox.frag" />
|
||||
<None Include="shaders\shader_skybox.vert" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{7B84D06D-946D-4DCB-BD1A-B5635B0F83F0}</ProjectGuid>
|
||||
<ProjectGuid>{F2FC2E8F-CBA6-49D7-8B73-4BFBCB64D310}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>grk-cw5</RootNamespace>
|
||||
<RootNamespace>grk-cw7</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>grk-cw5</ProjectName>
|
||||
<ProjectName>grk-cw7</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
@ -17,7 +17,7 @@
|
||||
<UniqueIdentifier>{0a247bb8-2e8e-4a90-b0ef-17415b0941ba}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\SOIL">
|
||||
<UniqueIdentifier>{fd2042cb-5cbc-4508-9e27-cb1e07254eb9}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0af44075-33f4-4953-b1d6-1d28d61d758f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -39,18 +39,18 @@
|
||||
<ClCompile Include="src\Texture.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_DXT.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_helper.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\SOIL.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\stb_image_aug.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_DXT.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\SOIL\image_helper.c">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\objload.h">
|
||||
@ -65,15 +65,9 @@
|
||||
<ClInclude Include="src\Camera.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ex_5_1.hpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\Texture.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\image_DXT.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\image_helper.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
@ -89,11 +83,14 @@
|
||||
<ClInclude Include="src\SOIL\stbi_DDS_aug_c.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\SOIL\image_DXT.h">
|
||||
<Filter>Source Files\SOIL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\ex_7_1.hpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="shaders\shader_5_1.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_sun.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
@ -103,5 +100,26 @@
|
||||
<None Include="shaders\shader_5_1.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_1.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_1_tex.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_1_tex.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_skybox.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_skybox.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_tex.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_5_tex.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 190 KiB |
Before Width: | Height: | Size: 329 KiB After Width: | Height: | Size: 329 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 978 KiB After Width: | Height: | Size: 978 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
Before Width: | Height: | Size: 260 KiB After Width: | Height: | Size: 260 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
12
cw 7/models/cube.mtl
Normal file
@ -0,0 +1,12 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 1
|
||||
|
||||
newmtl _PBR
|
||||
Ns 225.000000
|
||||
Ka 1.000000 1.000000 1.000000
|
||||
Kd 0.053704 0.053704 0.053704
|
||||
Ks 0.500000 0.500000 0.500000
|
||||
Ke 0.000000 0.000000 0.000000
|
||||
Ni 1.450000
|
||||
d 1.000000
|
||||
illum 3
|
7
cw 7/render.py
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
import os
|
||||
rootdir = './'
|
||||
for filename in os.listdir(rootdir):
|
||||
if filename.endswith(".md"):
|
||||
name = filename[:-3]
|
||||
os.system(f'pandoc -s -o "{name}.html" "{name}.md" --mathjax --css style.css')
|
18
cw 7/shaders/shader_5_1.frag
Normal file
@ -0,0 +1,18 @@
|
||||
#version 430 core
|
||||
|
||||
float AMBIENT = 0.1;
|
||||
|
||||
uniform vec3 color;
|
||||
uniform vec3 lightPos;
|
||||
|
||||
in vec3 vecNormal;
|
||||
in vec3 worldPos;
|
||||
|
||||
out vec4 outColor;
|
||||
void main()
|
||||
{
|
||||
vec3 lightDir = normalize(lightPos-worldPos);
|
||||
vec3 normal = normalize(vecNormal);
|
||||
float diffuse=max(0,dot(normal,lightDir));
|
||||
outColor = vec4(color*min(1,AMBIENT+diffuse), 1.0);
|
||||
}
|
@ -4,12 +4,15 @@ layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
|
||||
uniform mat4 transformation;
|
||||
out vec3 interpNormal;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
out vec3 vecNormal;
|
||||
out vec3 worldPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
|
||||
vecNormal = (modelMatrix* vec4(vertexNormal,0)).xyz;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
interpNormal = normalize(transformation * vec4(vertexNormal, 0.0)).xyz;
|
||||
}
|
21
cw 7/shaders/shader_5_1_tex.frag
Normal file
@ -0,0 +1,21 @@
|
||||
#version 430 core
|
||||
|
||||
float AMBIENT = 0.1;
|
||||
|
||||
uniform vec3 color;
|
||||
uniform vec3 lightPos;
|
||||
uniform sampler2D colorTexture;
|
||||
|
||||
in vec3 vecNormal;
|
||||
in vec3 worldPos;
|
||||
in vec2 vecTex;
|
||||
|
||||
out vec4 outColor;
|
||||
void main()
|
||||
{
|
||||
vec3 lightDir = normalize(lightPos-worldPos);
|
||||
vec3 normal = normalize(vecNormal);
|
||||
vec3 textureColor = texture2D(colorTexture, vecTex).xyz;
|
||||
float diffuse=max(0,dot(normal,lightDir));
|
||||
outColor = vec4(textureColor*min(1,AMBIENT+diffuse), 1.0);
|
||||
}
|
23
cw 7/shaders/shader_5_1_tex.vert
Normal file
@ -0,0 +1,23 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
layout(location = 3) in vec3 vertexTangent;
|
||||
layout(location = 4) in vec3 vertexBitangent;
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
out vec3 vecNormal;
|
||||
out vec3 worldPos;
|
||||
out vec2 vecTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
|
||||
vecNormal = (modelMatrix* vec4(vertexNormal,0)).xyz;
|
||||
vecTex = vertexTexCoord;
|
||||
vecTex.y = 1.0 - vecTex.y;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
10
cw 7/shaders/shader_5_sun.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 430 core
|
||||
|
||||
uniform vec3 objectColor;
|
||||
|
||||
in vec3 interpNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(objectColor, 1.0);
|
||||
}
|
15
cw 7/shaders/shader_5_sun.vert
Normal file
@ -0,0 +1,15 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec2 vertexTexCoord;
|
||||
layout(location = 2) in vec3 vertexNormal;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec3 interpNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
interpNormal = vertexNormal;
|
||||
}
|
31
cw 7/shaders/shader_5_tex.frag
Normal file
@ -0,0 +1,31 @@
|
||||
#version 430 core
|
||||
|
||||
float AMBIENT = 0.1;
|
||||
|
||||
uniform vec3 color;
|
||||
uniform sampler2D colorTexture;
|
||||
uniform sampler2D normalSampler;
|
||||
|
||||
in vec3 worldPos;
|
||||
in vec2 vecTex;
|
||||
|
||||
in vec3 viewDirTS;
|
||||
in vec3 lightDirTS;
|
||||
|
||||
out vec4 outColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 normal = vec3(0,0,1);
|
||||
vec3 lightDir = normalize(lightDirTS);
|
||||
|
||||
vec3 textureColor = texture2D(colorTexture, vecTex).xyz;
|
||||
|
||||
vec3 N = texture2D(normalSampler, vecTex).xyz;
|
||||
N = 2.0 * N - 1.0;
|
||||
N = normalize(N);
|
||||
|
||||
//float diffuse=max(0,dot(normal,lightDir));
|
||||
float diffuse=max(0,dot(N,lightDir));
|
||||
outColor = vec4(textureColor*min(1,AMBIENT+diffuse), 1.0);
|
||||
}
|
43
cw 7/shaders/shader_5_tex.vert
Normal file
@ -0,0 +1,43 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
layout(location = 3) in vec3 vertexTangent;
|
||||
layout(location = 4) in vec3 vertexBitangent;
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
out vec3 worldPos;
|
||||
out vec2 vecTex;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 cameraPos;
|
||||
|
||||
out vec3 viewDirTS;
|
||||
out vec3 lightDirTS;
|
||||
|
||||
mat3 TBN;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 tangent = normalize(mat3(modelMatrix) * vertexTangent);
|
||||
vec3 bitangent = normalize(mat3(modelMatrix) * vertexBitangent);
|
||||
vec3 normal = normalize(mat3(modelMatrix) * vertexNormal);
|
||||
|
||||
TBN = transpose(mat3(tangent, bitangent, normal));
|
||||
|
||||
vec3 worldPos = (modelMatrix * vec4(vertexPosition, 1)).xyz;
|
||||
|
||||
vec3 viewDir = normalize(cameraPos - worldPos);
|
||||
vec3 lightDir = normalize(lightPos - worldPos);
|
||||
|
||||
viewDirTS = vec3(TBN * viewDir);
|
||||
lightDirTS = vec3(TBN * lightDir);
|
||||
|
||||
vecTex = vertexTexCoord;
|
||||
vecTex.y = 1.0 - vecTex.y;
|
||||
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
12
cw 7/shaders/shader_skybox.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 430 core
|
||||
|
||||
uniform samplerCube skybox;
|
||||
|
||||
in vec3 texCoord;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = texture(skybox,texCoord);
|
||||
}
|
13
cw 7/shaders/shader_skybox.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
|
||||
uniform mat4 transformation;
|
||||
|
||||
out vec3 texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
texCoord = vertexPosition;
|
||||
gl_Position = transformation * vec4(vertexPosition, 1.0);
|
||||
}
|
39
cw 7/src/Texture.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "Texture.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include "SOIL/SOIL.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
GLuint Core::LoadTexture( const char * filepath )
|
||||
{
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
int w, h;
|
||||
unsigned char* image = SOIL_load_image(filepath, &w, &h, 0, SOIL_LOAD_RGBA);
|
||||
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
SOIL_free_image_data(image);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Core::SetActiveTexture(GLuint textureID, const char * shaderVariableName, GLuint programID, int textureUnit)
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(programID, shaderVariableName), textureUnit);
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
}
|
15
cw 7/src/Texture.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
GLuint LoadTexture(const char * filepath);
|
||||
|
||||
// textureID - identyfikator tekstury otrzymany z funkcji LoadTexture
|
||||
// shaderVariableName - nazwa zmiennej typu 'sampler2D' w shaderze, z ktora ma zostac powiazana tekstura
|
||||
// programID - identyfikator aktualnego programu karty graficznej
|
||||
// textureUnit - indeks jednostki teksturujacej - liczba od 0 do 7. Jezeli uzywa sie wielu tekstur w jednym shaderze, to kazda z nich nalezy powiazac z inna jednostka.
|
||||
void SetActiveTexture(GLuint textureID, const char * shaderVariableName, GLuint programID, int textureUnit);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#include "glew.h"
|
||||
#include "glew.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "glm.hpp"
|
||||
#include "ext.hpp"
|
||||
@ -7,28 +7,46 @@
|
||||
|
||||
#include "Shader_Loader.h"
|
||||
#include "Render_Utils.h"
|
||||
#include "Camera.h"
|
||||
#include "Texture.h"
|
||||
|
||||
#include "Box.cpp"
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <string>
|
||||
#include "SOIL/SOIL.h"
|
||||
|
||||
|
||||
namespace texture {
|
||||
GLuint earth;
|
||||
GLuint clouds;
|
||||
GLuint moon;
|
||||
GLuint ship;
|
||||
GLuint rust;
|
||||
|
||||
GLuint grid;
|
||||
|
||||
GLuint earthNormal;
|
||||
GLuint moonNormal;
|
||||
GLuint shipNormal;
|
||||
GLuint rustNormal;
|
||||
}
|
||||
|
||||
|
||||
GLuint program;
|
||||
|
||||
|
||||
GLuint programSun;
|
||||
GLuint programTex;
|
||||
GLuint programEarth;
|
||||
GLuint programProcTex;
|
||||
GLuint programSkyBox;
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
Core::RenderContext shipContext;
|
||||
Core::RenderContext sphereContext;
|
||||
Core::RenderContext cubeContext;
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
glm::vec3 lightColor = glm::vec3(1.f, 1.f, 1.f);
|
||||
glm::vec3 lightDir = glm::vec3(0.5, 0.5, 0.5);
|
||||
|
||||
glm::vec3 spaceshipPos = glm::vec3(-4.f, 0, 0);
|
||||
glm::vec3 spaceshipDir = glm::vec3(1.f, 0.f, 0.f);
|
||||
@ -36,23 +54,7 @@ GLuint VAO,VBO;
|
||||
|
||||
float aspectRatio = 1.f;
|
||||
|
||||
float lastTime = -1.f;
|
||||
float deltaTime = 0.f;
|
||||
|
||||
float exposition = 5.0f;
|
||||
|
||||
GLuint programSun;
|
||||
|
||||
void updateDeltaTime(float time) {
|
||||
if (lastTime < 0) {
|
||||
lastTime = time;
|
||||
return;
|
||||
}
|
||||
|
||||
deltaTime = time - lastTime;
|
||||
if (deltaTime > 0.1) deltaTime = 0.1;
|
||||
lastTime = time;
|
||||
}
|
||||
unsigned int textureID;
|
||||
|
||||
glm::mat4 createCameraMatrix()
|
||||
{
|
||||
@ -91,27 +93,42 @@ glm::mat4 createPerspectiveMatrix()
|
||||
return perspectiveMatrix;
|
||||
}
|
||||
|
||||
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color, GLuint program) {
|
||||
void drawObjectColor(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) {
|
||||
|
||||
glUseProgram(program);
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniform3f(glGetUniformLocation(program, "color"), color.x,color.y,color.z);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
|
||||
glm::vec3 lightDir = glm::normalize(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
glm::vec3 lightColor = glm::vec3(0.0f, 1.0f, 1.0f);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "cameraPos"), 1, glm::value_ptr(cameraPos));
|
||||
|
||||
glUniform1f(glGetUniformLocation(program, "exposition"), exposition);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
|
||||
glUniform3f(glGetUniformLocation(program, "color"), color.x, color.y, color.z);
|
||||
glUniform3f(glGetUniformLocation(program, "lightPos"), 0,0,0);
|
||||
Core::DrawContext(context);
|
||||
glUseProgram(0);
|
||||
|
||||
}
|
||||
void drawObjectTexture(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint textureID, GLuint normalMapId) {
|
||||
glUseProgram(programTex);
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(programTex, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniformMatrix4fv(glGetUniformLocation(programTex, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
|
||||
glUniform3f(glGetUniformLocation(programTex, "lightPos"), 0, 0, 0);
|
||||
Core::SetActiveTexture(normalMapId, "normalSampler", programTex, 1);
|
||||
Core::SetActiveTexture(textureID, "colorTexture", programTex, 0);
|
||||
Core::DrawContext(context);
|
||||
|
||||
}
|
||||
void drawObjectSkyBox(Core::RenderContext& context, glm::mat4 modelMatrix) {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glUseProgram(programSkyBox);
|
||||
glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix();
|
||||
glm::mat4 transformation = viewProjectionMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(programSkyBox, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniformMatrix4fv(glGetUniformLocation(programSkyBox, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
|
||||
glUniform3f(glGetUniformLocation(programSkyBox, "lightPos"), 0, 0, 0);
|
||||
//Core::SetActiveTexture(textureID, "colorTexture", programSkyBox, 0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
|
||||
Core::DrawContext(context);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
}
|
||||
void renderScene(GLFWwindow* window)
|
||||
@ -120,25 +137,15 @@ void renderScene(GLFWwindow* window)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glm::mat4 transformation;
|
||||
float time = glfwGetTime();
|
||||
updateDeltaTime(time);
|
||||
drawObjectSkyBox(cubeContext, glm::translate(cameraPos));
|
||||
|
||||
|
||||
//Uniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
drawObjectTexture(sphereContext, glm::mat4(), texture::rust, texture::rustNormal);
|
||||
|
||||
|
||||
drawObjectTexture(sphereContext, glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::scale(glm::vec3(0.3f)), texture::earth, texture::earthNormal);
|
||||
|
||||
glm::vec3 sunPosition = glm::vec3(0.0, 0.0, 0.0);
|
||||
glm::mat4 sunModelMatrix = glm::translate(glm::vec3(1.0f, 1.0f, 0.3f));
|
||||
drawObjectColor(sphereContext, sunModelMatrix, glm::vec3(1.0, 1.0, 0.3), programSun);
|
||||
|
||||
glUniform3fv(glGetUniformLocation(program, "lightPos"), 1, glm::value_ptr(sunPosition));
|
||||
|
||||
drawObjectColor(sphereContext, glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::scale(glm::vec3(0.3f)), glm::vec3(0.2, 0.7, 0.3), program);
|
||||
|
||||
drawObjectColor(sphereContext,
|
||||
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)),
|
||||
glm::vec3(0.5, 0.5, 0.5), program);
|
||||
drawObjectTexture(sphereContext,
|
||||
glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)), texture::moon, texture::moonNormal);
|
||||
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir));
|
||||
@ -154,13 +161,16 @@ void renderScene(GLFWwindow* window)
|
||||
// glm::translate(cameraPos + 1.5 * cameraDir + cameraUp * -0.5f) * inveseCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
|
||||
// glm::vec3(0.3, 0.3, 0.5)
|
||||
// );
|
||||
drawObjectColor(shipContext,
|
||||
glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()) * glm::scale(glm::vec3(0.2f)),
|
||||
glm::vec3(0.3, 0.3, 0.5),
|
||||
program
|
||||
);
|
||||
drawObjectTexture(shipContext,
|
||||
glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi<float>()),
|
||||
texture::ship, texture::shipNormal
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
glUseProgram(0);
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
@ -188,20 +198,75 @@ void init(GLFWwindow* window)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
program = shaderLoader.CreateProgram("shaders/shader_5_1.vert", "shaders/shader_5_1.frag");
|
||||
|
||||
programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag");
|
||||
//programTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
|
||||
//programEarth = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
|
||||
//programProcTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag");
|
||||
|
||||
programTex = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
|
||||
programEarth = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
|
||||
programProcTex = shaderLoader.CreateProgram("shaders/shader_5_tex.vert", "shaders/shader_5_tex.frag");
|
||||
|
||||
programSkyBox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag");
|
||||
|
||||
loadModelToContext("./models/sphere.obj", sphereContext);
|
||||
loadModelToContext("./models/spaceship.obj", shipContext);
|
||||
loadModelToContext("./models/cube.obj", cubeContext);
|
||||
|
||||
texture::earth = Core::LoadTexture("textures/earth.png");
|
||||
texture::ship = Core::LoadTexture("textures/spaceship.jpg");
|
||||
texture::moon = Core::LoadTexture("textures/moon.jpg");
|
||||
texture::rust = Core::LoadTexture("textures/rust.jpg");
|
||||
|
||||
texture::earthNormal = Core::LoadTexture("textures/earth_normalmap.png");
|
||||
texture::shipNormal = Core::LoadTexture("textures/spaceship_normal.jpg");
|
||||
texture::rustNormal = Core::LoadTexture("textures/rust_normal.jpg");
|
||||
texture::moonNormal = Core::LoadTexture("textures/moon_normal.jpg");
|
||||
|
||||
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
|
||||
|
||||
std::vector<std::string> filepaths = {
|
||||
"textures/skybox/space_rt.png",
|
||||
"textures/skybox/space_lf.png",
|
||||
"textures/skybox/space_up.png",
|
||||
"textures/skybox/space_dn.png",
|
||||
"textures/skybox/space_bk.png",
|
||||
"textures/skybox/space_ft.png",
|
||||
|
||||
|
||||
// Ustaw wartości dla lightDir i lightColor potem prześlij do shadera
|
||||
//glm::vec3 lightDir = glm::normalize(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
//glm::vec3 lightColor = glm::vec3(0.0f, 1.0f, 1.0f);
|
||||
//"textures/skybox/corona_rt.png",
|
||||
//"textures/skybox/corona_lf.png",
|
||||
//"textures/skybox/corona_up.png",
|
||||
//"textures/skybox/corona_dn.png",
|
||||
//
|
||||
//"textures/skybox/corona_bk.png",
|
||||
//"textures/skybox/corona_ft.png",
|
||||
|
||||
//glUseProgram(program);
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightDir"), 1, glm::value_ptr(lightDir));
|
||||
//glUniform3fv(glGetUniformLocation(program, "lightColor"), 1, glm::value_ptr(lightColor));
|
||||
//glUseProgram(0);
|
||||
//"textures/skybox_new/posx.jpg",
|
||||
//"textures/skybox_new/negx.jpg",
|
||||
//"textures/skybox_new/posy.jpg",
|
||||
//"textures/skybox_new/negy.jpg",
|
||||
//"textures/skybox_new/posz.jpg",
|
||||
//"textures/skybox_new/negz.jpg"
|
||||
};
|
||||
|
||||
int w, h;
|
||||
unsigned char* image;
|
||||
for (unsigned int i = 0; i < 6; i++)
|
||||
{
|
||||
image = SOIL_load_image(filepaths[i].c_str(), &w, &h, 0, SOIL_LOAD_RGBA);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
|
||||
0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image
|
||||
);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
}
|
||||
|
||||
@ -215,12 +280,8 @@ void processInput(GLFWwindow* window)
|
||||
{
|
||||
glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f)));
|
||||
glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f);
|
||||
float angleSpeed = 0.05f * deltaTime * 60;
|
||||
float moveSpeed = 0.05f * deltaTime * 60;
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
|
||||
angleSpeed *= 3;
|
||||
moveSpeed *= 3;
|
||||
}
|
||||
float angleSpeed = 0.005f;
|
||||
float moveSpeed = 0.0025f;
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
@ -241,13 +302,7 @@ void processInput(GLFWwindow* window)
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0));
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS)
|
||||
exposition += 0.1;
|
||||
if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS)
|
||||
exposition -= 0.1;
|
||||
|
||||
|
||||
cameraPos = spaceshipPos - 0.3f * spaceshipDir + glm::vec3(0, 1, 0) * 0.1f;
|
||||
cameraPos = spaceshipPos - 1.5 * spaceshipDir + glm::vec3(0, 1, 0) * 0.5f;
|
||||
cameraDir = spaceshipDir;
|
||||
|
||||
//cameraDir = glm::normalize(-cameraPos);
|
@ -6,7 +6,7 @@
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "ex_5_1.hpp"
|
||||
#include "ex_7_1.hpp"
|
||||
|
||||
|
||||
|
BIN
cw 7/textures/clouds.jpg
Normal file
After Width: | Height: | Size: 9.2 MiB |
BIN
cw 7/textures/earth.png
Normal file
After Width: | Height: | Size: 148 KiB |
BIN
cw 7/textures/earth2.png
Normal file
After Width: | Height: | Size: 4.4 MiB |
BIN
cw 7/textures/earth2_normals.png
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
cw 7/textures/earth_normalmap.png
Normal file
After Width: | Height: | Size: 163 KiB |
BIN
cw 7/textures/grid.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
cw 7/textures/grid_color.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
cw 7/textures/moon.jpg
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
cw 7/textures/moon_normal.jpg
Normal file
After Width: | Height: | Size: 374 KiB |
BIN
cw 7/textures/rust.jpg
Normal file
After Width: | Height: | Size: 6.5 MiB |
BIN
cw 7/textures/rust_normal.jpg
Normal file
After Width: | Height: | Size: 3.3 MiB |
BIN
cw 7/textures/scratches.jpg
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
cw 7/textures/skybox/corona_bk.png
Normal file
After Width: | Height: | Size: 803 KiB |
BIN
cw 7/textures/skybox/corona_dn.png
Normal file
After Width: | Height: | Size: 852 KiB |
BIN
cw 7/textures/skybox/corona_ft.png
Normal file
After Width: | Height: | Size: 992 KiB |
BIN
cw 7/textures/skybox/corona_lf.png
Normal file
After Width: | Height: | Size: 744 KiB |
BIN
cw 7/textures/skybox/corona_rt.png
Normal file
After Width: | Height: | Size: 920 KiB |
BIN
cw 7/textures/skybox/corona_up.png
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
cw 7/textures/skybox/space_bk.png
Normal file
After Width: | Height: | Size: 299 KiB |