Autor: Danilo Santos Vieira / Matrícula 20160141328
Esse repositório foi organizado da seguinte forma: a pasta trabalhos localizada em https://github.com/Danilosvsv/ICG, contém todos os códigos desenvolvidos por trabalho, já a parte da explicação dos resultados com texto/printscreens serão desenvolvidos no decorrer desse arquivo "readme.md".
- Trabalho 1: Rasterização de Linhas
- Trabalho 2: Compilando e Executando um Programa OpenGL Moderno
- Trabalho 3: Pipeline Gráfico
- Trabalho 4: Implementação de Modelos de Iluminação
Esse trabalho apresenta a fundamentação matemática para a compreensão e implementação de algoritmos para o desenho de pontos, linhas e triângulo na tela do computador. Para essa tarefa, foi necessário entender o algoritmo de Rasterização de Linhas, revisar conhecimentos fundamentais da matemática, como a equação da reta, e no âmbito computacional, foi necessário a instalação do OpenGL 3.0 e da Linguagem de Programação C.
Para desenhar um ponto na tela foi criado uma função que pega as coordenadas (x,y) e a cor desse ponto através dos seus respectivos valores R,G,B,A e rasteriza esse ponto na memória de vídeo atravès de um framework fornecido em: https://github.com/capagot/icg/tree/master/mygl_framework.
Algoritmo:
DesenhaPonto(x,y,valor R,valor G,,valor B,valor A){
fb_ptr[4*x+ 4*y*IMAGE_WIDTH + 0] = valor R;
fb_ptr[4*x+ 4*y*IMAGE_WIDTH + 0] = valor G;
fb_ptr[4*x+ 4*y*IMAGE_WIDTH + 0] = valor B;
fb_ptr[4*x+ 4*y*IMAGE_WIDTH + 0] = valor A;
}
Após a aplicação do algoritmo acima, obteve-se o seguinte resultado:
Figura 1 - Desenhando um ponto
A princípio, foi fornecido o Algoritmo de Bresenham para o caso 0 < m < 1.
MidPointLine() {
int dx = x1 – x0;
int dy = y1 – x0;
int d = 2 * dy – dx;
int incr_e = 2 * dy;
int incr_ne = 2 * (dy – dx);
int x = x0;int y = y0;
PutPixel(x, y, color)
while (x < x1) {
if (d <= 0) {
d += incr_e;x++;
}else {
d += incr_ne;
x++;
y++;
}
PutPixel(x, y, color);
}
}
Porém, não pode-se limitar o desenho das linhas apenas para o 1 octante, logo, é necessário generalizar esse algoritmo para os outros octantes, ou seja, realizou-se uma análise para identificar o comportamento de (x1-x0), (y1-y0), m e a relação entre as coordenadas x0,x1 e y0,y1 nos outros octantes. Dessa forma, obteve-se os seguintes resultados:
Figura 2 - Teste inicial: Desenho de linhas
Figura 3 - Teste final: Desenho de linhas
Por fim, foi feito uma interpolação das cores para o desenho da linha e triângulo. Previamente haviamos definido a cor do "objeto" a ser desenhado através dos seus parâmetros (r,g,b,a), agora define-se mais quatro parâmetros (r1,g1,b1,a1) para a segunda cor, logo a relação da interpolação das cores a ser calculada antes da chamada da função de desenho é dada pelo seguinte trecho de código:
float dr = (r1-r)/dx;
float dg = (g1-g)/dx;
float db = (b1-b)/dx;
float da = (a1-a)/dx;
Assim, obteve-se os seguintes resultados:
Figura 4 - Interpolação de cores: linha
Figura 5 - Interpolação de cores: triângulo
Para a execução desse trabalho, houve uma dificuldade considerável para generalizar o Algoritmo de Bresenham e para desenvolver a interpolação de cores. Uma possível melhoria pro trabalho seria a otimização do código com estruturas ou funções.
Notas de Aula da disciplina de Introdução à Computação Gráfica.
O teste pode ser visualizado através do vídeo no link: https://youtu.be/6ezLbbMFD6w
Esse trabalho consiste na verificação do ambiente de desenvolvimento em OpenGl 3.3. Assim, para essa tarefa foi fornecido o seguinte diretório no github https://github.com/capagot/icg/tree/master/hello_world_gl/modern_opengl. Dessa forma, realizou-se uma compilação inicial para observar se o resultado retornado à tela do usuário corresponde a um triângulo colorido.
Como observado, ainda não foi possível obter o triângulo, logo, foi feito mais alguns testes até que foi retornado a seguinte mensagem no terminal:
A figura 3 mostra que o OpenGL instalado na máquina é inferior a versão 3.3 do OpenGl, logo foi necessário realizar atualizações na máquina de forma a atualizar o OpenGl. Para isso foi realizado consultas na internet, de forma a achar os seguintes comandos para serem executados:
sudo apt-get update
sudo apt-get install freeglut3
sudo apt-get install freeglut3-dev
sudo apt-get install binutils-gold
sudo apt-get install g++ cmake
sudo apt-get install libglew-dev
sudo apt-get install g++
sudo apt-get install mesa-common-dev
sudo apt-get install mesa-common-dev
sudo apt-get install libglew1.5-dev libglm-dev
glxinfo | grep OpenGL
export MESA_GL_VERSION_OVERRIDE=3.3
Portanto, obteve-se o seguinte resultado
https://pt.wikihow.com/Instalar-Mesa-(OpenGL)-no-Linux-Mint
https://stackoverflow.com/questions/52592309/0110-error-glsl-3-30-is-not-supported-ubuntu-18-04-c
Esse trabalho consiste em aplicar conceitos de transformações geométricas através do OpenGL, GLM, Glew e C++. Onde o código foi fornecido pelo professor da disciplina através do repositório: https://github.com/capagot/icg. Com o código pronto para compilação, foram realizadas alterações nas matrizes 'model, 'view' e 'projection' de forma a gerar as imagens solicitadas na descrição do projeto. A seguir apresenta-se os resultados obtidos para cada transformação geométrica:
Exercício 1: Escala - No espaço bidimensional, essa transformação consiste em pegar as coordenadas x, y e z e modificar a largura e altura da figura original através da matriz model.
Exercício 2: Translação - Essa transformação move um elemento de sua posição atual de acordo com as coordenadas da matriz model.
Exercício 3: Projeção Perspectiva - Usada para tornas os objetos realísticos, onde a sua modelagem é caracterizada por:
Primeiramente, temos:
"As coordenadas (x,y), da projeção perspectiva P'' de qualquer ponto P de coordenadas (x,y,z), colocado do lado oposto de CP, em relação ao plano de projeção PI, é obtido criando-se uma linha L de P até CP e calculando-se a intersecção desta com o plano PI. A figura 2 exemplifica o cálculo de P".
Assim, é possível calcular P'' e por fim obter por semelhança de triângulo o valor da distância focal. Uma vez que obtida a expressão da distância focal, obteve-se através das notas de aula a matriz de projeção apresentada no código.
Exercício 4: Posição da Câmera - é uma transformação de um objeto e de sua área circundante que difere significativamente da aparência do objeto com uma distância focal normal , devido à escala relativa de características próximas e distantes.
Exercício 5: Transformações Livres - nessa transformações mudou-se os valores da matrizes 'model, 'view' e 'projection' simultaneamente.
Conclusão: A principal dificuldade encontrada no trabalho foi em relação a posição da câmera e fica como uma possível melhoria.
Referências:
- https://www.inf.pucrs.br/~pinho/CG/Aulas/Vis3d/Vis3d.htm#:~:text=A%20modelagem%20matem%C3%A1tica%20da%20proje%C3%A7%C3%A3o,Centro%20de%20Proje%C3%A7%C3%A3o(CP).
- https://en.wikipedia.org/wiki/Perspective_distortion_(photography)
Esse trabalho consiste em aplicar conceitos matemáticos referentes aos modelos de iluminação que são utilizadas no processo de rasterização como, por exemplo: ambiente, difuso e especular (Phong). Para essa tarefa foram utilizados o OpenGL, GLM, Glew e C++. O código foi fornecido pelo professor da disciplina através do repositório: https://github.com/capagot/icg. Com o código pronto para compilação, foram realizadas alterações no arquivo 'vertex_shader.glsl' de forma a adicionar os modelos de reflexão. Sobre os modelos de reflexão ou iluminação, pode-se afirmar que "definem a natureza da luz emanada por uma fonte e sua interação com todos os objetos da cena".
Exercício 1: Implementação do Modelo de Reflexão Difuso
"É a reflexão da luz ou outras ondas ou partículas de uma superfície, de forma que um raio incidente na superfície é espalhado em muitos ângulos, em vez de em apenas um ângulo, como no caso da reflexão especular". Para resolver essa atividade foram adicionadas alterações nos valores dos vetores, de acordo com o fornecido na figura 3 da descrição do trabalho. As mais significativas foram:
vec3 L = normalize(I_p_pos - (model_mat * vec4(obj_spc_vertex_pos , 1.0)).xyz);
vec3 N = normalize(mat3(transpose(inverse(model_mat))) * obj_spc_N);
I = I_a * k_a + I_p * k_d * (L * N);
Exercício 2: Implementação do Modelo de Reflexão Especular
"É a luz direcionada em um ângulo que é exatamente oposto à luz incidente ou quando o ângulo de incidência é igual ao ângulo de reflexão". De forma análoga ao exercício anterior, foram feitas alterações nos valores dos vetores de forma a cumprir aos requisitos da figura 4. As mudanças mais significativas no código foram:
vec3 R = -reflect(L, N);
vec3 V = normalize(cam_pos - (model_mat * vec4(obj_spc_vertex_pos , 1.0)).xyz);
float specular = 0.0;
float specAngle = max(dot(R, V), 0.0); // Extraído da referência 4
specular = pow(specAngle, 64.0); // Extraído da referência 4
I = I_a * k_a + I_p * (k_d * (L * N) + k_s * specular);
Conclusão: As principais dificuldades foram deixar as imagens geradas após a aplicação dos modelos de reflexão de forma fiel as solicitadas na descrição do trabalho. Nesse sentido, teve-se que fazer uma análise minuciosa no arquivo 'vertex_shader.glsl' de forma a encontrar eventuais equivocos na digitação dos valores contidos nos vetores ou nas fórmulas dos modelos de iluminação.
Referências:
- http://www.univasf.edu.br/~jorge.cavalcanti/comput_graf13_Iluminacao.pdf
- https://en.wikipedia.org/wiki/Diffuse_reflection#:~:text=Diffuse%20reflection%20is%20the%20reflection,the%20case%20of%20specular%20reflection.
- https://www.sciencedirect.com/topics/engineering/specular-reflection#:~:text=Specular%20reflection%20is%20the%20mirror,reflected%20from%20a%20smooth%20surface.
- http://www.cs.toronto.edu/~jacobson/phong-demo/