Rendering czasu rzeczywistego (PDF)
Transcript of Rendering czasu rzeczywistego (PDF)
![Page 2: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/2.jpg)
Wstęp
2
![Page 3: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/3.jpg)
Rendering w czasie rzeczywistym
Polega na generowaniu obrazów na tyle szybko, aby stworzyć wrażenie płynnej animacji i zagwarantować możliwość interaktywnej współpracy aplikacji z użytkownikiem 24 fps – 60 fps (120 fps dla stereo)
Ważne aspekty: Virtual reality (rzeczywistość wirtualna)
Augmented reality (rzeczywistość rozszerzona)
3
![Page 4: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/4.jpg)
Zastosowania
Gry rozrywka
„Serious games” symulacje
edukacja
terapia
4
![Page 5: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/5.jpg)
Co się zmienia?
Oczekiwania użytkowników
5
![Page 6: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/6.jpg)
Pong
1972
6 "TeleGames-Atari-Pong" by Evan-Amos - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:TeleGames-Atari-Pong.png#/media/File:TeleGames-Atari-Pong.png
![Page 7: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/7.jpg)
Donkey Kong
1981
7
"Donkey Kong Gameplay" by Source (WP:NFCC#4). Licensed under Fair use via Wikipedia - https://en.wikipedia.org/wiki/File:Donkey_Kong_Gameplay.png#/media/File:Donkey_Kong_Gameplay.png
![Page 8: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/8.jpg)
Combat Zone
1983 https://www.youtube.com/watch?v=SGDvi6ydFHE
8
![Page 9: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/9.jpg)
Doom
1993
9
![Page 10: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/10.jpg)
Unreal
1998
10
![Page 11: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/11.jpg)
Grand Theft Auto V
2013
11
"Grand Theft Auto V combat" by Source. Licensed under Fair use via Wikipedia - https://en.wikipedia.org/wiki/File:Grand_Theft_Auto_V_combat.jpg#/media/File:Grand_Theft_Auto_V_combat.jpg
![Page 12: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/12.jpg)
Wiedźmin III
2015
12
![Page 13: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/13.jpg)
Co się zmienia?
Rozdzielczość CGA (320x200),…,HD 1080 (1920x1080),…
Kolory 8, 16, 24, 32 bit/pixel, HDR (High Dynamic Range)
2D 3D
13
![Page 14: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/14.jpg)
14 "Vector Video Standards2" by Original uploader was XXV at en.wikipedia Later version(s) were uploaded by Jjalocha, Aihtdikh at en.wikipedia. - Transferred from en.wikipedia. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:Vector_Video_Standards2.svg#/media/File:Vector_Video_Standards2.svg
![Page 15: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/15.jpg)
Co się zmienia?
Moc obliczeniowa CPU
GPU
Pamięci (RAM, cache, SSD, itp.)
Przepustowość
15
![Page 16: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/16.jpg)
Biblioteki graficzne
Kilkanaście lat temu grafika czasu rzeczywistego była generowana na CPU, przy pomocy renderera napisanego „od zera” (Wolfenstein, Doom, Quake,…)
Wszystkie współczesne aplikacje tego typu wymagają kart graficznych
Biblioteki graficzne zapewniają dostęp do funkcjonalności kart graficznych różnych producentów, oferując podstawowe procedury renderingu
16
![Page 17: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/17.jpg)
Biblioteki graficzne, c.d.
Biblioteki te skupiają się tylko na jednym algorytmie renderingu – rasteryzacji
Obecnie żaden inny algorytm (np. śledzenie promieni) w czasie rzeczywistym nie jest w stanie stworzyć obrazu o lepszej jakości
17
![Page 18: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/18.jpg)
Biblioteki graficzne, c.d.
Najczęściej stosowane biblioteki to OpenGL i DirectX
Mają one bardzo podobne możliwości i wydajność
18
![Page 19: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/19.jpg)
OpenGL
Biblioteka niezależna od platformy (Windows, Unix, iOS, PS)
Opracowana przez SGI (Mark Segal i Kurt Akeley) w 1991/92
Powszechne stosowanie rozszerzeń przez producentów kart graficznych
Model programowania proceduralny
19
![Page 20: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/20.jpg)
DirectX
Biblioteka Microsoftu
Z OpenGL’em konkuruje jedynie Direct3D (część DirectX)
Opracowana początkowo w 1992 przez Servana Keondjiana (założył firmę RenderMorphics), następnie w 1995 wcielona do DirectX 2.0
Niedostępna na systemach Unix, iOS, PS
Brak mechanizmu rozszerzeń (teoretycznie)
Obiektowy model programowania 20
![Page 21: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/21.jpg)
Próba integracji
W 1997 SGI, Microsoft (i później HP) uruchomiły projekt mający na celu zintegrowanie OpenGL i Direct3D
Projekt został porzucony w 1999 Microsoft – zmiana strategii
SGI – kłopoty finansowe
21
![Page 22: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/22.jpg)
Historia renderingu na kartach graficznych
Karty graficzne nieprogramowalne
OpenGL 1.x, DirectX do wersji 7
Tylko rendering trójkątów z pojedynczą teksturą
Sprzętowa transformacja i oświetlenie wierzchołków
Programowalne przetwarzanie wierzchołków
Rozszerzenia OpenGL 1.x, DirectX 8.x
22
![Page 23: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/23.jpg)
Programowalne przetwarzanie fragmentów OpenGL 2.x, DirectX 9.x
Możliwość pisania coraz bardziej zaawansowanych programów
Nowe formaty tekstur, HDR (High Dynamic Range), rendering do tekstury
23
Historia renderingu na kartach graficznych, c.d.
![Page 24: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/24.jpg)
Programowalne przetwarzanie geometrii OpenGL 3.x, DirectX 10.x
Operacje na prymitywach
Obliczenia na GPU (ogólnego przeznaczenia)
24
Historia renderingu na kartach graficznych, c.d.
![Page 25: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/25.jpg)
Programowalna tesselacja OpenGL 4.x, DirectX 11
Nowe możliwości programów GPU
Zapis i odczyt z tekstury, operacje atomowe
25
Historia renderingu na kartach graficznych, c.d.
![Page 26: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/26.jpg)
Wersje OpenGL
https://www.opengl.org/wiki/History_of_OpenGL
26
![Page 27: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/27.jpg)
Rozszerzenia
GL_ : wszystkie platformy
GLX_ : Linux & Mac
WGL_ : Windows
EXT_ : rozszerzenie ogólne
ARB_ : zaakceptowane przez wszystkich członków OpenGL Architecture Review Board (EXT_ często stają się ARB_ w kolejnych wydaniach)
NV/AMD/INTEL/APPLE 27
![Page 28: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/28.jpg)
Vulkan
https://en.wikipedia.org/wiki/Vulkan_(API)
next generation OpenGL initiative
higher performance and lower CPU usage
prekompilowane shadery
28
![Page 29: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/29.jpg)
Vulkan, c.d. https://developer.nvidia.com/transitioning-opengl-vulkan
https://www.toptal.com/api-developers/a-brief-overview-of-vulkan-api
29
![Page 30: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/30.jpg)
Vulkan vs OpenGL
In OpenGL getting something on the screen is by far easier. Even without classic fixed function, just rendering full-screen effects or image-processing takes only few lines of code. Vulkan’s level of verbosity to get to the first pixel on the screen is far higher. As hinted in the previous blog posts on resource bindings or memory management, these additional complexities will require more code to be written. Especially for people new to graphics, it may be better to use OpenGL or rendering middleware that hides this complexity and focus on the actual task.
30
![Page 31: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/31.jpg)
Grafika 3D - przypomnienie
Modele budowane z wierzchołków Pozycja
Normalna
Współrzędne tekstury
I wiele, wiele, wiele innych
Wybrane trójki wierzchołków tworzą trójkąty, stanowiące brzeg modelu
Najnowsze karty obsługują bardziej złożone powierzchnie (sprzętowa teselacja)
31
![Page 32: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/32.jpg)
Wierzchołki są transformowane z przestrzeni obiektu, przez przestrzeń świata i widoku do przestrzeni ekranu przy pomocy macierzy
W przestrzeni ekranu wykonywana jest rasteryzacja trójkątów
Liczone jest oświetlenie i teksturowanie
32
Grafika 3D - przypomnienie, c.d.
![Page 33: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/33.jpg)
Wykonywane jest zasłanianie (z-bufor), wtapianie (blending) itp.
Wymienione powyżej elementy są bardzo podstawowe, obecnie stosuje się o wiele więcej zaawansowanych technik
33
Grafika 3D - przypomnienie, c.d.
![Page 34: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/34.jpg)
OpenGL 3.0 rendering pipeline
34
![Page 35: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/35.jpg)
OpenGL 4.3 rendering pipeline
35
![Page 36: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/36.jpg)
OpenGL 4.5 rendering pipeline
36
![Page 37: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/37.jpg)
Skrócona wersja obrazkowa
37
![Page 38: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/38.jpg)
Pojedyncze podawanie wierzchołków
glBegin(GL_TRIANGLES);
glVertexf(...); glVertexf(...); glVertexf(...); glVertexf(...); glVertexf(...); glVertexf(...); glEnd();
DEPRECATED 38
Stare style programowania OpenGL
![Page 39: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/39.jpg)
Stare style programowania OpenGL, c.d.
Bufory z wierzchołkami
DEPRECATED
39
![Page 40: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/40.jpg)
Stare style programowania OpenGL, c.d.
Display lists
glNewList(index, GL_COMPILE); glBegin(GL_TRIANGLES); glVertex3fv(v0); glVertex3fv(v1); glVertex3fv(v2); glEnd(); glEndList(); glCallList(index);
DEPRECATED
40
![Page 41: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/41.jpg)
A zatem jak?
Shaders
Vertex shader
Tesselation shaders (2x)
Geometry shadrer
Fragment shader
…
Bufory: VBO, VAO, EBO, textures,...
41
![Page 42: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/42.jpg)
Literatura
42
![Page 43: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/43.jpg)
Online
http://www.learnopengl.com
https://www.opengl.org/sdk/docs/man/html
https://www.opengl.org/registry
https://www.opengl.org/wiki/History_of_OpenGL
http://www.lighthouse3d.com/tutorials/glsl-tutorial
43
![Page 44: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/44.jpg)
44
Książki
![Page 45: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/45.jpg)
45
Książki, c.d.
![Page 46: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/46.jpg)
Zaczynamy
46
![Page 47: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/47.jpg)
Wersje OpenGL i GLSL
https://en.wikipedia.org/wiki/OpenGL_Shading_Language
47
![Page 48: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/48.jpg)
Sprawdzenie wersji
glGetString(...) GL_RENDERER
karta graficzna
GL_VERSION wersja OpenGL
GL_SHADING_LANGUAGE_VERSION wersja GLSL
GL_EXTENSIONS obsługiwane rozszerzenia
48
![Page 49: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/49.jpg)
Przykład OpenGL01
49
![Page 50: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/50.jpg)
NVIDIA was proud to introduce programmable shading with Cg, which supported dozens of different OpenGL and DirectX profile targets. It allowed developers to incorporate interactive effects within 3D applications and share them among other Cg applications, across graphics APIs, and most operating systems (Windows XP, Vista and Windows 7, Mac OS X for Leopard, Snow Leopard & Lion, Linux 32-bit & 64-bit) as well as balance effect complexities with client GPU capabilities.
Going forward, we recommend new development with GLSL, or HLSL for Windows applications, rather than Cg. (2012 Cg DEPRECATED)
„… via Cg compiler”
50
![Page 51: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/51.jpg)
Nie ma lekko…
In Modern OpenGL we are required to define at least a vertex and fragment shader of our own (there are no default vertex/fragment shaders on the GPU). For this reason it is often quite difficult to start learning Modern OpenGL since a great deal of knowledge is required before being able to render your first triangle…
51
![Page 52: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/52.jpg)
Przykład OpenGL02
52
![Page 53: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/53.jpg)
Shaders #version 450
in vec3 position;
in vec3 color;
uniform float zoom;
out vec3 fragColor;
void main()
{
gl_Position = vec4(position, 1.0)*zoom;
fragColor = color;
} 53
![Page 54: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/54.jpg)
Typy zmiennych
Skalary bool, int, float, double, uint
Wektory {b|i||d|u|}vec[2|3|4], np. vec3, uvec2
Macierze {d}mat[2|3|4|2x2|2x3|2x4|3x3|3x3|3x4|4x2|4x3|4x4] (kolumn x wierszy),
np. mat4, dmat2x3
Samplers, Images, Opaque types, Atomic counters
void
54
![Page 55: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/55.jpg)
Dostęp do składowych wektorów i macierzy
vec4 v v[0], v[1], v[2], v[3]
v.xyzw, v.x, v.xy, v.zyx, v.xxx, v.xxxx
v.rgba (kolory)
v.stpq (współrzędne tekstur)
mat4 m m[2][1]
m[3].xyz
55
![Page 56: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/56.jpg)
Typy zmiennych, c.d.
Struktury struct {
…
} nazwa;
Tablice typ nazwa[rozmiar]
Po szczegóły dotyczące tablic odsyłam do specyfikacji GLSL
56
![Page 57: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/57.jpg)
Przesyłanie danych
57
![Page 58: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/58.jpg)
Vertex Buffer Object (VBO)
Służy do przekazania danych wierzchołków Zwykle: współrzędne, normalna, kolor, współrzędne tekstur
Ale może zawierać praktycznie dowolne dane
Dane przygotowujemy na CPU, a następnie: GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
58
![Page 59: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/59.jpg)
VBO dla wielu obiektów
Lepiej (wydajniej) jest operować na pojedynczym VBO Przełączanie pomiędzy VBO zajmuje czas
Ale są wyjątki np. dla obiektów, dla których liczba wierzchołków znacząco się zmienia, lepiej
przydzielić oddzielne VBO
www.opengl.org/wiki/Vertex_Specification_Best_Practices
59
![Page 60: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/60.jpg)
Aktualizacja fragmentu lub całości VBO
glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
60
![Page 61: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/61.jpg)
Opisanie struktury VBO
Poprzez tzw. atrybuty: GLint attr = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(attr, 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), 0);
glEnableVertexAttribArray(attr);
61
![Page 62: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/62.jpg)
Vertex Array Object (VAO)
Pozwala zapamiętać VBO i jego atrybuty glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
GLint attr = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(attr, 3, GL_FLOAT, GL_FALSE, 9*sizeof(GLfloat), 0);
glEnableVertexAttribArray(attr);
glBindVertexArray(0); // ???
62
![Page 63: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/63.jpg)
VAO
63
![Page 64: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/64.jpg)
Uruchomienie rysowania VAO (=VBO+attr)
…jest już bardzo proste: glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, offset, count);
64
![Page 65: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/65.jpg)
Przykład OpenGL03
65
![Page 66: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/66.jpg)
Element Buffer Object (EBO)
66
Korzystanie wyłącznie z wierzchołków jest w większości przypadków nieefektywne
![Page 67: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/67.jpg)
Sześcian – ile trójkątów, ile wierzchołków?
67
![Page 68: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/68.jpg)
Sześcian – ile trójkątów, ile wierzchołków? c.d.
Sześcian ma 8 wierzchołków
Ściany zbudować można z 12 trójkątów
Daje to 36 wierzchołków – 4.5 x więcej!
68
![Page 69: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/69.jpg)
Sześcian – ile trójkątów, ile wierzchołków? c.d.
Jeśli jednak dodamy normalne, to jest lepiej, bo: Wierzchołków jest 3x8 = 24
Czyli licząc 36 liczymy tylko 1.5 x więcej
Ale tak jest tylko dlatego, że wszystkie wierzchołki w sześcianie są „niegładkie”
Często jest całkiem inaczej -->
69
![Page 70: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/70.jpg)
EBO
Reasumując: Często ten sam wierzchołek występuje w kilku trójkątach
Jego wielokrotne obliczanie w vertex shaderze jest zbędne!
70
![Page 71: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/71.jpg)
EBO, c.d.
71
![Page 72: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/72.jpg)
EBO, c.d.
Przekazanie EBO do OpenGL jest podobne do VBO: GLuint EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
72
![Page 73: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/73.jpg)
EBO, c.d.
EBO może być zawarte w VAO
Rysowanie wg EBO: glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
73
![Page 74: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/74.jpg)
Przykład OpenGL04
74
![Page 75: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/75.jpg)
EBO i kilka VBO
75
![Page 76: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/76.jpg)
Przykład OpenGL05
76
![Page 77: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/77.jpg)
Przepływ danych
W wersji bardzo uproszczonej:
77
![Page 78: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/78.jpg)
Zmienne wbudowane
Pełny wykaz i opis w „The OpenGL Shading Language”, rozdział „Built-in Variables” https://www.opengl.org/registry/doc/GLSLangSpec.4.40.pdf
Część zmiennych aktywna jedynie w określonych kontekstach lub po aktywacji glEnable(…) np. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE) i glDrawArrays(GL_POINTS, …)
pozwala ustawiać gl_PointSize
Należy unikać używania własnych zmiennych z nazwą zaczynającą się od „gl_”
78
![Page 79: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/79.jpg)
Interpolacja dla fragment shadera
Zmienne trafiają do fragment shadera interpolowane
Trzy metody interpolacji (dla zmiennych typu float i pochodnych): smooth – liniowa z uwzględnieniem perspektywy (domyślna metoda)
flat – brak interpolacji (brana jest wartość z ostatniego punktu)
noperspective – liniowa
definiuje się na wejściu do fragment shadera (np. in flat vec3 …)
Ograniczenie zmiennych wejściowych fragment shadera: Nie można używać bool i pochodnych
Zmienne typu int, double i pochodne muszą być oznaczone flat
79
![Page 80: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/80.jpg)
smooth vs noperspective
80
![Page 81: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/81.jpg)
Bufory framebuffera
W celu uniknięcia „migotania” i innych artefaktów: Rysowanie odbywa się do bufora GL_BACK
Po narysowaniu całej sceny, kiedy można ją pokazać, wykonywany jest transfer danych do właściwego widocznego bufora (GL_FRONT) – operacja ta jest zależna od platformy
Np. w Qt, przed wywołaniem paintGL() domyślnie ustawiany jest bufor GL_BACK, o po zakończeniu paintGL() wykonywany jest transfer (zamiana) buforów
GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT
glDrawBuffer(…) ustawia aktualnie używany do rysowania bufor (lub bufory)
81
![Page 82: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/82.jpg)
Modele
82
![Page 83: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/83.jpg)
Modele obiektów
Aby posunąć się dalej z materiałem, jeden trójkąt to za mało
Ręczne wpisywanie modeli bardziej skomplikowanych jest niewygodne
Modele tworzymy zatem w zewnętrznych programach do modelowania (z ew. pomocą skanerów 3D)
83
![Page 84: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/84.jpg)
Modele obiektów, c.d.
Aby model czegoś bardziej skomplikowanego niż trójkąt wyglądał jako tako przyzwoicie, to potrzebne jest: Wczytywanie współrzędnych położenia, współrzędnych tekstur oraz
normalnych wierzchołków
Przekształcenia geometryczne
Oświetlenie
Dopiero potem ma sens dodawanie kolejnych efektów…
84
![Page 85: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/85.jpg)
Demo prostego modelu…
85
![Page 86: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/86.jpg)
Przykład OpenGL07
86
![Page 87: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/87.jpg)
Skąd brać modele (dygresja)
Można zrobić samemu
Można wynająć kogoś z zacięciem plastycznym
Można skorzystać z gotowych modeli http://tf3dm.com
http://graphics.stanford.edu/data/3Dscanrep
87
![Page 88: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/88.jpg)
Przykład OpenGL08
88
glEnable(GL_DEPTH_TEST);
![Page 89: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/89.jpg)
Geometria
89
![Page 90: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/90.jpg)
Przekształcanie wierzchołków
Odbywa się w vertex shader
Współrzędne do vertex shadera trafiają z VBO
Na wyjściu muszą się znaleźć współrzędne wpisane w gl_Position znormalizowane do (-1, -1, -1) – (1, 1, 1)
90
![Page 91: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/91.jpg)
Przekształcanie wierzchołków, c.d.
91
![Page 92: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/92.jpg)
Przestrzenie i przekształcenia
Podział przekształceń na: Modelu (obiektu)
Widoku
Projekcji
oraz przestrzeni na: Modelu
Świata (sceny)
Widoku
jest całkowicie umowny, jednak stosowany jest w wielu pakietach, programach, systemach, artykułach, tutorialach itp., że warto się go trzymać
92
![Page 93: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/93.jpg)
Macierze 4x4
Najwygodniej zakodować przekształcenia za pomocą macierzy 4x4. Można dzięki temu wykonywać: Przesunięcia
Skalowania
Obroty
Rzuty perspektywiczne
Składać w/w przekształcenia
Odwracać w/w przekształcenia
…w sposób łatwy, prosty i przyjemny 93
![Page 94: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/94.jpg)
Przesunięcie (translacja)
94
![Page 95: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/95.jpg)
Skalowanie
95
![Page 96: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/96.jpg)
Obroty
96
![Page 97: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/97.jpg)
Perspektywa
http://www.songho.ca/opengl/gl_projectionmatrix.html 97
![Page 98: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/98.jpg)
Perspektywa, c.d.
98
![Page 99: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/99.jpg)
Rzut równoległy
99
![Page 100: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/100.jpg)
Biblioteki
Tylko najbardziej zawzięci programiści tworzą macierze ręcznie bo to żadne wyzwanie
a pomylić się łatwo
Korzystamy z gotowych bibliotek Np. w Qt jest klasa Matrix4x4, która posiada metody:
• setToIdentity, translate, scale, rotate, ortho, perspective, frustum, inverted, transposed itd.
100
![Page 101: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/101.jpg)
Przekazanie macierzy do vertex shadera
QMatrix4x4 pvm_matrix = p_matrix*v_matrix*m_matrix;
int attr = glGetUniformLocation(shaderProgram, "pvm_matrix");
glUniformMatrix4fv(attr, 1, GL_FALSE, pvm_matrix.data());
Uniformy nie są związane z VBO, więc i do VAO nie da się ich włączyć
101
![Page 102: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/102.jpg)
Przykład OpenGL09/10/11
102
![Page 103: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/103.jpg)
Przód i tył trójkąta
która strona trójkąta to przód? glFrontFace(…); GL_CCW (wartość domyślna)
GL_CW
glEnable(GL_CULL_FACE);
którą stronę trójkątów odrzucać? glCullFace(…); GL_FRONT
GL_BACK 103
![Page 104: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/104.jpg)
Przód i tył trójkąta, c.d.
bool gl_FrontFacing dostępne w fragment shader
Badany jest znak wyrażenia:
104
![Page 105: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/105.jpg)
Przekształcenie normalnych
Wektorów normalnych nie można przekształcać tak samo, jak współrzędnych wierzchołków:
105
![Page 106: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/106.jpg)
Przekształcenie normalnych, c.d.
Macierz do przekształcania normalnych ma postać:
Wyprowadzenie: http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix
106
![Page 107: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/107.jpg)
Przykład OpenGL12/13
107
![Page 108: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/108.jpg)
Przekształcanie normalnych, c.d.
Vertex shader powinien dysponować dwoma macierzami:
in vec3 position;
in vec3 normal;
uniform mat4 pvm_matrix;
uniform mat3 norm_matrix;
out vec3 fragNormal;
void main()
{
gl_Position = pvm_matrix*vec4(position, 1.0);
fragNormal = normalize(norm_matrix*normal);
}
108
![Page 109: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/109.jpg)
Przekształcanie normalnych, c.d.
Użycie normalnych w fragment shaderze: in vec3 fragNormal;
out vec4 color;
void main()
{
// przykładowe mapowanie normalnej na kolor:
color = vec4(abs(normalize(fragNormal)), 1.0);
}
109
![Page 110: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/110.jpg)
Normalizacja normalnych
Czy jest potrzebna we fragment shaderze?
110
![Page 111: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/111.jpg)
Normalizacja normalnych, c.d.
Czy jest potrzebna w vertex shaderze?
111
![Page 112: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/112.jpg)
Normalizacja normalnych
Reasumując: Brak normalizacji w vertex shaderze może wprowadzać
błąd w kierunku normalnej
Brak interpolacji w fragment shaderze może wprowadzić błąd w długości normalnej
112
![Page 113: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/113.jpg)
Przykład OpenGL14
113
![Page 114: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/114.jpg)
Modele oświetlenia
114
![Page 115: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/115.jpg)
Cel
Modele oświetlenia starają się oddać, jak najbardziej wiernie, zjawiska optyczne związane z postrzeganiem koloru obiektów
Oświetlenie znane z rzeczywistości jest zjawiskiem zbyt złożonym, aby udało się go odwzorować dokładnie, szczególnie w renderingu czasu rzeczywistego Konieczne są zatem uproszczenia
115
![Page 116: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/116.jpg)
Oświetlenie lokalne i globalne
Lokalne: Brane jest pod uwagę jedynie źródło światła i oświetlany obiekt
Obliczane jest tylko jedno odbicie światła (od rozpatrywanego obiektu)
Globalne: Uwzględniane są optyczne interakcje pomiędzy obiektami
• rzucanie cienia
• wielokrotne odbicia
116
![Page 117: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/117.jpg)
117
Oświetlenie lokalne i globalne, c.d.
![Page 118: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/118.jpg)
Oświetlenie lokalne i globalne, c.d.
W grafice czasu rzeczywistego stosuje się oświetlenie lokalne
Dodatkowe efekty uzyskuje się poprzez zastosowanie pewnych elementów oświetlenia globalnego: Cienie
Mapowanie środowiskowe (odbicia, załamanie)
SSAO
itp.
118
![Page 119: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/119.jpg)
Oko
Siatkówka oka
119
„Retina-diagram” autorstwa Fig_retine.png: Cajalderivative work Fig retine bended.png: Anka Friedrich (talk)derivative work: vectorisation by chris 論 - Fig_retine.pngFig retine bended.png. Licencja CC BY-SA 3.0 na podstawie Wikimedia Commons - https://commons.wikimedia.org/wiki/File:Retina-diagram.svg#/media/File:Retina-diagram.svg
![Page 120: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/120.jpg)
Oko, c.d.
Widzenie kolorów zawdzięczamy czopkom, w percepcji barw uczestniczą barwniki: erythrolabe – reagujący z największą czułością na promieniowanie o λ = 590
nm (symbol D od długofalowe), wywołujące wrażenie czerwieni
chlorolabe – najbardziej czuły na promieniowanie o λ = 540 nm (wrażenie zieleni, symbol Śr)
cyanolabe – najbardziej czuły na promieniowanie o λ = 450 nm (wrażenie barwy niebieskiej, symbol K od krótkofalowe)
120
![Page 121: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/121.jpg)
Oko, c.d.
121 "Cone-response PL". Licencja: CC BY-SA 3.0 na podstawie Wikimedia Commons - https://commons.wikimedia.org/wiki/File:Cone-response_PL.svg#/media/File:Cone-response_PL.svg
![Page 122: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/122.jpg)
Model koloru
Dlatego model RGB jest bardzo popularny
Dostarczając do oka odpowiednią mieszankę kolorów czerwonego, zielonego i niebieskiego możemy zasymulować dowolny kolor
Niestety model ten nie jest odpowiedni przy rozpatrywaniu niektórych zjawisk optycznych (np. załamanie światła)
122
![Page 123: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/123.jpg)
Modele źródeł światła
W grafice off-line można pozwolić sobie na lepsze przybliżenia źródeł światła
W grafice czasu rzeczywistego stosuje się kilka uproszczonych rodzajów źródeł światła Źródła punktowe
Źródła kierunkowe
Oświetlenie rozproszone (otoczenia)
123
![Page 124: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/124.jpg)
Źródła punktowe
Zdefiniowane przez: Położenie (punkt w przestrzeni)
Kolor i natężenie emitowanego światła
Pewnym wariantem są źródła typu „spot light”, które dodatkowo charakteryzują się: Kierunkiem świecenia
Kątem oświetlania (ogólniej: funkcją jasności w zależności od kąta)
124
![Page 125: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/125.jpg)
Zmiana jasności w zależności od odległości
Zgodnie z fizyką:
gdzie I – jasność, r – odległość od źródła światła, c – stała
Ze względu na pomijanie wielu zjawisk (głównie odbić) zastosowanie powyższego wzoru powoduje zbyt szybki zanik światła; stosuje się zatem wzór:
125
![Page 126: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/126.jpg)
Źródła kierunkowe
Zdefiniowane przez: Kierunek padania
Kolor i natężenie światła
Jasność nie zmienia się
126
![Page 127: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/127.jpg)
Źródła powierzchniowe
Kształt ma dużo mniejsze znaczenie niż powierzchnia
Najczęściej realizowane jako suma wielu źródeł punktowych
(obrazek obok został wygenerowany off-line)
127
![Page 128: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/128.jpg)
Oświetlenie rozproszone
Zdefiniowane przez: Kolor (ale rzadko)
Natężenie
Pomaga uniknąć wysokich kontrastów i wrażenia ponurości…
Pomaga również na etapie modelowania obiektów i sceny
128
![Page 129: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/129.jpg)
Oświetlenie Phonga
Połączenie światła odbitego (specular) i rozpraszanego (diffuse) od obiektu oraz światła rozproszonego (ambient)
129
![Page 130: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/130.jpg)
Oświetlenie Phonga, c.d.
130
"Phong components version 4" by No machine-readable author provided. Rainwarrior~commonswiki assumed (based on copyright claims). - No machine-readable source provided. Own work assumed (based on copyright claims).. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:Phong_components_version_4.png#/media/File:Phong_components_version_4.png
![Page 131: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/131.jpg)
Oświetlenie Phonga, c.d.
Oznaczenia: N – wektor normalny
L – wektor w kierunku źródła światła
R – wektor odbicia źródła światła
V – wektor w kierunku kamery
Wszystkie wektory są znormalizowane
131
![Page 132: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/132.jpg)
Oświetlenie Phonga, c.d.
132
![Page 133: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/133.jpg)
Inne modele
Model oświetlenia Phonga jest bardzo wygodny, ale nie zawsze doskonale się nadaje – najlepiej sprawdza się dla powierzchni „plastikowych”, dla innych materiałów czasem trudniej dobrać parametry
Model Orena-Nayara Inny model światła rozproszonego (zależny od położenia kamery)
Model BRDF (Bidirectional reflectance distribution function) Inny, bardziej dokładny model światła odbitego
np. Cook’a – Torrance’a http://www.codinglabs.net/article_physically_based_rendering_cook_torrance.aspx
133
![Page 134: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/134.jpg)
Odbicie anizotropowe
134
![Page 135: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/135.jpg)
Odbicie anizotropowe, c.d.
Model Ashikhmina – Shirleya http://www.cs.utah.edu/~shirley/papers/jgtbrdf.pdf
Wykorzystuje model Cook’a – Torrance’a z rozkładem:
135
![Page 136: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/136.jpg)
Obliczenia
Obliczenia można rozłożyć pomiędzy vertex shaderem i fragment shaderem Na ogół więcej jest fragmentów niż wierzchołków
Jeżeli wszystkie obliczenia wykonamy dla wierzchołków (w vertex shaderze) i uzyskany wynik interpolujemy dla fragmentów, to uzyskamy cieniowanie Gourauda
Jeżeli jedynie wektory są jest interpolowane, a reszta obliczeń przeprowadzana jest dla fragmentów, to jest to cieniowanie Phonga
136
![Page 137: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/137.jpg)
Gouraud vs Phong
137
![Page 138: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/138.jpg)
Przykład OpenGL15
138
![Page 139: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/139.jpg)
Materiał
Informacja o kolorze (obiektu lub jego fragmentu) nie jest informacją wystarczającą do realistycznego renedringu
W zależności od przyjętego modelu oświetlenia potrzebne są jeszcze inne atrybuty, np. dla Phonga.: Współczynniki ka, ks, dd, n (shininess)
139
![Page 140: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/140.jpg)
Przykład OpenGL16
140
![Page 141: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/141.jpg)
Uniform Data Block
Pozwala załadować dane typu uniform z bufora OpenGL
Pozwala na dzielenie danych pomiędzy programami
Deklaracja w shaderze: layout (std140) uniform Nazwa
{
// pola
};
141
![Page 142: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/142.jpg)
Uniform Data Block, c.d.
Załadowanie do OpenGL: glGenBuffers(1, &MAT);
glBindBuffer(GL_UNIFORM_BUFFER, MAT);
glBufferData(GL_UNIFORM_BUFFER, data_size, data, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, MAT);
GLuint blockIndex = glGetUniformBlockIndex(shaderProgram, "Nazwa");
glUniformBlockBinding(shaderProgram, blockIndex, 0);
142
![Page 143: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/143.jpg)
layout
Zgodnie z https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt opcje layoutu, dotyczące upakowania, to: shared (domyślne) pozwala kompilatorowi zoptymalizować położenie pól, ale nie
pozwala ich usuwać, jeśli nie są używane; gwarantuje, że pakowanie będzie takie samo dla takich samych definicji bloku
packed podobnie jak share, jednak pola nieużywane mogą zostać usunięte
std140 położenie pól zgodne ze zdefiniowanymi regułami
143
![Page 144: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/144.jpg)
layout std140
Dla: layout (std140) uniform Material
{
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
}
144
![Page 145: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/145.jpg)
(1) If the member is a scalar consuming <N> basic machine units, the base alignment is <N>.
(2) If the member is a two- or four-component vector with components consuming <N> basic machine units, the base alignment is 2<N> or 4<N>, respectively.
(3) If the member is a three-component vector with components consuming <N> basic machine units, the base alignment is 4<N>.
(4) If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The array may have padding at the end; the base offset of the member following the array is rounded up to the next multiple of the base alignment.
(5) If the member is a column-major matrix with <C> columns and <R> rows, the matrix is stored identically to an array of <C> column vectors with <R> components each, according to rule (4).
(6) If the member is an array of <S> column-major matrices with <C> columns and <R> rows, the matrix is stored identically to a row of <S>*<C> column vectors with <R> components each, according to rule (4).
(7) If the member is a row-major matrix with <C> columns and <R> rows, the matrix is stored identically to an array of <R> row vectors with <C> components each, according to rule (4).
(8) If the member is an array of <S> row-major matrices with <C> columns and <R> rows, the matrix is stored identically to a row of <S>*<R> row vectors with <C> components each, according to rule (4).
(9) If the member is a structure, the base alignment of the structure is <N>, where <N> is the largest base alignment value of any of its members, and rounded up to the base alignment of a vec4. The individual members of this sub-structure are then assigned offsets by applying this set of rules recursively, where the base offset of the first member of the sub-structure is equal to the aligned offset of the structure. The structure may have padding at the end; the base offset of the member following the sub-structure is rounded up to the next multiple of the base alignment of the structure.
(10) If the member is an array of <S> structures, the <S> elements of the array are laid out in order, according to rule (9).
145
![Page 146: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/146.jpg)
Przykład OpenGL17
146
![Page 147: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/147.jpg)
Tekstury
147
![Page 148: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/148.jpg)
Tekstura (mapa)
Tekstury generalnie służą do tego, aby zastąpić we fragment shaderze: Interpolowane wartości
poprzez: Wartości z tekstury dla interpolowanych współrzędnych
Istnieje wiele rodzajów tekstur: GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP, …
148
![Page 149: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/149.jpg)
Tekstura jako kolor
149
![Page 150: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/150.jpg)
Współrzędne tekstury
Współrzędne tekstur, podobnie jak np. wektory normalne są generowane przez programy do tworzenia modeli
Ręczne generowanie jest raczej niewygodne…
Oznaczane są jako u i v lub s i t
150
![Page 151: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/151.jpg)
Współrzędne tekstury, c.d.
W OpenGL punkt (0, 0) tekstury to lewy dolny róg
W większości programów do modelowania punkt (0, 0) to lewy górny róg…
Trzeba zatem na jakimś etapie dokonać odbicia współrzędnej Y: Można na etapie wczytywania modelu/tekstur (najlepsze rozwiązanie)
Można odbić tekstury (słabe rozwiązanie)
Można w vertex shaderze (może być)
Można we fragment shaderze (nieefektywne rozwiązanie) 151
![Page 152: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/152.jpg)
Zakres współrzędnych tekstury
Współrzędne tekstur są z zakresu <0, 1>, jeśli wyjdziemy poza, to zachowanie może być różne (domyślnie GL_REPEAT):
152
![Page 153: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/153.jpg)
Mipmapping
Jeżeli „rozdzielczość” fragmentów jest mniejsza niż tekstury, to aby ustalić wartość tekstury należałoby uśrednić pewien obszar tekstury
153
![Page 154: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/154.jpg)
Mipmapping, c.d.
Aby uniknąć uśredniania w czasie renderingu, wcześniej należy przygotować odpowiedni zestaw tekstur
Generowane są pomniejszone tekstury (za każdym razem dwukrotnie), tzw. poziomy (level)
Mipmapping może być wykorzystywany tylko kiedy zachodzi konieczność pomniejszenia tekstury, przy powiększaniu wykorzystywana jest zawsze tekstura poziomu 0
154
![Page 155: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/155.jpg)
Mipmapping, c.d.
155
"MipMap Example STS101" by en:User:Mulad, based on a NASA image - Created by en:User:Mulad based on File:ISS from Atlantis - Sts101-714-016.jpg. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:MipMap_Example_STS101.jpg#/media/File:MipMap_Example_STS101.jpg
![Page 156: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/156.jpg)
Mipmapping, c.d.
W zależności od ustawienia parametru GL_TEXTURE_MIN_FILTER: GL_NEAREST, GL_LINEAR
• mipmapping nie jest używany, stosowana jest tekstura poziomu 0
GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST • Wybierana jest jedna najlepsza mipmapa
GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR • Wybierane są dwie mipmapy i następuje interpolacja między nimi
156
![Page 157: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/157.jpg)
Ładowanie tekstury
Qt ma klasę QImage do wczytywania i przetwarzania obrazków:
QImage tex(nazwa_pliku);
Następnie można wysłać teksturę do karty:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
tex.width(), tex.height(),
0, GL_BRGA, GL_UNSIGNED_BYTE, tex.bits());
157
![Page 158: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/158.jpg)
Ładowanie tekstury, c.d.
Można zlecić wykonanie mipmap:
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
Końcowe podłączenie do shadera:
int attr_tex = glGetUniformLocation(shaderProgram, "textureBitmap");
glUniform1i(attr_tex, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
158
![Page 159: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/159.jpg)
Użycie tekstury we fragment shaderze
in vec2 fragTexCoor;
uniform sampler2D textureBitmap;
…
vec4 color = texture(textureBitmap, fragTexCoor);
159
![Page 160: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/160.jpg)
Przykład OpenGL18
160
![Page 161: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/161.jpg)
Inne zastosowania tekstur
Użycie tekstury do pokolorowania powierzchni było ich pierwszym zastosowaniem
161
![Page 162: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/162.jpg)
Inne zastosowania tekstur, c.d.
Obecnie, kiedy mamy pełną kontrolę nad danymi z tekstury (przez program w shaderze) możemy wykorzystywać je w praktycznie dowolny sposób
W szczególności: Do mapowania parametrów cieniowania (np. specular, shininess)
Do mapowania normalnych
Do mapowania paralaksy
Do generowania cieni
162
![Page 163: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/163.jpg)
Przykład OpenGL19
163
![Page 164: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/164.jpg)
Mapowanie normalnych
Pozwala uzyskać efekt nierówności powierzchni
Wymaga niestety pewnych manipulacji geometrycznych
164
![Page 165: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/165.jpg)
Mapa normalnych
165
W składowych RGB kodujemy wektory normalne do powierzchni
![Page 166: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/166.jpg)
Przestrzeń stycznych
Wektor normalny pobrany z mapy musi zostać odpowiednio przetransformowany do współrzędnych powierzchni do której się odnosi
166
![Page 167: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/167.jpg)
Przestrzeń stycznych, c.d.
Wektory T (tangent) i B (bitangent) można wyliczyć ze współrzędnych tekstury dla wierzchołków
167
![Page 168: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/168.jpg)
Przestrzeń stycznych, c.d.
168
![Page 169: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/169.jpg)
Macierz TBN
Rozszerzając macierz o wektor normalny uzyskujemy tzw. macierz TBN:
Która transformuje pomiędzy przestrzenią mapy normalnych a przestrzenią modelu i posiada użyteczną własność:
169
![Page 170: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/170.jpg)
VBO
Obliczone wektory T i B dodajemy do VBO
Czyli obliczeń T i B możemy dokonać po wczytaniu modelu (jeśli model już ich nie zawiera)
170
![Page 171: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/171.jpg)
Obliczenia w shaderach, wersja 1
Vertex shader: in vec3 normal;
in vec3 tgnU;
in vec3 tgnV;
out mat3 fragTBN;
…
vec3 T = normalize(norm_matrix * tgnU);
vec3 B = normalize(norm_matrix * tgnV);
vec3 N = normalize(norm_matrix * normal);
fragTBN = mat3(T, B, N);
171
![Page 172: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/172.jpg)
Obliczenia w shaderach, wersja 1, c.d.
Fragment shader: in mat3 fragTBN;
…
vec3 texNormal = texture(textureNormal, fragTexCoor).rgb * 2.0 - 1.0;
texNormal = normalize(fragTBN*texNormal);
172
![Page 173: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/173.jpg)
Przykład OpenGL20
173
![Page 174: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/174.jpg)
Obliczenia w shaderach, wersja 2
Vertex shader: uniform Light light;
uniform vec3 eyePos;
out vec3 fragTanEyePos;
out vec3 fragTanLightPos;
out vec3 fragTanFragPos;
out vec3 fragTanNormal;
…
fragTanLightPos = TBN * light.pos;
fragTanEyePos = TBN * eyePos;
fragTanFragPos = TBN * fragPos;
fragTanNormal = TBN * N;
174
![Page 175: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/175.jpg)
Obliczenia w shaderach, wersja 2, c.d.
Fragment shader: in vec3 fragTanEyePos;
in vec3 fragTanLightPos;
in vec3 fragTanFragPos;
in vec3 fragTanNormal;
…
vec3 texNormal = normalize(texture(textureNormal, fragTexCoor).rgb * 2.0 - 1.0);
…
vec3 lightDir = normalize(fragTanLightPos - fragTanFragPos);
175
![Page 176: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/176.jpg)
Porównanie
Wersja 1: Prostsza koncepcyjnie
Wersja 2: Wydajniejsza (mnożenie macierzy dla wierzchołków, nie dla fragmentów)
176
![Page 177: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/177.jpg)
Przykład OpenGL21
177
![Page 178: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/178.jpg)
Mapowanie paralaksy
Chcemy, aby teksturowana powierzchnia wyglądała jakby miała elementy przestrzenne à la płaskorzeźba
178
![Page 179: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/179.jpg)
Mapowanie paralaksy, c.d.
Ale użycie takiej tekstury nie daje w pełni zadowalających efektów…
179
![Page 180: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/180.jpg)
Mapowanie paralaksy, c.d.
Aby uzyskać dobry wynik, należałoby obliczyć poprawny punkt przecięcia na powierzchni (pkt B zamiast A):
![Page 181: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/181.jpg)
Mapa wysokości
Aby uzyskać taki efekt potrzebna jest tekstura z wysokością/głębokością
181
![Page 182: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/182.jpg)
Przesunięcie tekstury, wersja 1
W wersji najbardziej prymitywnej przesuwamy współrzędne tekstury o wysokość tekstury odczytaną z mapy wysokości
182
![Page 183: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/183.jpg)
Przesunięcie tekstury, wersja 1, c.d.
Fragment shader: uniform sampler2D textureDepth;
vec2 ParallaxMapping(vec2 texCoor, vec3 viewDir)
{
const float height_scale = 2.0/128.0; float height = texture(textureDepth, texCoor).r * height_scale;
vec2 p = viewDir.xy / viewDir.z * height;
return texCoor - p;
} 183
![Page 184: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/184.jpg)
Przykład OpenGL22
184
![Page 185: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/185.jpg)
Przesunięcie tekstury, wersja 2
Wersja 1 sprawdza się tylko dla kątów patrzenia niezbyt odchylonych od normalnej (do mniej więcej 45 stopni)
Ale przesunięcia tekstury można szukać iteracyjnie (steep parallax mapping)
185
![Page 186: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/186.jpg)
Przesunięcie tekstury, wersja 3
Jeśli jeszcze uśrednimy wynik z dwóch końcowych poziomów, to unikniemy efektu schodków i efekt będzie znacznie lepszy…
186
![Page 187: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/187.jpg)
Przykład OpenGL23
187
![Page 188: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/188.jpg)
Uwagi praktyczne dot. mapowania paralaksy
Mapowanie paralaksy może być czasochłonnym procesem Dobór parametrów (np. liczba warstw)
Nie zawsze daje oczekiwany (łatwo zauważalny) wzrost realizmu Zależy od odległości od tekstury, wielkości szczegółów, różnic w głębokości
itp.
188
![Page 189: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/189.jpg)
Skybox
Służy do renderowania statycznego tła
Wykorzystuje teksturę typu GL_TEXTURE_CUBE_MAP 6 tekstur jednakowej wielkości
(X+, X-, Y+, Y-, Z+, Z-)
Wartość pobierana dla dowolnego wektora 3D
189
![Page 190: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/190.jpg)
Skybox, c.d.
190
SkyboxSet by Heiko Irrgang ( http://gamvas.com ) is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License. Based on a work at http://93i.de.
![Page 191: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/191.jpg)
Skybox, c.d.
Obiektem, na którym renderowane jest tło jest kwadrat wielkości ekranu, którego współrzędna Z gwarantuje, że faktycznie będzie w tle
Obliczenia Vertex shader oblicza jedynie współrzędne tekstury tła (na podstawie odwrotnej
macierzy złożenia widoku i perspektywy) • Macierz ta może być policzona wcześniej przez CPU
Fragment shader pobiera kolor fragmentu z tekstury • Może dokonać modyfikacji, np. przyciemnienia, rozjaśnienia itp.
Skybox renderujemy na końcu
191
![Page 192: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/192.jpg)
Przykład OpenGL24
192
![Page 193: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/193.jpg)
Dwa ciekawe efekty
Dysponując skyboxem możemy uzyskać w prosty sposób dwa efekty: Obiekty lustrzane (odbicie światła)
Obiekty przejrzyste (załamanie światła)
Wykorzystujemy tu fakt, że skybox zawiera widok świata, który jest niezmienny dla wszystkich punktów sceny
193
![Page 194: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/194.jpg)
Odbicie lustrzane skyboxa
We fragment shaderze: vec3 I = normalize(fragPos.xyz - eyePos);
vec3 R = reflect(I, normalize(fragNormal));
…
vec3 mirror = texture(textureSkybox, R).rgb;
color = vec4(material.ambient + diffuse + specular + mirror, 1.0);
194
![Page 195: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/195.jpg)
Przykład OpenGL25
195
![Page 196: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/196.jpg)
Odbicie lustrzane skyboxa, c.d.
Jeżeli nie cały obiekt ma być lustrzany, można np. zastosować dodatkową teksturę obiektu definiującą, które fragmenty powierzchni są odbijające
196
![Page 197: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/197.jpg)
Załamanie światła
We fragment shaderze: float ratio = 1.0 / 1.52;
vec3 I = normalize(fragPos.xyz - eyePos);
vec3 R = refract(I, normalize(fragNormal), ratio);
…
vec3 refracted = texture(textureSkybox, R).rgb;
color = vec4(material.ambient + diffuse + specular + refracted, 1.0);
197
![Page 198: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/198.jpg)
Przykład OpenGL26
198
![Page 199: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/199.jpg)
Dwie tekstury na płaski obiekt
Zastosowanie dwóch tekstur dla płaskich obiektów pozwala uzyskać efekt prześwitywania
199
![Page 200: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/200.jpg)
Przykład OpenGL27
200
![Page 201: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/201.jpg)
Cienie, cz. I
201
Cienie od kierunkowych źródeł światła
![Page 202: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/202.jpg)
Mapowanie cieni
Podstawowym sposobem generowania cieni w OpenGL jest tzw. shadow mapping
Algorytm działa dwuprzebiegowo: W pierwszym przebiegu generowana jest mapa głębokości obiektów
widziana z perspektywy źródła światła
W drugim przebiegu generowany jest właściwy obraz
Jeżeli źródeł światła jest więcej, to pierwszy przebieg wykonywany jest dla każdego źródła światła, generując oddzielną mapę
202
![Page 203: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/203.jpg)
Mapowanie cieni, c.d.
W obu przebiegach renderowana jest ta sama scena
Pierwszy przebieg jest znacznie szybszy: Nie wykonujemy cieniowania
Nie wykonujemy przesunięć normalnych, paralaksy itp.
Interesuje nas wyłącznie obliczenie współrzędnej Z każdego fragmentu
Pierwszy przebieg można jeszcze przyspieszyć: Stosując mniej szczegółowe modele obiektów
Pomijając obiekty, które nie rzucają cienia (np. ściany)
Pomijając obiekty, o których wiemy, że nie zostaną objęte mapą cienia 203
![Page 204: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/204.jpg)
Framebuffer
Domyślnie rendering wykonywany jest do framebuffera, który jest następnie mapowany (w kooperacji z systemem okienkowym) na ekran
Można jednak utworzyć własny framebuffer
Framebuffer składa się z kilku buforów: Głębokości (jeden)
Kolorów (kilka, w domyślnym: GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT, GL_BACK_RIGHT, we własnych 0…N)
Szablonu (jeden) 204
![Page 205: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/205.jpg)
Nowy framebuffer
Aby utworzyć framebuffer należy stworzyć odpowiednie tekstury, utworzyć obiekt framebuffera (FBO) i podczepić do niego utworzone tekstury w roli odpowiednich buforów
205
![Page 206: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/206.jpg)
Tekstury dla framebuffera (W x H)
Tekstura bufora koloru: glGenTextures(1, &tex_FBO_color);
glBindTexture(GL_TEXTURE_2D, tex_FBO_color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
Tekstura bufora głębokości: glGenTextures(1, &tex_FBO_depth);
glBindTexture(GL_TEXTURE_2D, tex_FBO_depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
W, H, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
206
![Page 207: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/207.jpg)
Framebuffer
Utworzenie samego framebuffera jest już proste: glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_FBO_color, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex_FBO_depth, 0);
207
![Page 208: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/208.jpg)
Rendering do framebuffera
Aby rendering odbywał się do nowego framebuffera: glViewport(0, 0, W, H);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
A jak przywrócić stan pierwotny? Kiedyś było prościej:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Ale teraz: GLint FBO_screen;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &FBO_screen);
…
glBindFramebuffer(GL_FRAMEBUFFER, FBO_screen);
I jeszcze trzeba pamiętać o przywróceniu rozdzielczości: glViewport(0, 0, width(), height());
208
![Page 209: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/209.jpg)
Przykład OpenGL28
209
![Page 210: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/210.jpg)
Mapa cienia dla światła kierunkowego
Rendering z perspektywą równoległą zgodną z kierunkiem światła
Do ustalenia: Rozdzielczość framebuffera
Rozmiar framebuffera
Głębokości graniczne dla bufora głębokości (near plane, far plane)
210
![Page 211: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/211.jpg)
Generacja mapy cienia
W tym przebiegu interesuje nas tylko bufor głębokości, zatem w utworzonym FBO nie będzie żadnego bufora kolorów
Aby dodatkowo zasygnalizować, że kolor ma nie być renderowany: glDrawBuffer(GL_NONE);
211
![Page 212: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/212.jpg)
Macierz dla mapy cienia
W Qt (przykładowe dane): light_matrix.setToIdentity();
light_matrix.ortho(-5.0, 5.0, // x
-5.0, 5.0, // y
0.0, 20.0); // z
light_matrix.lookAt(
QVector3D(light.dir[0], light.dir[1], light.dir[2]).normalized()*5.0, // eye
QVector3D(0, 0, 0), // center
QVector3D(1, 1, 1)); // up 212
![Page 213: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/213.jpg)
Shadery dla mapy cienia
Vertex shader (nie najbardziej optymalny): in vec3 position;
uniform mat4 light_matrix;
uniform mat4 m_matrix;
void main()
{
gl_Position = light_matrix*m_matrix*vec4(position, 1.0);
}
Fragment shader: void main() { }
213
![Page 214: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/214.jpg)
Rendering z wykorzystaniem mapy cienia
Vertex shader wykonuje to samo obliczenie, co w przebiegu generacji mapy cienia (oprócz innych obliczeń)
Fragment shader sprawdza, czy dany fragment jest w cieniu, czy nie i odpowiednio modyfikuje kolor
214
![Page 215: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/215.jpg)
Testowanie cienia bool inShadow(vec3 lightdir, vec3 normal)
{
vec3 p = (fragPosLight.xyz / fragPosLight.w)*0.5 + 0.5; if (p.x < 0.0 || p.x > 1.0 || p.y < 0.0 || p.y > 1.0 || p.z > 1.0) return false;
float d = texture(textureShadow, p.xy).x;
float bias = max(0.01 * (1.0 - dot(normal, lightdir)), 0.001);
return p.z - bias > d;
}
215
![Page 216: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/216.jpg)
Efekt moiré
216
![Page 217: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/217.jpg)
bias
Aby uniknąć efektu moiré (samocieniowania) należy zastosować odpowiednie przesunięcie współrzędnej Z
Nie za małe, bo efekt nie zostanie usunięty
Nie za duże, bo powstanie nowy niepożądany efekt, tzw. efekt Piotrusia Pana (peter panning)
Może być adaptacyjne, jak w przykładzie na poprzednim slajdzie
Istnieją też inne, bardziej precyzyjne algorytmy 217
![Page 218: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/218.jpg)
Przykład OpenGL29
218
![Page 219: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/219.jpg)
PCF (Percentage-Closer Filtering)
Cienie ostre: Rzadko wyglądają dobrze
Ze względu na ograniczoną rozdzielczość mapy cienia widoczne są poszarpane krawędzie cieni
Cienie miękkie: Wyglądają lepiej
Rozmazują krawędzie cieni ukrywając poszarpanie
219
![Page 220: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/220.jpg)
PCF, c.d.
Metoda PCF polega na próbkowaniu kilku/kilkunastu/kilkudziesięciu próbek mapy cienia zamiast jednej
float shadow = 0.0;
vec2 texel = 1.0/textureSize(textureShadow, 0);
for (float i = -1.5; i <= 1.51; i += 1.0)
for (float j = -1.5; j <= 1.51; j += 1.0)
{
float d = texture(textureShadow, p.xy + vec2(i, j)*texel).x;
shadow += (p.z - bias > d) ? 1.0 : 0.0;
}
return 1.0 - shadow/16.0; 220
![Page 221: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/221.jpg)
PCF z ditheringiem
Zamiast próbkować 16 razy można 4 wykorzystując technikę ditheringu http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
221
![Page 222: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/222.jpg)
Przykład OpenGL30
222
![Page 223: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/223.jpg)
Mapa cienia dla światła punktowego
Sprawa się komplikuje i, aby zrobić to efektywnie, będziemy potrzebowali…
223
![Page 224: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/224.jpg)
Geometry shader
224
![Page 225: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/225.jpg)
Nie tylko trójkąty
Do tej pory we wszystkich przykładach obiekty były rysowane jako zbiór trójkątów glDrawArrays…(GL_TRIANGLES, …);
albo
glDrawElements…(GL_TRIANGLES, …);
Są jednak także inne możliwości
225
![Page 226: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/226.jpg)
Nie tylko trójkąty, c.d.
226
![Page 227: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/227.jpg)
GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
227
![Page 228: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/228.jpg)
Nie tylko trójkąty, c.d.
228
![Page 229: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/229.jpg)
Zastosowanie geometry shadera
Geometry shader dostaje na wejściu wierzchołki pojedynczego prymitywu, a następnie na ich podstawie może wygenerować dowolną liczbę dowolnych prymitywów (ale zawsze tych samych) i ich wierzchołki
229
![Page 230: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/230.jpg)
OpenGL 4.5 rendering pipeline (przypomnienie)
230
![Page 231: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/231.jpg)
Wejście do geometry shadera
Musimy określić, jakie prymitywy trafiają do geometry shadera z vertex shadera (tesselation shadera): layout (points) in;
• Dla: GL_POINTS
layout (lines) in; • Dla: GL_LINES i GL_LINE_STRIP
layout (triangles) in; • Dla: GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN
layout (lines_adjacency) in; • Dla: GL_LINES_ADJACENCY i GL_LINE_STRIP_ADJACENCY
layout (triangles_adjacency) in; • Dla: GL_TRIANGLES_ADJACENCY i GL_TRIANGLE_STRIP_ADJACENCY
231
![Page 232: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/232.jpg)
Wejście do geometry shadera, c.d.
Za każdym razem geometry shader dostanie na wejściu tablicę wierzchołków: points: gl_in[1]
lines: gl_in[2]
triangles: gl_in[3]
lines_adjacency: gl_in[4]
triangles_adjacency: gl_in[6]
232
![Page 233: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/233.jpg)
Zmienne wbudowane
W geometry shaderze mamy do dyspozycji tablicę gl_in[], której elementy zawierają pola: vec4 gl_Position;
float gl_PointSize;
float gl_ClipDistance[];
float gl_CullDistance[];
Mamy też do dyspozycji licznik prymitywów: int gl_PrimitiveIDIn;
233
![Page 234: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/234.jpg)
Wejście do geometry shadera, c.d.
Również każda wyjściowa dana z vertex shadera staje się automatycznie tablicą w geometry shaderze: Vertex shader:
out vec3 abc;
Geometry shader: in vec3 abc[];
Rozmiar tablicy określa rodzaj prymitywu (czyli 1, 2, 3, 4 lub 6)
234
![Page 235: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/235.jpg)
Wyjście z geometry shadera
Musimy określić jakie prymitywy będzie generował geometry shader: layout (points, max_vertices = …) out;
layout (line_strip, max_vertices = …) out;
layout (triangle_strip, max_vertices = …) out;
W każdym przypadku musimy podać maksymalną liczbę wierzchołków jakie wygenerujemy
235
![Page 236: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/236.jpg)
Przykład OpenGL31
236
![Page 237: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/237.jpg)
Przykład OpenGL32
237
![Page 238: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/238.jpg)
Cienie, cz. II
238
Cienie od punktowych źródeł światła
![Page 239: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/239.jpg)
Cienie punktowych źródeł światła
Po pierwsze należy rozważyć, czy cienie światła punktowego nie mogą być mapowane tak, jak w przypadku światła kierunkowego
Może się tak stać, jeśli: Źródło światła jest „poza” sceną
Źródło światła oświetla mniej niż połowę sfery (np. światło typu spotlight)
Inne przypadki
239
![Page 240: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/240.jpg)
Cienie punktowych źródeł światła, c.d.
Wówczas można jedynie zastosować tylko inne przekształcenie (perspektywiczne zamiast równoległego)
240
![Page 241: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/241.jpg)
Mapa cienia typu CUBE
241
W pozostałych przypadkach, aby objąć całą przestrzeń otaczającą źródło światła, można zastosować teksturę typu CUBE
![Page 242: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/242.jpg)
Mapa cienia typu CUBE, c.d.
Problem polega na tym, że nie można do framebufora podczepić textury typu CUBE jako bufora głębokości i liczyć, że to od razu zadziała…
Każdą ze ścian skyboxa należy potraktować oddzielnie i co za tym idzie dokonać mapowania cieni sześciokrotnie
Można to zrobić na 2 sposoby: W paintGL() najpierw 6 razy generujemy mapy cieni odpowiednio
zmieniając framebufory
Wykorzystać do tego geometry shader 242
![Page 243: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/243.jpg)
Co należy przygotować na CPU?
6 macierzy widoku sceny z punktu źródła światła w kierunku wszystkich sześciu ścian
Teksturę typu CUBE
Framebufor
243
![Page 244: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/244.jpg)
gl_Layer
Specjalna zmienna gl_Layer służy do wyboru ściany tekstury CUBE, która zostanie wykorzystana
244
gl_Layer tekstura
0 GL_TEXTURE_CUBEMAP_POSITIVE_X
1 GL_TEXTURE_CUBEMAP_NEGATIVE_X
2 GL_TEXTURE_CUBEMAP_POSITIVE_Y
3 GL_TEXTURE_CUBEMAP_NEGATIVE_Y
4 GL_TEXTURE_CUBEMAP_POSITIVE_Z
5 GL_TEXTURE_CUBEMAP_NEGATIVE_Z
![Page 245: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/245.jpg)
Działanie geometry shadera
Geometry shader „rozmnaża” każdy trójkąt: for (int face = 0; face < 6; face++) {
gl_Layer = face;
for (int i = 0; i < 3; i++) {
fragPos = gl_in[i].gl_Position;
gl_Position = light_matrix[face] * fragPos;
EmitVertex();
}
EndPrimitive();
}
245
![Page 246: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/246.jpg)
Przykład OpenGL33
246
![Page 247: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/247.jpg)
PCF dla cieni od punktowych źródeł światła
Próbkowanie z tekstury typu CUBE odbywa się na bazie wektora 3D, a nie 2D
Może to powodować nadmierną liczbę próbkowań
Rozwiązaniem jest wykorzystanie tablicy z predefiniowanymi punktami w 3D
247
![Page 248: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/248.jpg)
Przykład OpenGL34
248
![Page 249: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/249.jpg)
HDR
249
High Dynamic Range
![Page 250: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/250.jpg)
Historia
HDR (High Dynamic Range) ma swój rodowód w fotografii 1850, Gustave Le Gray
250
"Gustave Le Gray - Brig upon the Water - Google Art Project" by Gustave Le Gray - dwEJBbTOxE61pQ at Google Cultural Institute, zoom level maximum. Licensed under Public Domain via Commons - https://commons.wikimedia.org/wiki/File:Gustave_Le_Gray_-_Brig_upon_the_Water_-_Google_Art_Project.jpg#/media/File:Gustave_Le_Gray_-_Brig_upon_the_Water_-_Google_Art_Project.jpg
![Page 251: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/251.jpg)
251
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
-4
![Page 252: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/252.jpg)
252
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
-2
![Page 253: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/253.jpg)
253
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
+2
![Page 254: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/254.jpg)
254
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
+4
![Page 255: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/255.jpg)
255
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
Simple contrast reduction
![Page 256: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/256.jpg)
256
"StLouisArchMultExpEV-4.72" by Kevin McCoy - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:StLouisArchMultExpEV-4.72.JPG#/media/File:StLouisArchMultExpEV-4.72.JPG
Local tone mapping
![Page 257: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/257.jpg)
I jeszcze jeden przykład
257
by Dean S. Pemberton, 6 exposures illustrating the Steps to take an HDR Image
![Page 258: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/258.jpg)
258
![Page 259: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/259.jpg)
LDR
Standardowo bufory kolorów przechodują dane w formacie LDR
Każdy komponent jest z zakresu [0.0…1.0], z dokładnością 1/256
Problemy: Sumowanie oświetlenia z kilku źródeł może doprowadzić, do przekroczenia
wartości 1.0 (nastąpi wówczas przycięcie do tej wartości)
Brak możliwości elastycznego różnicowania jasności źródeł światła
Itp. 259
![Page 260: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/260.jpg)
LDR, dodawanie kolorów
260
![Page 261: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/261.jpg)
HDR
Rendering wykonujemy do bufora, który ma więcej niż 8 bitów na kolor i nie przycina wartości do zakresu [0.0…1.0] GL_RGB16F, GL_RGBA16F
GL_RGB32F, GL_RGBA32F
Następnie renderujemy ten bufor na prostokąt ekranu (podobnie jak w przypadku skyboxa) zmieniając wartości HDR na LDR
261
![Page 262: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/262.jpg)
HDR output? http://images.nvidia.com/content/pdf/quadro/data-
sheets/NV_DS_Quadro_M6000_FEB15_NV_US_FNL_HR.pdf
262
![Page 263: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/263.jpg)
HDR output? c.d. http://www.firstshowing.net/2015/dolby-impresses-cinemacon-with-
10000001-hdr-projection-demo
263
![Page 264: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/264.jpg)
Typy zmiennoprzecinkowe w OpenGL
264
https://www.opengl.org/wiki/Small_Float_Formats
https://en.wikipedia.org/wiki/IEEE_754-1985
![Page 265: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/265.jpg)
Tone mapping
Istnieje wiele metod na mapowanie HDR LDR, które przy okazji pozwalają uzyskać dodatkowe efekty
Mapowanie Reinharda Bardzo proste
Zachowuje większy kontrast dla ciemnych kolorów
265
![Page 266: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/266.jpg)
Tone mapping, c.d.
Ekspozycja
266
![Page 267: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/267.jpg)
Tone mapping, c.d.
W http://filmicgames.com/archives/75 można znaleźć kilka ciekawych wzorów
Np. Jim Hejl i Richard Burgess-Dawson:
267
![Page 268: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/268.jpg)
Adaptacyjny tone mapping
Próbkowanie pobliskich 25 punktów, określenie ich jasności („luminancji”)
Na ich podstawie określenie lokalnej jasności i dopasowanie ekspozycji
268
![Page 269: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/269.jpg)
Skala szarości
Niektórzy uważają, że jak coś jest czarno-białe, to robi się bardziej „artystyczne”
Wzór dla nich wygląda tak:
A jak ma być cieplej, to:
269
![Page 270: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/270.jpg)
Tekstury HDR
Format RADIANCE (*.hdr) 1985 by Greg Ward, format RGBE
32 bit/pixel
Kod C do dekodowania: http://www.graphics.cornell.edu/~bjw/rgbe.html
Format OpenEXR (*.exr) 2003 by Industrial Light and Magic
16 lub 32 bit/kolor
Lib do dekodowania: http://www.openexr.com
Format KTX (*.ktx) Khronos
https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec 270
![Page 271: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/271.jpg)
Korekcja gamma
271
Oko ludzkie nie odbiera jasności kolorów w sposób liniowy
Stosuje się tzw. korekcję gamma, która powoduje, że skala kolorów jest bardziej naturalna (pokazać obrazek gamma-test.png!)
Wartości parametru gamma wahają się w okolicy 2 CRT: 2.2
LCD: ~ 1.8
Projektory: ???
![Page 272: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/272.jpg)
Korekcja gamma, c.d.
Niestety, fakt że kolory są przesunięte zgodnie ze krzywą gamma powoduje, że dodawanie kolorów nie jest do końca poprawne nawet w HDR
Można to oczywiście zignorować, albo pracować na kolorach „zlinearyzowanych”, a następnie nałożyć korektę gamma
W OpenGL możemy wykorzystać specjalny format tekstury GL_SRGB (GL_SRGB_ALPHA), oczywiście tylko do tekstur z informacją o kolorach (tekstury z normalnymi, mapami głębokości itp. nie podlegają korekcji gamma!)
272
![Page 273: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/273.jpg)
Porównanie
273
![Page 274: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/274.jpg)
Osłabianie światła (attenuation)
Stosowanie korekcji gamma pozwala na użycie liniowej zależności pomiędzy odległością od punktowego źródła światła, a jego intensywnością
Normalnie zależność ta jest kwadratowa, ale skoro stosujemy gammę w okolicach 2.0, to jest to akceptowalne…
274
![Page 275: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/275.jpg)
Przykład OpenGL35
275
![Page 276: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/276.jpg)
Rozmycie gaussowskie
Służy do miękkiego rozmycia obrazu
Wzór: określa wartość współczynnika w odległości (x, y) od środka
276
![Page 277: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/277.jpg)
Rozmycie gaussowskie, c.d.
Tabela współczynników może wyglądać np. tak:
Jest symetryczna, współczynniki na końcu są pomijalnie małe
277
![Page 278: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/278.jpg)
Rozmycie gaussowskie, c.d.
Gdyby bezpośrednio zastosować tabelkę z poprzedniego slajdu, to dla każdego pixela trzeba by wykonać 49 (7x7) sumowań
Na szczęście rozmycie gaussowskie ma tę ciekawą własność, że można je obliczyć jako złożenie rozmycia jednowymiarowego w kierunku X i kierunku Y
Każde z rozmyć jednowymiarowych to 7 składników, zatem ostatecznie będzie tylko 14 (7+7)
278
![Page 279: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/279.jpg)
Rozmycie gaussowskie, c.d.
279
W celu uzyskania większego rozmycia można: Zwiększyć promień rozmycia
Rozmyć powtórnie już rozmyty obraz
(Rysunek poglądowy…)
![Page 280: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/280.jpg)
Współczynniki
Współczynniki można albo obliczyć bezpośrednio z rozkładu Gaussa, albo wykorzystać trójkąt Pascala
280
![Page 281: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/281.jpg)
Współczynniki, c.d.
281
![Page 282: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/282.jpg)
Fragment shader dla rozmycia gaussowskiego uniform float horizontal;
…
float w[5] = {0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216};
vec2 texel = 1.0/textureSize(textureIn, 0);
texel.x *= horizontal;
texel.y *= (1.0 - horizontal);
color = texture(textureIn, fragTexCoor)*w[0];
for (int i = 1; i < w.length; i++)
color += texture(textureIn, fragTexCoor + vec2(texel.x*i, texel.y*i))*w[i] + texture(textureIn, fragTexCoor - vec2(texel.x*i, texel.y*i))*w[i];
282
![Page 283: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/283.jpg)
Efekt poświaty
Aby uwidocznić w scenie obiekty o większej jasności stosuje się tzw. poświatę (glow, bloom), bo w większości przypadków nie ma fizycznej możliwości, aby zaświecić piksele mocniej niż (255, 255, 255)…
283
![Page 284: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/284.jpg)
Efekt poświaty
Do uzyskania efektu poświaty należy: Wykryć fragmenty o jasności większej niż zadany próg (co jest możliwe
dzięki HDR)
Wykryte fragmenty zapisać do oddzielnej tekstury
Rozmyć teksturę z jasnymi fragmentami
Połączyć (dodać) obraz oryginalny i rozmyte jasne fragmenty
284
![Page 285: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/285.jpg)
Efekt poświaty, c.d.
285
![Page 286: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/286.jpg)
Przykład OpenGL36
286
![Page 287: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/287.jpg)
Przetwarzanie w OpenGL36
287
![Page 288: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/288.jpg)
Opóźnione cieniowanie
288
Deferred shading
![Page 289: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/289.jpg)
Cel opóźnienia cieniowania
Proces cieniowania staje się coraz bardziej czasochłonny
Dla każdego fragmentu należy obliczyć: Światło odbite (diffuse)
Światło rozproszone (specular)
Cienie, na bazie map cieni
PCF cieni
Mapowanie normalnych
Mapowanie paralaksy
Mapowanie środowiskowe
itp. 289
![Page 290: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/290.jpg)
Cel opóźnienia cieniowania, c.d.
Te wszystkie obliczenia wykonuje się także dla fragmentów, które potem są zasłaniane przez inne fragmenty, a więc de facto te obliczenia są całkiem zbędne
Problem pogłębia się wraz ze złożonością sceny oraz komplikacją shaderów obliczających cieniowanie 290
![Page 291: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/291.jpg)
Wizualizacja 60 000 sfer
291
![Page 292: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/292.jpg)
Rozwiązanie
Stąd pomysł, aby cieniowanie wykonać dopiero wtedy, kiedy będzie dokładnie wiadomo, które fragmenty są widoczne
Wykonywany jest zatem najpierw szybki przebieg renderingu, który: Zapamiętuje wszystkie potrzebne do cieniowania dane (np. pozycje, normalne,
kolory tekstur)
Stara się jak najmniej obliczać…
A następnie wykonywany jest przebieg cieniujący, który korzysta z przygotowanych danych, i który oblicza cieniowanie tylko dla widocznych fragmentów
292
![Page 293: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/293.jpg)
G-buffer
Framebuffer, do którego w pierwszym przebiegu wykonywany jest rendering nosi nazwę „g-buffer”
„g” od geometry, gdyż zawiera także dane związane z geometrią fragmentów, takie jak położenie i normalne
G-buffer z przykładu, który zaraz nastąpi, zawiera dla każdego fragmentu: Pozycję
Informację, że fragment istnieje w danym miejscu ekranu
Wektor normalny
Kolor
Natężenie światła rozproszonego (ambient) 293
![Page 294: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/294.jpg)
Tekstury g-bufora Pozycje i istnienie:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width(), height(), 0, GL_RGBA, GL_FLOAT, NULL);
Normale:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width(), height(), 0, GL_RGB, GL_FLOAT, NULL);
Kolor i ambient (tu: LDR):
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width(), height(), 0, GL_RGBA, GL_FLOAT, NULL);
Bufor głębokości:
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width(), height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 294
![Page 295: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/295.jpg)
Fragment shader do generacji g-bufora in vec3 fragNormal;
in vec3 fragPos;
in vec2 fragTexCoor;
uniform sampler2D textureBitmap;
uniform float ambient;
layout (location = 0) out vec4 gPosition;
layout (location = 1) out vec3 gNormal;
layout (location = 2) out vec4 gColor;
void main() {
gPosition = vec4(fragPos, 0.0); // pozycja + istnienie
gNormal = normalize(fragNormal); // normalna
gColor = vec4(texture(textureBitmap, fragTexCoor).rgb, ambient); // kolor + ambient
}
295
![Page 296: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/296.jpg)
Przykład OpenGL37
296
![Page 297: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/297.jpg)
Przetwarzanie w OpenGL37
297
![Page 298: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/298.jpg)
Zawartość g-bufora w OpenGL37
298
![Page 299: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/299.jpg)
Cienie + PCF + HDR + Gauss + mapowanie normalnych + Opóźnione cieniowanie + SkyBox +… ?
Nie tylko, że się da - tak działa większość silników 3D!
299
![Page 300: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/300.jpg)
Przykład OpenGL38
300
![Page 301: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/301.jpg)
Przetwarzanie w OpenGL38
301
![Page 302: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/302.jpg)
Wady opóźnionego cieniowania
Dwie podstawowe wady opóźnionego cieniowania: Wszystkie obiekty muszą być przetwarzane w taki sam sposób
Nie można bezpośrednio korzystać z kanału alfa
Istnieją obejścia w/w problemów Warunkowe/wieloprzebiegowe cieniowanie
Łączenie opóźnionego cieniowania z normalnym (trzeba tylko zachować i wykorzystać bufor głębokości z etapu tworzenia g-bufora)
Pojawiają się za to nowe możliwości…
302
![Page 303: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/303.jpg)
SSAO
303
Screen-Space Ambient Occlusion
![Page 304: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/304.jpg)
SSAO wymyślone przez Crytek dla gry Crysis
304
"Screen space ambient occlusion" by Vlad3D at en.wikipedia - Transferred from en.wikipedia. Licensed under Public Domain via Commons - https://commons.wikimedia.org/wiki/File:Screen_space_ambient_occlusion.jpg#/media/File:Screen_space_ambient_occlusion.jpg
Vladimir Kajalin, 2007
![Page 305: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/305.jpg)
AO (Ambient Occlusion)
Generowanie zacienienia miejsc z mniejszym dostępem światła w dobrze oświetlonym otoczeniu
Sprawdzenie: Ile przestrzeni w otoczeniu każdego
punktu jest wolne od obiektów?
305
![Page 306: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/306.jpg)
AO, c.d.
Wykonanie takiego testu w przestrzeni sceny byłoby dość skomplikowane:
Obiekty są definiowane jako powierzchnie, a nie objętości
Trudno określić, dla których miejsc i jak gęsto dokonywać sprawdzania
306
![Page 307: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/307.jpg)
SSAO
Stąd powstał prawdopodobnie pomysł, aby detekcji zacienienia dokonywać w przestrzeni ekranu, czyli już po etapie wygenerowania g-bufora
Po dołączeniu do g-bufora tekstury z głębokością zawiera on przybliżone dane 3D sceny
Detekcja odbywa się dla każdego fragmentu: współrzędne x i y to współrzędne fragmentu we framebuferze, z jest pobierane z g-bufora
307
![Page 308: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/308.jpg)
Bufor głębokości w g-buforze
Po przekształceniu perspektywicznym głębokość (współrzędna Z) nie jest liniowa
To bardzo utrudniałoby próbkowanie w shaderze SSAO
Dlatego zamiast wykorzystać automatycznie tworzony bufor głębokości, należy utworzyć dodatkowy, w którym zapisywane wartości będą liniowe
308
![Page 309: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/309.jpg)
Mapowanie głębokości
Do przejścia z (near, far) na (0, 1): Zamiast:
OpenGL stosuje:
309
![Page 310: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/310.jpg)
SSAO, c.d.
310
![Page 311: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/311.jpg)
Próbkowanie otoczenia
Nie da się przejrzeć całej kuli otaczającej punkt, ale można wygenerować kilkadziesiąt punktów próbkujących
311
![Page 312: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/312.jpg)
Kształt otoczenia
Próbkowanie otoczenia w kuli jest najprostszym rozwiązaniem, jednak ma tę wadę, że nawet całkiem płaska ściana jest wykrywana jako w 50% zacieniona…
Aby tego uniknąć stosuje się półkule, zorientowane zgodnie z normalną do badanej powierzchni
312
![Page 313: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/313.jpg)
Wynik SSAO
313
![Page 314: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/314.jpg)
Usprawnienia SSAO
Punkty próbkowania powinny być wylosowane niejednorodnie – więcej punktów powinno znaleźć się bliżej środka kuli/półkuli
Punkty powinny być dodatkowo randomizowane dla poszczególnych fragmentów
Tekstura uzyskana po SSAO powinna zostać rozmyta
314
![Page 315: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/315.jpg)
Schemat działania
315
Zamiast:
![Page 316: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/316.jpg)
Kontrola zasięgu
Dodatkowe sprawdzenie, które pozwala uniknąć zacieniania pomiędzy fragmentami znacząco się różniącymi głębokością
316
![Page 317: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/317.jpg)
Cechy SSAO
Szybkość działania SSAO nie zależy od: Złożoności sceny
Liczby świateł
Szybkość działania zależy od: Rozdzielczości ekranu (czyli liczby fragmentów)
Liczby próbek na fragment
317
![Page 318: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/318.jpg)
Konfiguracja SSAO
SSAO posiada kilka parametrów konfiguracyjnych, których dobór jest kluczowy dla uzyskania dobrego efektu: Promień półkuli
Liczba próbek w półkuli
Rozkład próbek w półkuli
Stopień rozmycia
318
![Page 319: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/319.jpg)
Przykład OpenGL39
319
![Page 320: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/320.jpg)
Rendering instancyjny
320
Instancing
![Page 321: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/321.jpg)
Rendering wielu jednakowych/podobnych obiektów Jeżeli każdy obiekt będzie
zlecany do renderingu oddzielnie przez CPU, to czas będzie tracony na: Przesył danych do GPU i wywołanie
funkcji OpenGL
Przygotowanie danych dla shaderów w GPU
321
![Page 322: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/322.jpg)
Rendering instancyjny
Problem dostrzeżono już dawno i od OpenGL 3.1 jest możliwość zlecenia renderingu wielu kopii tego samego obiektu (a właściwie zawartości VBO)
322
![Page 323: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/323.jpg)
Rendering instancyjny, c.d.
Wywołanie renderingu instacyjnego: glDrawArraysInstanced(mode, first, count, instances_count);
glDrawElementsInstanced(mode, count, type, void *indices, instances_count);
Zamiast pojedynczego: glDrawArrays(mode, first, count);
glDrawElements(mode, count, type, void *indices);
Dodatkowy argument instances_count mówi, ile razy rendering ma być wykonany
323
![Page 324: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/324.jpg)
Rozróżnianie instancji
Jeżeli w shaderach nie rozróżnimy instancji, to wizualnie nic nie uzyskamy…
Najprostszym sposobem jest wykorzystanie zmiennej gl_InstanceID dostępnej w vertex shaderze
gl_InstanceID Przyjmuje wartości 0..instances_count-1
Jeżeli nie wykorzystujemy renderingu instancyjnego, to zmienna ta ma zawsze wartość 0
324
![Page 325: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/325.jpg)
Przykład OpenGL40
325
![Page 326: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/326.jpg)
Rozróżnianie instancji, c.d.
Użycie gl_InstanceID czasami jest jednak niewygodne
Bardziej uniwersalna metoda polega na: Przygotowaniu VBO z danymi dla poszczególnych instancji
Podłączeniu tych danych jako wejściowych dla vertex shadera
326
![Page 327: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/327.jpg)
VBO z parametrami instancji
Przygotowanie i przesłanie do GPU identyczne, jak dla VBO z parametrami wierzchołków, np.:
struct InstanceData { GLfloat x, y, z, r, g, b; };
InstanceData positions_and_colors[1000];
…
GLuint VBO_positions;
glGenBuffers(1, &VBO_positions);
glBindBuffer(GL_ARRAY_BUFFER, VBO_positions);
glBufferData(GL_ARRAY_BUFFER, sizeof(InstanceData)*1000, positions_and_colors, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); 327
![Page 328: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/328.jpg)
VBO z parametrami instancji, c.d.
Podczepienie VBO pod VAO: glBindVertexArray(VAO);
…
attr = glGetAttribLocation(shaderProgram, "instancePosition");
glBindBuffer(GL_ARRAY_BUFFER, VBO_positions);
glVertexAttribPointer(attr, 3, GL_FLOAT, GL_FALSE, sizeof(InstanceData), 0);
glVertexAttribDivisor(attr, 1);
glEnableVertexAttribArray(attr);
328
![Page 329: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/329.jpg)
VBO z danymi wierzchołków i VBO z danymi instancji
W pseudokodzie, poszczególne inwokacje vertex shadera będą otrzymywać następujące dane:
for (int i = 0; i < inst_count; i++)
for (int k = 0; k < vert_count; k++)
vertex_shader(uniformy, VBO_vertex[k], VBO_instance[i]);
329
![Page 330: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/330.jpg)
Przykład OpenGL41
330
![Page 331: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/331.jpg)
Tesselation shaders
331
![Page 332: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/332.jpg)
Tesselacja
Wygenerowanie prymitywów (potencjalnie ich dużej ilości) na podstawie punktów kontrolnych (potencjalnie małej ilości)
LOD (Level of Detail), czyli uzależnienie szczegółowości modelu od jego wielkości na ekranie
332
![Page 333: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/333.jpg)
Trzy etapy tesselacji
333
Dostępne od OpenGL 4.0
Opcjonalna tesselacja następuje po vertex shaderze
![Page 334: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/334.jpg)
Tesselation control shader (TCS)
Vertex shader generuje zestawy wierzchołków
Zestaw nosi nazwę patch, a wierzchołki, które się na niego składają to tzw. punkty kontrolne (control points, CP)
Każdy patch ma zawsze tę samą liczbę punktów kontrolnych, maksymalnie 32, choć dana implementacja OpenGL może podnieść ten limit, sprawdzić to można poprzez: glGetIntegerv(GL_MAX_PATCH_VERTICES, …);
Liczbę punktów kontrolnych ustawia się poleceniem glPatchParameteri(GL_PATCH_VERTICES, …);
334
![Page 335: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/335.jpg)
Tesselation control shader, c.d.
TCS jest wywoływany dla każdego wyjściowego punktu kontrolnego
TCS musi określić stopień (czyli gęstość) tesselacji wypełniając tablice gl_TessLevelOuter[] i gl_TessLevelInner[] Maksymalna wartość określa GL_MAX_TESS_GEN_LEVEL, obecnie na ogół jest to 64
TCS może zmienić punkty kontrolne, dodać im nowe atrybuty itp.
TCS może też wygenerować parametr dla całego patcha, poprzedzając deklarację słowem kluczowym patch, np.: patch out vec3 jakisparametr;
335
![Page 336: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/336.jpg)
Tesselation control shader, c.d.
Dane wejściowe punktów kontrolnych dostępne są w tablicy gl_in[]
Dane wyjściowe zapisuje się w tablicy gl_out[]
Numer aktualnie przetwarzanego wyjściowego punktu kontrolnego określa zmienna wbudowana gl_InvocationID
Każdy dodatkowy atrybut punktu kontrolnego na wejściu i na wyjściu jest tablicą
Liczba punktów na wyjściu z TCS określa deklaracja, np.: layout (vertices = 3) out;
336
![Page 337: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/337.jpg)
Tesselation engine
Kiedy patch zostanie obrobiony przez TCS (co oznacza, że tablice kontrolne tesselacji też zostały wypełnione) do pracy przystępuje tesselation engine, który generuje współrzędne punktów tesselacji
Dla każdego wygenerowanego punktu tesselacji uruchamiany jest tesselation evaluation shader (TES), który ma dostęp do wszystkiego, co ustawił TCS oraz dodatkowo do współrzędnych wygenerowanego wierzchołka poprzez zmienną wbudowaną gl_TessCoord 337
![Page 338: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/338.jpg)
Tesselation evaluation shader (TES)
Zadaniem TES jest wygenerowanie wierzchołków dla docelowych prymitywów (trójkątów, linii lub punktów)
TES określa sposób (tryb) przeprowadzenia tesselacji: layout (triangles) in;
layout (quads) in;
layout (isolines) in;
Dostęp do punktów kontrolnych uzyskiwany jest przez tablicę gl_in[], dostęp do ich atrybutów poprzez zdefiniowane tablice, dostęp do wygenerowanego punku tesselacji poprzez gl_TessCoord
338
![Page 339: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/339.jpg)
Tryby tesselacji
Dostępne są trzy tryby tesselacji: Trójkąty
Kwadraty
Izolinie
339
![Page 340: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/340.jpg)
Tryb tesselacji: trójkąt
Występuje, gdy kompilator znajdzie w TES deklarację: layout (triangles) in;
W trójkącie generowane są punkty wg schematu
340
![Page 341: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/341.jpg)
gl_TessLevelOuter
Podział każdej krawędzi jest definiowany osobno, aby możliwe było dokładne dopasowanie sąsiadujących patchy
341
![Page 342: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/342.jpg)
Tryb tesselacji: trójkąt, c.d.
Współrzędne są w tzw. systemie barycentrycznym https://pl.wikipedia.org/wiki/Współrzędne_barycentryczne_(matematyka)
Układ punktów zależny jest tylko od gl_TessLevel*[], nie zależy w szczególności od punktów kontrolnych
342
![Page 343: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/343.jpg)
Przykład OpenGL42
343
![Page 344: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/344.jpg)
Tryb tesselacji: kwadrat
Występuje, gdy kompilator znajdzie w TES deklarację: layout (quads) in;
W kwadracie generowane są punkty wg schematu
344
![Page 345: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/345.jpg)
Tryb tesselacji: kwadrat, c.d.
Współrzędne są w układzie kartezjańskim
Układ punktów zależny jest tylko od gl_TessLevel*[], nie zależy w szczególności od punktów kontrolnych
345
![Page 346: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/346.jpg)
Przykład OpenGL43
346
![Page 347: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/347.jpg)
Tryb tesselacji: izolinie
Występuje, gdy kompilator znajdzie w TES deklarację: layout (isolines) in;
W kwadracie generowane są punkty wg schematu
347
![Page 348: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/348.jpg)
Dodatkowe modyfikatory
W deklaracji TES: layout (mode, …) in możliwe jest podanie dodatkowych modyfikatorów:
Dotyczących rozkładu: equal_spacing, fractional_even_spacing, fractional_odd_spacing
Generującego punkty: point_mode
Dotyczących „skrętności” trójkątów wynikowych: cw, ccw 348
![Page 349: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/349.jpg)
Krzywe Bézier
Pierre Étienne Bézier 1960(?) (Sergei Natanovich Bernstein 1912, algorytm Paula de Casteljau 1959)
https://en.wikipedia.org/wiki/Bézier_curve
349
![Page 350: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/350.jpg)
Płaty Bézier
350
"Bicubic Patches" by Philip Rideout - Own work. Licensed under CC BY-SA 3.0 via Commons - https://commons.wikimedia.org/wiki/File:Bicubic_Patches.png#/media/File:Bicubic_Patches.png
Ed Catmull – model słonia Gumbo
Składa się z płatów Bézier
Każdy płat kontrolowany jest przez 16 punktów (w tym przykładzie)
![Page 351: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/351.jpg)
Przykład OpenGL44
351
![Page 352: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/352.jpg)
Mapowanie terenu
Generowanie terenu na podstawie mapy wysokości
Użycie instancingu do wygenerowania bazowej siatki
Użycie tesselacji do wygenerowania gęstej siatki Zmienny LOD – Level of Detail
352
Bjørn Sandvik, http://blog.thematicmapping.org/2013/10/terrain-building-with-threejs-part-1.html
![Page 353: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/353.jpg)
Przykład OpenGL45
353
![Page 354: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/354.jpg)
Mgła
354
![Page 355: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/355.jpg)
Mgła
Efekt mgły pozwala na bardziej realistyczne odwzorowanie otwartych przestrzeni dodając im dodatkowej głębi
355 http://www.iquilezles.org/www/articles/fog/fog.htm
![Page 356: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/356.jpg)
Mgła, c.d.
Mgła pozwala także na uniknięcie problemu skończoności modelu terenu – przy odpowiednio dodanych parametrach mgły „końca świata” nie będzie widać
Efekt mgły można oczywiście także stosować we wnętrzach
356
![Page 357: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/357.jpg)
Mgła w funkcji odległości
W OpenGL 1.0 można było uzyskać efekt mgły wykorzystując jeden z trzech predefiniowanych modeli Liniowy:
Wykładniczy:
Wykładniczy, wersja 2:
357
![Page 358: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/358.jpg)
Mgła w funkcji odległości, c.d.
Gdzie: f – współczynnik „mglistości”
z – odległość fragmentu od kamery
d – gęstość mgły
start, end – zasięg mgły w modelu liniowym
Obecnie w shaderach można zaprogramować dowolną funkcję mgły – należy dobrać taką, która najlepiej odpowiada wymaganiom
358
![Page 359: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/359.jpg)
Mgła w shaderach
Należy ustalić kolor mgły, a następnie na ten właśnie kolor ustawić kolor tła
Vertex shader (lub tesselation evaluation shader): float z = length(gl_Position - eyePos);
fogFactor = clamp(exp(-fogDensity*fogDensity * z*z), 0.0, 1.0);
Fragment shader: color = mix(vec4(fogColor, 1.0), color, fogFactor);
359
![Page 360: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/360.jpg)
Mgła w funkcji wysokości
Efekt zalegania mgły „w dolinach”
Natężenie mgły zależne od wysokości terenu h:
Jest to wzór przybliżony, ale daje dobre rezultaty wizualne…
360
![Page 361: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/361.jpg)
Mgła w funkcji wysokości, c.d.
Można też policzyć dokładniej:
361
![Page 362: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/362.jpg)
Przykład OpenGL46
362
![Page 363: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/363.jpg)
Głębia ostrości
363
Depth of Field
![Page 364: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/364.jpg)
Głębia ostrości
Jest to kolejny efekt mający na celu podniesienie realizmu renderowanej sceny
Wynika z braku możliwości takiego ustawienia układu optycznego (kamery, aparatu fotograficznego, źrenicy oka), aby obiekty o różnym oddaleniu od obiektywu były ostre na elemencie światłoczułym (kliszy, detektorze, siatkówce)
364
![Page 365: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/365.jpg)
Krążek rozmycia (Circle of Confusion)
365
CoC zależy od średnicy soczewki (proporcjonalnie)
CoC jest ograniczone dla obiektów „w nieskończoności”
CoC nie jest ograniczone dla obiektów bliskich soczewce Obiekty bliskie są bardziej rozmyte niż odległe
![Page 366: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/366.jpg)
Krążek rozmycia, c.d.
Wzór określający CoC:
f – ogniskowa
d – średnica apertury
https://en.wikipedia.org/wiki/Circle_of_confusion
366
![Page 367: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/367.jpg)
Krążek rozmycia w praktyce
367
![Page 368: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/368.jpg)
Głębia ostrości – czy zawsze warto stosować?
Jeżeli chcemy, aby nasza scena przypominała zdjęcie lub film, to można to rozważyć
Jeżeli scena ma przypominać świat rzeczywisty, jakim widzimy go dookoła (zakładając dobry wzrok lub poprawne szkła korygujące), to już niekoniecznie… Bo nasze oczy automatycznie dostosowują się do różnej odległości poprzez
akomodację, tak aby to na co patrzymy, było maksymalnie ostre
Jeśli jakiś fragment obrazu rozmyjemy, to żadne wytężanie wzroku już nie pomoże…
368
![Page 369: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/369.jpg)
Porównajmy…
369 http://www.trusim.com/
![Page 370: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/370.jpg)
Metody
Istnieje kilka metod na uzyskanie efektu głębi ostrości, różnią się uzyskaną dokładnością oraz złożonością Wykorzystanie akumulacji
Ray tracing dla obszaru soczewki
Wykorzystanie bufora głębokości
Metody oparte o bufor głębokości są najszybsze, tym bardziej, że bufor głębokości i tak często jest generowany jako element g-bufora
370
![Page 371: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/371.jpg)
Metody oparte o bufor głębokości
Sposób 1 – bardziej poprawny Należy przeprowadzić rozmycie zależne od różnicy odległości fragmentu i
odległości o prawidłowej ostrości
Tu ponownie jest kilka metod do wyboru
Sposób 2 – mniej poprawny Wykonujemy rozmytą kopię całej sceny
W trakcie końcowego renderingu mieszamy obraz rozmyty i ostry w stosunku zależnym od różnicy między odległością fragmentu i odległości o prawidłowej ostrości
371
![Page 372: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/372.jpg)
Przykład OpenGL47
372
![Page 373: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/373.jpg)
Obiekty przejrzyste
373
![Page 374: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/374.jpg)
Kanał alfa
Model kolorów w OpenGL to RGBA
Kanał alfa dodany w 1971-72 (Edwin „Ed” Catmull & Alvy Ray Smith)
Nazwa od greckiej litery α w równaniu interpolacji liniowej:
374
![Page 375: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/375.jpg)
Kanał alfa, c.d.
Zgodnie z konwencją A określa stopień nieprzejrzystości (1.0 - całkowite zasłanianie, 0.0 całkowita transparentność)
Domyślnie A jest ignorowane – jeśli chcemy korzystać z przejrzystości należy włączyć jej obsługę i określić tryb mieszania kolorów (blending)
Albo wykorzystać wartość A we fragment shaderze do odrzucania fragmentu
375
![Page 376: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/376.jpg)
Test alfa
Ta druga możliwość nosi nazwę testu alfa (alpha test) i polega na tym, że we fragment shaderze, po ustaleniu koloru fragmentu wykonujemy operację: if (color.a < jakiś_próg)
discard;
Ponieważ odrzucanie jest zerojedynkowe, aby wynikowy obraz nie był postrzępiony, konieczne jest użycie antyaliasingu
376
![Page 377: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/377.jpg)
Testowe drzewo
377
model
tekstura
![Page 378: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/378.jpg)
Przykład OpenGL48
378
![Page 379: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/379.jpg)
Włączenie mieszania (blending)
Mieszanie pozwala określić jaka wartość RGBA ma zostać umieszczona w framebuforze, po obliczeniu nowych wartości przez fragment shader
Aby włączyć funkcję mieszania należy wywołać funkcję: glEnable(GL_BLEND);
W przeciwnym wypadku do framebufora zostanie zawsze skopiowana nowa wartość RGBA policzona we fragment shaderze
379
![Page 380: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/380.jpg)
Określenie mieszania
Funkcje określające sposób mieszania wartości już istniejącej w framebuforze oraz wartości obliczonej przez fragment shader: glBlendFunc(GLenum src, GLenum dst)
glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
Druga wersja umożliwia ustawienie innego mieszania dla komponentu A, a innego dla RGB
Możliwe stałe src i dst przedstawia tabelka na następnym slajdzie src oznacza wartość z fragment shadera
dst oznacza wartość z framebufora
380
![Page 381: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/381.jpg)
381
![Page 382: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/382.jpg)
Funkcja mieszania
Po określeniu, jak ma zostać przetworzone src i dst, ostateczny wynik może zostać: Dodany: p(src) + p(dst) operacja domyślna
Odjęty: p(src) – p(dst)
Odjęty, ale odwrotnie: p(dst) – p(src)
Ustalony jako minimum: min(p(src), p(dst))
Ustalony jako maximum: max(p(src), p(dst))
Określa się to funkcją glBlendEquation(), lub glBlendEquationSeparate() z parametrem: GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN albo GL_MAX
![Page 383: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/383.jpg)
Przykład mieszania
Najbardziej popularne ustawienie to: glEnable(GL_BLEND);
• Włącza mieszanie
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD); • Ostateczny kolor umieszczony we framebufferze to:
• Czyli stopień wymieszania z „tłem” określa Asrc ustalone przez fragment shader
383
![Page 384: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/384.jpg)
Mieszanie we fragment shaderze
Mieszanie we fragment shaderze jest dostępne na razie jedynie jako rozszerzenie na OpenGL ES: EXT_shader_framebuffer_fetch https://www.khronos.org/registry/gles/extensions/EXT/EXT_shader_framebuffer_fetch.txt
Rozszerzenie udostępnia zmienną gl_LastFragData z aktualną zawartość framebufera
384
![Page 385: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/385.jpg)
Rendering obiektów przejrzystych
Umieszczenie w scenie obiektów przejrzystych wymaga następujących kroków:
Włączenie odpowiedniego mieszania kolorów
Wyrenderowanie całej sceny z pominięciem obiektów prześwitujących
Wyłączenie uaktualniania bufora głębokości glDepthMask(GL_FALSE);
Wyrenderowanie obiektów przejrzystych w kolejności od najdalszych do najbliższych
385
![Page 386: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/386.jpg)
Sortowanie względem głębokości
Jest zadaniem nie zawsze jednoznacznym…
386
![Page 387: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/387.jpg)
Przykład OpenGL49
387
![Page 388: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/388.jpg)
A może można prościej?…
Prościej, czyli bez oddzielania nieprzejrzystych obiektów od przejrzystych i bez sortowania tych drugich…
Można:
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
388
![Page 389: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/389.jpg)
Alpha to coverage
Realizowany przez kartę algorytm alfa test, ale na poziomie antyaliasingu
Liczba odrzuconych fragmentów zależy od wartości alfa
Wadą jest to, że zaczyna ładnie wyglądać dopiero od 32 próbek na fragment
389
![Page 390: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/390.jpg)
Alpha to coverage dla różnej liczby próbek
390
![Page 391: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/391.jpg)
Przykład OpenGL50
391
![Page 392: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/392.jpg)
Billboardy
Płaszczyzny (na ogół prostokąty), które, niezależnie od położenia kamery, są zawsze zwrócone do niej na wprost
392
![Page 393: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/393.jpg)
Zastosowanie billboardów
Wizualizacja systemów cząsteczkowych Chmury
Ogień
Dym
Gwiazdy
itp.
W pewnych okolicznościach także np. drzewa, kempki trawy itp.
Paski życia (health bar) 393
„Eternal lands1” autorstwa Eternal Lands developers; screenshot taken by Sir Lothar - Eternal Lands. Licencja CC BY 3.0 na podstawie Wikimedia Commons - https://commons.wikimedia.org/wiki/File:Eternal_lands1.jpg#/media/File:Eternal_lands1.jpg
![Page 394: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/394.jpg)
Generowanie billboardów
Jedną z metod jest generowanie billboardu w geometry shaderze Geometry shader na wejściu dostaje położenie punktu centralnego
i rozmiar billboardu
Geometry shader generuje 2 trójkąty stanowiące prostokąt
Geometry shader generuje także współrzędne tekstury
Właściwy rendering wykonuje fragment shader nakładając odpowiednią teksturę
394
![Page 395: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/395.jpg)
Przykład OpenGL51
395
![Page 396: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/396.jpg)
Chmury
396 https://tel.archives-ouvertes.fr/tel-00319974/file/defense.pdf
![Page 397: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/397.jpg)
Chmury, dym, ogień, gwiazdy itp.
Na drodze symulacji (która również może być realizowana na GPU!) generujemy punkty (cząstki), których ruch i położenie imituje te zjawiska
Wizualizacja chmury cząstek najczęściej jest wówczas realizowana przy pomocy billboardów z teksturą o dużej przejrzystości (małym alfa)
397
![Page 398: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/398.jpg)
Przykład OpenGL52
398
![Page 399: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/399.jpg)
Przykład OpenGL53
399
![Page 400: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/400.jpg)
Obrazowanie objętościowe
400
Volume rendering
![Page 401: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/401.jpg)
Medycyna
Obrazowanie wolumetryczne wykorzystywane jest głównie w medycynie (ale też np. w archeologii)
Tomografia komputerowa (CT) Pierwszy tomograf powstał w 1968 roku
(nobel w 1979)
Pierwszy pacjent zbadany w 1972
Rezonans magnetyczny (MRI) Wymyślony w 1971 roku (nobel w 2003)
Pierwszy przydatny skan w 1980
Pozytonowa tomografia emisyjna (PET) – dodatkowo z CT lub MRI 401
![Page 402: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/402.jpg)
Seria zdjęć
Wynikiem działania CT czy rezonansu jest seria obrazów o tej samej rozdzielczości przedstawiającej przekroje fragmentu ciała pacjenta (głowy, tułowia, stawu kolanowego itp.) w jednakowych odstępach
402
![Page 403: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/403.jpg)
Seria zdjęć, c.d.
Sama seria zdjęć przynosi już lekarzowi bardzo dużo informacji
Chcemy jednak uzyskać także możliwość wizualizacji 3D oraz uzyskania dowolnego przekroju badanej części ciała
403
![Page 404: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/404.jpg)
Główne problemy
Badanie MRI trwa kilka-kilkanaście minut – nie zawsze jest możliwe całkowite unieruchomienie pacjenta
Zbyt niska rozdzielczość obrazów lub zbyt duży odstęp między przekrojami
Nieostre obrazy
Szumy i inne zakłócenia
Różnice pomiędzy obrazami w poszczególnych warstwach
Mnogość formatów danych
404
![Page 405: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/405.jpg)
Wyzwanie
Jednoczesna wizualizacja danych z wielu źródeł…
405
![Page 406: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/406.jpg)
DICOM
Digital Imaging and Communications in Medicine
Format przechowywania obrazów medycznych Wiele dodatkowych danych dotyczących pacjenta, metody pomiaru itp.
Opracowana dla ujednolicenia wymiany danych
Główna wada: format jest zbyt obszerny, wielość możliwości powoduje, że w różnych programach lub placówkach medycznych są one wypełniane w różny sposób
Osobnym problemem jest brak mechanizmów szyfrowania/uwierzytelniania
406
![Page 407: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/407.jpg)
Trywialna rekonstrukcja 3D
Polega na wyrenderowaniu odpowiedniej liczby prostokątów z naniesionymi teksturami
Pojawi się problem z obserwacją dla niewielkich kątów patrzenia
Pojawi się problem z kolejnością rysowania prostokątów
Dobór kanału alpha, progu odcięcia
Stosuje się na ogół rzutowanie równoległe zamiast perspektywicznego
Uwaga na problem lustrzanego odbicia! Ciało ludzkie jest prawie symetryczne, więc łatwo o pomyłkę
407
![Page 408: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/408.jpg)
Przykład OpenGL54
408
![Page 409: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/409.jpg)
Kolejność renderingu warstw
Kolejność renderingu warstw ma znaczenie
Należy wyświetlać je w kolejności od najdalszej do najbliższej (w stosunku do obserwatora)
409
![Page 410: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/410.jpg)
Przykład OpenGL55
410
![Page 411: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/411.jpg)
Tekstury 3D
W OpenGL mamy do dyspozycji także tekstury trójwymiarowe
Ich obsługa (alokowanie, wczytywanie, dostęp w shaderach) jest identyczny jak w przypadku tekstur 2D, dodana jest jedynie trzecia współrzędna określająca odpowiednio rozmiar tekstury lub położenie punktu w teksturze
411
![Page 412: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/412.jpg)
Tekstury 3D, c.d.
Jedno z podejść polega na tym, że w czasie renderingu przekształcane są współrzędne tekstury 3D a nie obiektu
Często voxele (trójwymiarowe odpowiedniki pixeli) nie są sześcianami – OpenGL nie uwzględnia takiej możliwości (podobnie jak niekwadratowych pixeli) bezpośrednio, trzeba to uwzględnić w odpowiednim skalowaniu macierzy, np.: v_matrix.scale(1.0, width*spacing_x/(height*spacing_y),
width*spacing_x/(depth*spacing_z)); 412
![Page 413: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/413.jpg)
Przykład OpenGL56
413
![Page 414: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/414.jpg)
Inne metody
Splatting Rzutowanie vexeli jako billboardy
Shear warp Odpowiednie przeskalowanie i przesunięcie źródłowych tekstur
https://graphics.stanford.edu/papers/shear/shearwarp.pdf
414
![Page 415: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/415.jpg)
Odtwarzanie geometrii
Innym sposobem wizualizacji jest próba rekonstrukcji geometrii na podstawie danych wolumetrycznych
Wymaga określenia progu, który umożliwi detekcję izopowierzchni – jest najłatwiejsze w przypadku kości, czy zastosowania kontrastu
415
![Page 416: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/416.jpg)
Algorytm marching cubes
Wymyślony w 1987 (Williama E. Lorensen, Harvey E. Cline)
Algorytm opatentowany w USA w 1987, jednak już wygasł…
Podział przestrzeni na sześciany
416 "Marchingcubes-head". Licensed under CC BY-SA 2.5 via Commons - https://commons.wikimedia.org/wiki/File:Marchingcubes-head.png#/media/File:Marchingcubes-head.png
![Page 417: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/417.jpg)
Marching cubes
W każdym z wierzchołków sześcianu sprawdzane jest, czy wartość pola skalarnego jest większa, czy mniejsza od progu
Jest zatem 256 możliwości (28), jednak ze względu na różne symetrie autorzy wyodrębnili jedynie 15 przypadków kanonicznych
417
„MarchingCubes” autorstwa Jmtrivial (talk). Licencja GPL na podstawie Wikimedia Commons - https://commons.wikimedia.org/wiki/File:MarchingCubes.svg#/media/File:MarchingCubes.svg
![Page 418: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/418.jpg)
Teksturowanie proceduralne
418
![Page 419: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/419.jpg)
Tekstury statyczne
Tradycyjne tekstury
Zaleta: dzięki sprzętowej realizacji i optymalizacji są bardzo szybkie
Wady: • Zajmują pamięć GPU
• Są statyczne
• Sprawiają kłopot przy projektowaniu obiektów o skomplikowanym kształcie
419
![Page 420: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/420.jpg)
420
![Page 421: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/421.jpg)
Tekstury proceduralne
Innym pomysłem na określenie koloru fragmentu jest jego algorytmiczne obliczenie, tak aby obiekt przypominał wykonanie z jakiegoś naturalnego materiału (klasyczne przykłady to drewno i marmur)
Tekstury proceduralne mogą być 2D lub 3D (a nawet 4D)
Wadą jest brak pełnej kontroli grafików nad powstającą teksturą (w odróżnieniu od tekstur klasycznych, którym zawsze można coś dorysować)
421
![Page 422: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/422.jpg)
Tekstury proceduralne
Tekstury proceduralne mogą być obliczane: Off-line, czyli np. przed renderingiem sceny czy animacji i następnie
załadowane jako tradycyjne tekstury statyczne do GPU – to rozwiązanie dotyczy głównie tekstur 2D
On-line, czyli na bieżąco w shaderze w czasie redneringu – obliczenia powinny być zatem maksymalnie uproszczone i zoptymalizowane
Podobnie, jak tekstury tradycyjne, mogą być wykorzystywane także do zaburzania normalnych, przesunięcia paralaksy, generowania wysokości terenu itp. 422
![Page 423: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/423.jpg)
Tekstury proceduralne 3D
Wartość tekstury obliczana jest w funkcji trójwymiarowej pozycji
mapowanie do współrzędnych tekstury UV nie jest potrzebne
Uzyskujemy efekt wycięcia obiektu z materiału
423
![Page 424: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/424.jpg)
Tekstury proceduralne 3D, c.d
Często stosowany schemat:
gdzie: c – kolor wynikowy
p – funkcja periodyczna
n – wykładnik funkcji periodycznej (zmienia szerokości warstw)
f – funkcja pozycji (może być także zależna od czasu t)
s – funkcja szumu
424
![Page 425: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/425.jpg)
Przykład 1 - drewno
Funkcje:
p – funkcja piłokształtna
425
![Page 426: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/426.jpg)
Przykład 2 - marmur
426
Funkcje:
p – funkcja sin
![Page 427: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/427.jpg)
Przykład OpenGL57
427
![Page 428: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/428.jpg)
Świat nie jest idealny
Drewniane klocki z ostatniego przykładu wyglądają jakby: Wyciął je stolarz perfekcjonista (idealnie centralnie i symetrycznie)
Zostały wycięte z idealnego drzewa (słoje regularne i koncentryczne, o stałej grubości)
Marmurowe klocki wyglądają jeszcze gorzej…
428
![Page 429: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/429.jpg)
Wprowadzenie zniekształceń
Można wprowadzić macierz przekształcenia tekstury, która poprzez translację i rotację, wyeliminuje problem idealnego rzemieślnika (stolarza, kamieniarza)
Do wprowadzenia zakłóceń w strukturze należy użyć funkcji szumu s
429
![Page 430: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/430.jpg)
Funkcje szumu
Funkcje szumu służą do wprowadzenia kontrolowanej losowości do modelu tekstury
Szum musi być powtarzalny
Najczęściej jest realizowany poprzez pseudolosową funkcję s, której parametr (1,2,3…n wymiarowy) jest przekształcany na liczbę z zakresu [-1, 1] lub [0, 1]
Dla tego samego parametru funkcja musi zwrócić tę samą wartość
430
![Page 431: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/431.jpg)
Funkcje szumu, c.d.
Funkcja szumu powinna mieć następujące własności: Średnia wartość szumu powinna być w połowie przedziału
Charakter statystyczny nie powinien zależeć od translacji i rotacji (powinien być izotropowy)
W GLSL dostępne są funkcje noiseN(…), jednak na większości kart nie działają Kompilacja shadera uda się, program się uruchomi, ale noise() zwraca stałą
wartość…
431
![Page 432: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/432.jpg)
Kenneth H. "Ken" Perlin
1981 – praca przy filmie TRON
1983 – pierwszy generator szumu
1984 – pierwszy shader (język+interpreter)
1986-88 – Pixar, Alias, Softimage, Renderman, Dynamation, 3D Studio Max, …
• Filmy Jamesa Camerona (Abyss,Titanic,...), filmy animowane (Lion King, Moses,...), filmy ze Schwarzeneggerem (T2, True Lies, ...), filmy Star Wars, filmy Star Trek, filmy z Batmanem, …
1989 – hypertekstury
432
http://mrl.nyu.edu/~perlin/
![Page 433: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/433.jpg)
To Ken Perlin for the development of Perlin Noise, a technique used to produce natural appearing textures on computer generated surfaces for motion picture visual effects.
The development of Perlin Noise has allowed computer graphics artists to better represent the complexity of natural phenomena in visual effects for the motion picture industry.
433
Nagroda Akademii „Technical Achievement Award” – 1997
![Page 434: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/434.jpg)
Szum Perlina
Algorytm w skrócie: Funkcja Rn [-1, 1] (najczęściej n = 1…4)
W przestrzeni Rn mamy regularną siatkę z wygenerowanymi pseudolosowo wartościami gradientu (osobny algorytm)
Dla każdego punktu odnajdujemy jego 2n najbliższych węzłów
Dla każdego węzła obliczamy wektor do niego i mnożymy iloczynem skalarnym z wartością gradientu w węźle
Otrzymane wartości interpolujemy jakąś gładką funkcją np. 3x2 – 2x3
(potrzebne jest 2n - 1 interpolacji) 434
![Page 435: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/435.jpg)
Szum Perlina, c.d. Użycie czasu jako dodatkowego wymiaru pozwala na uzyskanie
animacji (szum 3D i 4D):
435
http://www.noisemachine.com/talk1/
![Page 436: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/436.jpg)
Szum Simplex
Inny sposób generacji szumu (Ken Perlin 2001) Mniejsza ilość obliczeń
Mniejsza złożoność obliczeniowa O(n2) zamiast O(2n) (n – wymiarowość)
Lepsza niezależność szumu od kierunku
Łatwiejsza implementacja sprzętowa
Szczegóły: http://webstaff.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
436
![Page 437: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/437.jpg)
Szum widmowy (fraktalny)
Prosta funkcja szumu nie daje czasem oczekiwanych rezultatów ze względu na mały zakres częstotliwości
W celu uzyskania szumu widmowego należy zastosować sumę szumów, za każdym razem zwiększając częstotliwość (2x) i zmniejszając amplitudę (2x)
437
![Page 438: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/438.jpg)
Przykład OpenGL58
438
![Page 439: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/439.jpg)
Użycie funkcji szumu w teksturach
Zaburzając współrzędne tekstury szumem możemy uzyskać bardziej naturalne efekty
Np. dla drewna:
439
![Page 440: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/440.jpg)
Przykład OpenGL59
440
![Page 441: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/441.jpg)
Szum Worley’a
Wprowadzony przez Stevena Worley’a w 1996
Zwany też szumem komórkowym (cell noise)
Bazuje na diagramie Woronoja (Георгий Феодосьевич Вороной)
Algorytm: Pseudolosowe wylosowanie punktów w przestrzeni
Funkcja szumu Fn(x,y,z) zwraca n najbliższych odległości od punktów
Szczegóły: http://www.rhythmiccanvas.com/research/papers/worley.pdf
441
![Page 442: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/442.jpg)
Przykład OpenGL60
442
![Page 443: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/443.jpg)
Zaznaczanie obiektów
443
![Page 444: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/444.jpg)
Wskazywanie obiektów (object picking)
Często zdarza się, że powstaje potrzeba, aby użytkownik mógł wskazać (klikając myszką, dotykając palcem) obiekt lub jego fragment
Istnieje wiele metod na wykrycie, który obiekt został wskazany, wybór metody zależy od takich czynników, jak np.: Szybkość działania
Oczekiwana precyzja
Dostępne dane 444
![Page 445: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/445.jpg)
Wskazywanie obiektów, c.d.
Mając dane współrzędne ekranu (x, y), należy znaleźć obiekt, który w tym miejscu został wyrenderowany
Metody geometryczne Ray-tracing pojedynczego promienia (od kamery przez (x, y)) i znalezienie
najbliższego przecięcia
Odczytanie z z-bufora wartości głębokości z i dokonując przekształceń odwrotnych można z punktu (x, y, z) odtworzyć punkt w przestrzeni modelu a następnie odnaleźć obiekt znajdujący się najbliżej
445
![Page 446: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/446.jpg)
Wskazywanie obiektów, c.d.
Metody oparte o OpenGL Renderowanie obiektów z
zapamiętaniem ich identyfikatorów we framebuforze
• Można napisać oddzielny program na GPU, który wykona tę czynność wtedy kiedy taki odczyt będzie konieczny
• Można także wykonać tę czynność przy okazji generowania g-buffora w metodzie opóźnionego cieniowania
446
![Page 447: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/447.jpg)
Przekazanie id obiektu do shadera
Jeżeli obiekty są renderowane oddzielnie jako uniform
Jeżeli wiele obiektów jest renderowanych z VBO id jako dodatkowe pole (obok położenia, normalnych itp.)
Jeżeli wykorzystujemy instancing można wykorzystać gl_InstanceID
Inne
447
![Page 448: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/448.jpg)
Pobranie id z tekstury
W wersjach OpenGL < 4.5 Musimy pobrać całą teksturę do CPU
glBindTexture(GL_TEXTURE_2D, tex_id);
glGetTexImage(GL_TEXTURE_2D, 0, …, …, ids);
W OpenGL >= 4.5 Można pobrać dowolny prostokąt z tekstury, także taki o wymiarach 1x1:
glGetTextureSubImage(tex_id, 0, x, y, 0, 1, 1, 1, …, …, sizeof(id), &id);
448
![Page 449: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/449.jpg)
Przykład OpenGL61
449
![Page 450: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/450.jpg)
Obwódka obiektu (outline)
Wizualne sygnalizowanie wskazanego obiektu Zmiana koloru
Obwódka
Do zrobienia obwódki można wykorzystać: Bufor z id obiektów
• Obwódkę można dodatkowo rozmyć (np. gaussem), co może dać dodatkowy ładny efekt
Stencil buffer
450
![Page 451: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/451.jpg)
Przykład OpenGL62
451
![Page 452: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/452.jpg)
Stencil buffer
Dodatkowy bufor pozwalający na ciekawe operacje, np. maskowanie
Bufor najczęściej jest 8bitowy (8 bitów na każdy pixel), ale można to sprawdzić: int stencil_bits;
glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
452
![Page 453: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/453.jpg)
Stencil buffer, c.d.
Stencil buffer wykonuje dwie czynności: testowanie i właściwą operację
Testowanie polega obliczeniu wyrażenia: (ref & mask) FUNC (stencil & mask) Gdzie:
• ref – referencyjna stała całkowita
• mask – stała całkowita umożliwiająca korzystanie z wybranych bitów stencil bufora
• FUNC – operacja logiczno-relacyjna (GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL, GL_EQUAL, GL_NOTEQUAL
• stencil – zawartość stencil bufora
glStencilFunc(func, ref, mask) 453
![Page 454: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/454.jpg)
Stencil buffer, c.d.
Właściwa akcja definiowana jest dla 3 sytuacji: sfail – stytuacja, kiedy test stencil bufora zwrócił 0
dpfail – sytuacja, kiedy test stencil bufora nie zwrócił 0, ale test głębokości wykazał, że fragment będzie niewidoczny
dppass – sytuacja gdy oba testy przeszły pomyślnie
Uwaga: fragment nie jest obliczany, jeśli stencil test zwrócił 0!
W każdym z w/w przypadków możliwa jest jedna z czynności: GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_INCR_WRAP, GL_DECR, GL_DECR_WRAP, GL_INVERT
glStencilOp(sfail, dpfail, dppass) 454
![Page 455: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/455.jpg)
Czynności wykonywane na stencil buforze GL_KEEP - nie zmienia zawartości
GL_ZERO - ustawia na 0
GL_REPLACE - zamienia na wartość ref
GL_INCR - zwiększa zawartość stencil bufora o 1, aż do maksimum
GL_INCR_WRAP - zwiększa zawartość bufora, ale przechodzi na 0 po osiągnięciu maksimum
GL_DECR - zmiejsza wartość stencil bufora aż do 0
GL_DECR_WRAP - zmiejsza wartość stencil bufora, ale przechodzi na maksimum po osiągnięciu 0
GL_INVERT - neguje bity stencil bufora
455
![Page 456: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/456.jpg)
Przykład - obwódka obiektu z wykorzystaniem stencil bufora glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 1, 0xFFFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
// tu renderujemy obiekt normalnie efekt: „1” tam gdzie obiekt
glStencilFunc(GL_NOTEQUAL, 1, 0xFFFF);
// tu renderujemy obiekt jako wireframe „grubymi” liniami
glDisable(GL_STENCIL_TEST); 456
![Page 457: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/457.jpg)
457
1
2
Bufor koloru i stencil
![Page 458: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/458.jpg)
Wady i zalety metody
Wady Obrysowywany obiekt wymaga dwukrotnego renderingu
Linie, szczególnie grubsze nie są ładnie rysowane przez OpenGL
Zalety Prostota implementacji
Brak konieczności alokowania i używania własnych buforów
458
![Page 459: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/459.jpg)
Przykład OpenGL63
459
![Page 460: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/460.jpg)
Wykrywanie krawędzi
W celu uzyskania „komiksowego” wyglądu można dokonać detekcji krawędzi w oparciu o: Wektory normalne
Bufor głębokości
Wykrywanie krawędzi – wiele algorytmów: Krzyż Robertsa
Operator Sobela
Operator Sharra
Algorytm Canny’ego
… 460
![Page 461: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/461.jpg)
Krzyż Robertsa
461
![Page 462: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/462.jpg)
Operator Sobela
462
![Page 463: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/463.jpg)
Przykład OpenGL64
463
![Page 464: Rendering czasu rzeczywistego (PDF)](https://reader034.fdocument.pub/reader034/viewer/2022051302/587603bf1a28ab6c728b7ea5/html5/thumbnails/464.jpg)
464