Animação e Visualização Tridimensional Mestrado em Engenharia Informática e de Computadores Alameda º mini-teste 22 de Outubro de 204 O mini-teste tem a duração máxima de 45 minutos, tolerância incluída. Responda a caneta azul ou preta às questões seguintes justificando adequadamente todas as respostas. Se necessário utilize o verso da respectiva folha para completar a resposta. Calculadoras, telemóveis ou qualquer outro tipo de dispositivos móveis não são permitidos. Identifique todas as folhas do enunciado. Boa Sorte. Sintaxe de funções relevantes usadas em trechos de código : void lookat(gldouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz);. (2 valores) Explique o que entende por VAO e VBO. VBO é um buffer que contém informação de atributos de vértices de uma primitiva gráfica e que se destina a ser enviado para o GPU. O VAO é um objecto gerado por primitiva gráfica e que encapsula a informação do(s) VBOs bem como o respectivo layout. 2. ( valor) Considere abaixo o troço de programa em OpenGL. Indique a localização da variável position no programa GLSL referenciado por p? enum AttribType { TEXTURE_COORD, VERTEX_COORD, NORMAL_ATTRIB }; glbindfragdatalocation(p, 0,"colorOut"); glbindattriblocation(p, VERTEX_COORD, "position"); glbindattriblocation(p, NORMAL, "normal"); glbindattriblocation(p, TEXTURE_COORD, "texcoord"); gllinkprogram(p); pvm_id = glgetuniformlocation(p, "m_pvm"); vm_uniformid = glgetuniformlocation(p, "m_viewmodel"); normal_uniformid = glgetuniformlocation(p, "m_normal"); glbindattriblocation(p, VERTEX_COORD, "position"); Esta intrução impõe que o índice (location) da variável position é (posição de VERTEX_COORD no enum) 3. Considere o seguinte excerto de código em OpenGL 3.3. Assuma que foi implementado um mecanismo de pilha para os três tipos de matrizes MODEL, VIEW e PROJECTION, que caracterizam o andar de transformações geométricas no pipeline OpenGL. void renderscene(void) {.
glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); loadidentity(view); loadidentity(model); lookat(0.0, 0.0, -2.0, -2.0, 2.0, -2.0, 0.0, 0.0, -.0) pushmatrix(model); translate(model, 2.0f, 0.0f, 2.0f); draw_obj(); pushmatrix(model); scale (MODEL,.5f,.5f,.5f); draw_obj2(); popmatrix(model); draw_obj3(); popmatrix(model); a) (2 valores) Indique o conteúdo da matriz VIEW enviado para o GLSL relativo ao desenho de cada um dos três objectos. VRP = [eye x eye y eye z] = [0 0 2] VPN = [center x eye x center y eye y center z eye z] = [ 2 2 0] VUV = [up x up y up z] = [0 0 ] VUV = VUV VPN(VPN VUV ) = [0 0 ] [ 2 2 0] ([ 2 2 0] [0 0 ]) = [0 0 ] [ 2 2 0] 0 = [0 0 ] n = VPN VPN = [ 2 2 0] = [ 0] 8 v = VUV VUV = [ 0 0 ] = [0 0 ] u = n v = [ 0] [0 0 ] = [ 0] u x u y u z u VRP 0 0 v M View@LookAt = x v y v z v VRP = 0 0 2 n x n y n z n VRP 0 0 [ ] [ ] Esta matriz é aplicada aos 3 objectos b) (2 valores) Indique o conteúdo da matriz MODEL enviado para o GLSL relativo ao desenho de cada um dos três objectos. 0 0 2 0 0 0 Objecto : MODEL: Identity * 0 0 2 Objecto 2: MODEL: Identity * 0 0 2 0 0 0 0 0 2.5 0 0 0 0.5 0 0 = 0 0.5 0.5 0 0 2 0.5 0 0 0 0.5 2
Objecto 3: tem o mesmo conteúdo que o objecto 4. Analise no final deste enunciado o trecho de código OpenGL bem como os respectivos programas, vertex shader e fragment shader, em código GLSL, versão 330. Considere que as componentes ambiente, difusa e especular da fonte de luz são unitárias nos três canais de cor RGB e que o vector lightpos contém coordenadas no referencial da câmara. a) (2 valores) Identifique o algoritmo de sombreamento utilizado por esta aplicação e justifique. Algoritmo de sombreamento de Phong. O cálculo da cor Blinn-Phong é realizado no fragmento shader, portanto ao nível do fragmento, utilizando as normais dos vértices (vertex shader) interpoladas. b) ( valor) Qual o tipo de fonte de luz que é usado neste programa? Porquê? Fonte de luz pontual pois a 4 componente do vector lightpos é. c) (2 valores) Em que referencial se encontra a informação da variável out DataOut? Justifique. No vertex shader são realizadas transformações para o referencial da câmara, ao nível do vector normal (uso de m_normal) e da posição do vértice (viewmodel) bem como o vector de observação (DataOut.eye) d) (2 valores) Qual a relação entre matriz de dimensão 3 guardada em m_normal e a matriz de dimensão 4 na m_viewmodel? Primeiro obtém-se a submatriz 3x3 da m_viewmodel (na prática elimina-se a última linha e a última coluna). Designe-se essa matriz por m_viewmodel3x3. Assim m_normal = ([m_viewmodel3x3] T ) - e) (2 valores) Porque razão a normal guardada na variável DataIn.normal é normalizada no fragment shader, uma vez que a mesma foi normalizada no vertex shader? Normaliza-se no vertex shader para garantir que o vector interpolado recebido no fragment shader tem a direcção correcta. Mas essa interpolação não garante vectores com o comprimento unitário pelo que se tem de realizar a respectiva normalização
f) (2 valores) Qual o referencial em que o pipeline OpenGL espera encontrar as coordenadas da variável pré-definida gl_position? Clip Coordinates. Para ser usado no algoritmo de recorte g) (2 valores) Assuma que para um determinado fragmento as direcções do vector l e do vector e fazem, ambas, com a normal n, um ângulo de 60 graus. Calcule qual o conteúdo da variável colorout para esta situação. O half-vector h = l + e logo h faz zero graus com a normal o que significa que dot(h,n) = cos 60 = 0.5 intensity*diffuse = [ 0 0 0.3 ] spec = [0 0 0.8 ]. intensity*diffuse + spec= [0.0 0.0..0] que será truncado para[0.0 0.0.0.0] colorout vai escolher o max deste vector e do ambiente pelo que colorout = [ 0.2 0.2.0.0] GLfloat lightpos[4] = {4.0f, 6.0f, 2.0f,.0f}; GLfloat mat_ambient[] = { 0.2 0.2, 0.5,.0 }; GLfloat mat_diffuse[] = { 0.0, 0.0, 0.6,.0 }; GLfloat mat_specular[] = { 0.0, 0.0, 0.8,.0 }; GLfloat mat_shininess= 00.0f; loc = glgetuniformlocation(p, l_pos ); gluniform4fv(loc,, lightpos); loc = glgetuniformlocation(p, "mat.ambient"); gluniform4fv(loc,, mat_ambient); loc = glgetuniformlocation(p, "mat.diffuse"); gluniform4fv(loc,, mat_diffuse); glgetuniformlocation(p, "mat.specular"); gluniform4fv(loc,, mat_specular); loc = glgetuniformlocation(p, "mat.shininess"); gluniformf(loc,mat_shininess); ------Vertex shader uniform mat4 m_pvm; // contém o produto: proj * view * model uniform mat4 m_viewmodel; // contém o produto: view * model uniform mat3 m_normal; // matriz a ser aplicada às normais uniform vec4 l_pos; // vector posição luz em eye coordinates in vec4 position; in vec4 normal; out Data { vec3 normal, eye, lightdir;} DataOut; void main () { } vec4 pos = m_viewmodel * position; DataOut.normal = normalize(m_normal * normal.xyz); DataOut.lightDir = vec3(l_pos - pos); DataOut.eye = vec3(-pos); gl_position = m_pvm * position; ------fragment shader
out vec4 colorout; struct Materials { vec4 diffuse, ambient, specular, emissive; float shininess; }; uniform Materials mat; in Data { vec3 normal, eye, lightdir;} DataIn; void main() { vec4 spec = vec4(0.0); vec3 n = normalize(datain.normal); vec3 l = normalize(datain.lightdir); vec3 e = normalize(datain.eye); float intensity = max(dot(n,l), 0.0); if (intensity > 0.0) { vec3 h = normalize(l + e); float intspec = max(dot(h,n), 0.0); spec = mat.specular * pow(intspec, mat.shininess); } colorout = max(intensity*mat.diffuse + spec, mat.ambient);