Skip to content
This repository was archived by the owner on Jun 11, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 175 additions & 3 deletions reports/RelatorioFase2.tex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
\documentclass[12pt, a4paper]{article}

\usepackage{amsmath}
\usepackage{bm}
\usepackage{array}
\usepackage{amsmath}
\usepackage[portuguese]{babel}
Expand Down Expand Up @@ -85,7 +86,164 @@ \section{Modelo estático do sistema solar}

\section{Extras}

\textbf{\color{red} TODO - extras}
\section{\emph{Frustum culling}}

Cada \emph{draw call} tem um custo elevado para o desempenho da aplicação. Logo, procurando reduzir
o número de \emph{draw calls}, foi implementado \emph{frustum culling}, para apenas ser requisitada
à GPU a renderização das entitidades totalmente ou parcialmente no \emph{view frustum} da câmara.

Seria muito computacionalmente intensivo verificar se a geometria de um modelo se encontra dentro ou
fora do \emph{view frustum}, pelo que se encapsulam todos os modelos em esferas que, devido à sua
geometria simples, permitem uma verificação rápida da sua visibilidade no \emph{view frustum}. No
entanto, visto que estas esferas podem ser um pouco maiores do que os modelos em si, é possível que
algumas entidades fora do ecrã sejam desenhadas, visto que parte das suas esferas ainda podem
intersetar os planos do \emph{view frustum}. Para mitigar este problema, formas geométricas
encapsuladoras mais complexas poderiam ser utilizadas, visto que estas se poderiam adaptar melhor à
geometria dos modelos. No entanto, o uso destas formas complexas conduziria a testes de visibilidade
mais caros, possivelmente anulando os benefícios de desenhar um menor número de entidades.

Quando um modelo é carregado, é necessário calcular a esfera que o encapsula. Em primeiro lugar, o
seu centro é calculado como o centro de massa de todos os pontos, como mostra a expressão abaixo,
onde $M$ é o modelo, uma sequência de pontos tridimensionais:

$$
C = \frac{1}{|M|} \sum_{p \in M} p
$$

Depois, o raio da esfera pode ser determinado como a distância entre o centro da esfera e o ponto
mais longínquo do mesmo, como mostra a expressão abaixo, onde $d$ é a função de distância cartesiana
entre dois pontos:

$$
r = \max \left \lbrace d(C, p) \mid p \in M \right \rbrace
$$

É também necessário saber como uma esfera encapsuladora é afetada quando o objeto que encapsula
sofre uma transformação no mundo. Considere-se uma matriz de transformação aplicada ao objeto (em
coordenadas do mundo), originada através da aplicação de translações, rotações, e escalas. A matriz
será 4x4 e terá o seguinte aspeto:

$$
\bgroup
T =
\begin{bmatrix}
\vec \imath & \vec \jmath & \vec k & \vec t \\
0 & 0 & 0 & 1
\end{bmatrix}
\egroup
$$

Para calcular o centro da esfera após a transformação da entidade, basta multiplicar a matriz de
transformação pela posição do centro da esfera:

$$
C' = T C
$$

Depois, para calcular o novo raio da esfera, não é necessário ter em conta as transformações de
rotação, visto que as esferas são simétricas em todos os eixos possíveis. No entanto, é necessário
ter em conta a escala aplicada ao modelo. Por exemplo, na matriz $T$, a escala da entidade pelo
eixo $x$ é $\lVert \vec \imath \rVert$, e o mesmo se tem para o eixo $y$ e
$\lVert \vec \jmath \rVert$, e para $z$ e $\lVert \vec k \rVert$. Logo, o raio da esfera
transformada é:

$$
r' =
\max
\left ( \lVert \vec \imath \rVert, \lVert \vec \jmath \rVert, \lVert \vec k \rVert \right )
\cdot
r
$$

É possível tirar proveito da estrutura hierárquica da cena para otimizar o processo de
\emph{frustum culling}. Por exemplo, caso um grupo contenha várias entidades ou subgrupos, pode
construir-se uma esfera que encapsula a totalidade do grupo. Caso essa esfera não esteja no
\emph{view frustum}, pode-se evitar fazer os testes de visibilidade para as esferas dos objetos
individuais que compõem o grupo. Caso contrário, é na mesma necessário realizar esses testes.

O processo para determinar as características de uma esfera que encapsula todos os objetos de um
grupo é semelhante ao da construção de esferas com base no conjunto de pontos de um modelo. Em
primeiro lugar, para determinar o centro da esfera, calcula-se o centro de massa do conjunto de
pontos formado pelos centros de todas as esferas, $C$. De seguida, para cada subesfera, calcula-se
a sua distância máxima a $C$, o raio da subesfera adicionado à distância entre $C$ e o centro da
subesfera. Depois, a maior destas distâncias é escolhida para ser o raio da nova esfera, como mostra
a expressão abaixo, onde $S$ representa o conjunto de subesferas:

$$
r' = \max \left \lbrace d(C', C) + r \mid (C, r) \in S \right \rbrace
$$

Depois de saber como determinar as esferas encapsuladoras das entidades, é necessário determinar
o \emph{view fustum} da câmara, para se poder verificar a posição das esferas em relação aos planos
do \emph{view fustum}. Para determinar o \emph{view frustum}, é necessário obter alguns vetores
importantes da câmara \cite{lighthouse3d-frustum-planes}:

\textbf{\color{red} TODO - com a fusão das partes do relatório, referenciar vetores da câmara livre}

Além destes vetores, é também necessário conhecer as dimensões dos planos \emph{near} e \emph{far}.
Apesar de, matematicamente, planos não terem uma altura e uma largura, utiliza-se esta linguagem
para se referir às dimensões dos retângulos nestes planos que constituem o \emph{view frustum}. Na
expressão abaixo, mostra-se como se pode calcular a altura ($H_\text{near}$) e a largura
($W_\text{near}$) do plano \emph{near}. O processo para o plano \emph{far} é semelhante. Com o FOV
da câmara ($\theta$), a distância ao plano \emph{near} ($d_\text{near}$) e o \emph{aspect ratio}
(A), podem calcular-se as dimensões deste plano \cite{lighthouse3d-frustum-distances}:

$$
H_\text{near} = 2 d_\text{near} \tan \left ( \frac{\theta}{2} \right )
\hspace{1cm}
W_\text{near} = H_\text{near} A
$$

Com estes valores, é possível determinar as coordenadas dos pontos dos retângulos do
\emph{view frustum}. Os quatro pontos do plano \emph{near} (a amarelo na figura abaixo) podem ser
calculados do seguinte modo, e o método utilizado para o plano \emph{far} é semelhante
\cite{lighthouse3d-frustum-planes}:

$$
F = P +
d_\text{near} \; \widehat{d} \; \pm
\frac{H_\text{near}}{2} \; \widehat{up} \; \pm
\frac{W_\text{near}}{2} \; \widehat{r} \;
$$

\begin{figure}[H]
\centering
\includegraphics[width=0.4\textwidth]{res/phase2/ViewFrustum.pdf}
\caption{\emph{View Frustum}.}
\end{figure}

Com os oito pontos do \emph{view frustum}, é possível determinar as equações cartesianas de cada
um dos seus planos, considerando três pontos da sua superfície. Em primeiro lugar, determina-se o
vetor normal ao plano. Com os três pontos, $P_1$, $P_2$ e $P_3$, determinam-se dois vetores, a
partir dos quais se calcula um produto externo, determinando-se assim um vetor perpendicular ao
plano \cite{lighthouse3d-plane}:

$$
n = \overrightarrow{P_1 P_2} \times \overrightarrow{P_1 P_3}
$$

Depois, com este vetor normalizado, é possível determinar a constante na equação cartesiana do plano
com base nas coordenadas de um dos três pontos dados \cite{lighthouse3d-plane}:

\begin{align*}
& \alpha x + \beta y + \gamma z + \delta = 0 \\
\Leftrightarrow \; & \widehat{n} \cdot P + \delta = 0 \\
\Leftrightarrow \; & \delta = -\widehat{n} \cdot P
\end{align*}

Durante a renderização de cada \emph{frame}, verificam-se que esferas estão totalmente ou
parcialmente dentro do \emph{view frustum}. Para uma esfera estar no \emph{view frustum} $F$, é
necessário que a distância assinada entre o centro da esfera e cada um dos planos do
\emph{view frustum} não seja inferior ao simétrico do seu raio, ou seja \cite{lighthouse3d-sphere}:

$$
\forall_{p \in F} \left ( \widehat{n} \cdot C + \delta \ge - r \right )
$$

Uma vez que é necessário calcular distâncias assinadas, é imperativo que os vetores normais de todos
os planos do \emph{view frustum} apontem para o seu interior, para que o conteúdo no seu interior (e
não no seu exterior) seja desenhado. \cite{lighthouse3d-frustum-planes} Por este motivo, a ordem em
que os pontos $P_1$, $P_2$ e $P_3$ são especificados é relevante.

\section{Resultados obtidos}

Expand All @@ -100,8 +258,22 @@ \section{Bibliografia}
\renewcommand{\section}[2]{}

\begin{thebibliography}{9}
\bibitem{exemplo}
\href{https://youtu.be/dQw4w9WgXcQ}{Um item de exemplo na bibliografia}
\bibitem{lighthouse3d-frustum-planes}
``Geometric Approach -- Extracting the Planes.''. Lighthouse3d.com. Accessed:
Mar. 29, 2025. [Online.] Available:
\url{https://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/}
\bibitem{lighthouse3d-frustum-distances}
``View Frustum’s Shape.''. Lighthouse3d.com. Accessed:
Mar. 29, 2025. [Online.] Available:
\url{https://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/}
\bibitem{lighthouse3d-plane}
``Plane.''. Lighthouse3d.com. Accessed:
Mar. 29, 2025. [Online.] Available:
\url{https://www.lighthouse3d.com/tutorials/maths/plane/}
\bibitem{lighthouse3d-sphere}
``Geometric Approach -- Testing Points and Spheres.''. Lighthouse3d.com. Accessed:
Mar. 29, 2025. [Online.] Available:
\url{https://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-points-and-spheres/}
\end{thebibliography}
\endgroup

Expand Down
Binary file added reports/res/phase2/ViewFrustum.pdf
Binary file not shown.
4 changes: 3 additions & 1 deletion scripts/formatlatex.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ grep_error_message() {

# shellcheck disable=SC2266
find reports -type f -name "*.tex" | while IFS="" read -r file; do
grep -PHn '.{101,}$' "$file" | grep_error_message "Column exceeds 100 characters"
grep -PHn '.{101,}$' "$file" | \
grep -Pv 'http' | \
grep_error_message "Column exceeds 100 characters"
grep -PHn '\t$' "$file" | grep_error_message "Use of tabs"
grep -PHn '\s+$' "$file" | grep_error_message "Trailing whitespace"
done |
Expand Down