TA159

Notas, resueltos y trabajos practicos de la materia Sistemas Gráficos
Index Commits Files Refs Submodules README LICENSE
guias/pipeline.md (11618B)
   1 # El Pipeline Gráfico de WebGL
   2 
   3 Sistemas Gráficos (86.43) - 1C2024 - FIUBA  
   4 Martin J. Klöckner - [mklockner@fi.uba.ar](mailto:mklockner@fi.uba.ar)
   5 
   6 > 1. ¿Qué es el Pipeline Gráfico en el contexto de WebGL y Three.js?
   7 
   8 El pipeline gráfico hace referencia a la serie de procedimientos que hacen falta
   9 para renderizar un objeto 3D en la pantalla de una computadora, en el contexto
  10 de WebGL y Three.js, el objeto se renderiza en un navegador.
  11 
  12 ![principales etapas del pipeline gráfico junto con las entradas y salidas](./graphics-pipeline.png)
  13 
  14 En la figura anterior se puede ver una vista simplificada de las etapas del
  15 pipeline gráfico junto con las entradas y salidas del mismo.
  16 
  17 > 2. ¿Cuáles son las etapas principales del Pipeline Gráfico?
  18 
  19 Las etapas principales del Pipeline Gráfico son el procesamiento de vertices
  20 ("vertex shader"), la etapa de pasterización y la etapa de procesamiento de
  21 fragmentos ("fragment shader" o "pixel shader").
  22 
  23 > 3. ¿Qué función desempeña el "vertex shader" en el proceso de renderizado?
  24 
  25 El procesador de vertices o "vertex shader" se encarga de aplicar
  26 transformaciones a cada uno de los vertices, la principal tarea es transformar
  27 la posición 3D del vértice en una posición 2D en el plano virtual que se
  28 mostrara en pantalla, así como también obtener la profundidad y almacenarla en
  29 el `z-buffer`.[^1]
  30 
  31 [^1]: [“Shader” Wikipedia, The Free Encyclopedia, 2 Mar 2024.](https://en.wikipedia.org/w/index.php?title=Shader)
  32 
  33 Los "vertex shader" pueden manipular propiedades del vértice como la posición,
  34 el color o las coordenadas de la textura, no pueden crear nuevos vértices.
  35 
  36 > 4. ¿Cómo se define un vertex shader en GLSL, cuáles son las salidas mínimas 
  37 >    necesarias (que valores debe retornar obligatoriamente)?
  38 
  39 En GLSL el trabajo mínimo de un vertex shader es asignar a la variable
  40 especial `gl_Position` un vector de 4 dimensiones (x, y, z, w). Esta variable
  41 luego será entregada a la siguiente etapa del pipeline gráfico.[^2]
  42 
  43 [^2]: ["A Primer on Shaders", Learn WebGL, Wayne Brown, 2015.](http://learnwebgl.brown37.net/rendering/shader_primer.html)
  44 
  45 Una implementación en GLSL del vertex shader más básico para renderizar un objeto
  46 se puede ver a continuación:
  47 
  48 ```glsl
  49 // Vertex Shader
  50 uniform   mat4 u_Transform;
  51 uniform   vec4 u_Color;
  52 attribute vec3 a_Vertex;
  53 
  54 void main() {
  55     // Transforma la posicion del vertice
  56     gl_Position = u_Transform * vec4(a_Vertex, 1.0);
  57 }
  58 ```
  59 
  60 El vertex shader se debe encargar de aplicar las transformaciones necesarias al
  61 objeto para transformarlo del espacio de modelado a espacio de pantalla. Para
  62 eso realiza un cambio de base multiplicando por la matriz de modelado, vista,
  63 proyección y finalmente de viewport.
  64 
  65 > 5. ¿Qué datos se pueden pasar al vertex shader a través de atributos?
  66 
  67 Los atributos que se pueden pasar al "vertex shader" se denominan "vertex
  68 attributes" y pueden contener por ejemplo posiciones, normales o coordenadas de
  69 textura.
  70 
  71 > 6. ¿Qué es una variable uniform en el contexto de shaders?
  72 
  73 En GLSL una variable `uniform` es una variable de alcance global la cual se
  74 puede utilizar para recibir parámetros del programa que utiliza el shader.[^3]
  75 El valor de las variables de tipo `uniform` se almacena en el propio objeto
  76 compilado del shader.[^4]
  77 
  78 [^3]: ["GLSL Object" OpenGL Wiki, 2015.](https://www.khronos.org/opengl/wiki/GLSL_Object)
  79 [^4]: ["Uniform (GLSL)" OpenGL Wiki, 2015.](https://www.khronos.org/opengl/wiki/Uniform_(GLSL))
  80 
  81 Las variables de tipo `uniform` se denominan así porque no cambian entre las
  82 diferencias instancias de la ejecución del shader. Recordemos que en el caso de
  83 los "vertex shaders", por ejemplo, se ejecuta una instancia del shader por cada
  84 vértice. Las variables `uniform` se diferencian de otras variables como las de
  85 entrada y salida de cada etapa, las cuales por lo general cambian en cada
  86 invocación del shader.
  87 
  88 Un ejemplo común de utilización de variables uniform es para informar al shader
  89 del variables constantes, o que permanecerán constantes en la ejecución del
  90 shader, por ejemplo el tiempo, ya que durante la ejecución del shader la
  91 variable permanecerá constante y no cambiará, quizás en la próxima iteración
  92 cambie o quizás no, pero eso es ajeno al alcance del shader, si no más bien
  93 depende de quien lo invoca.
  94 
  95 > 7. ¿Cuál es la diferencia entre un vertex shader y un fragment shader?
  96 
  97 La diferencia entre "fragment shader" y "vertex shader" es
  98 que el trabajo del primero es asignar un color a cada fragmento, mientras que el
  99 trabajo del segundo es, como vimos previamente, aplicar transformaciones a cada
 100 vértice.
 101 
 102 Recordemos que un "fragmento" es el conjunto de un pixel y toda su información
 103 necesaria para ser renderizado. 
 104 
 105 > 8. ¿Cómo se almacenan los valores de color de cada pixel en el fragment
 106 >    shader?
 107 
 108 En el fragment shader se almacenan en la variable `gl_FragColor`
 109 
 110 ```glsl
 111 // Fragment shader
 112 uniform vec4 u_Color;
 113 
 114 void main() {
 115   gl_FragColor = u_Color;
 116 }
 117 ```
 118 
 119 > 9. ¿Qué es un `sampler2D` y cómo se utiliza en un fragment shader?
 120 
 121 Un sampler en GLSL es un tipo de variable especial que se utiliza par acceder a
 122 una textura desde un shader. En particular `sampler2D` es un tipo especial de
 123 sampler que se utiliza para acceder o almacenar texturas bidimensionales desde
 124 un shader.
 125 
 126 > 10. ¿Cuál es el propósito del rasterizador en el Pipeline Gráfico?
 127 
 128 El rasterizador se encarga de convertir cada primitiva (generada en la etapa de
 129 "vertex post-processing") en un fragmentos, para luego ser enviados al "fragment
 130 shader".[^5]
 131 
 132 [^5]: ["Rendering Pipeline Overview" OpenGL Wiki, 2022.](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview)
 133 
 134 Un fragmento es un conjunto de estados que se utiliza para computar la salida de
 135 un pixel (o `sample` si se utiliza `multisampling`) en el `framebuffer`. Este
 136 conjunto de estados para un fragmento incluye la posición en el espacio de
 137 pantalla y una lista de datos arbitrarios provenientes de etapas previas del
 138 pipeline gráfico, como el "vertex shader". 
 139 
 140 Este ultimo conjunto de datos se computa para cada fragmento mediante la
 141 interpolación de los valores de los vertices. El método de interpolación queda
 142 definido por el shader que procesó esos datos.
 143 
 144 > 11. ¿Cuál es la función principal de la GPU en el Pipeline Gráfico?
 145 
 146 La GPU se encarga de la mayor parte del pipeline gráfico, ya que procesa desde
 147 el "vertex shader" hasta el renderizado de la imagen en pantalla. La GPU obtiene
 148 los píxeles a procesar en el vertex shader de su propia memoria, la cual es
 149 distinta de la memoria del CPU, es el CPU el que se encarga de enviar los
 150 píxeles a renderizar a la memoria de la GPU.
 151 
 152 > 12. ¿Cómo se extrae un valor de una textura en un fragment shader?
 153 
 154 Para obtener un valor de una textura en un fragment shader, primero se debe
 155 tener acceso a la misma mediante un `sampler`, como se mencionó previamente,
 156 luego se puede utilizar la función `texture`, la cual obtiene el valor de la
 157 textura para las coordinas pedidas. Como se muestra en el siguiente ejemplo de
 158 "fragment shader":
 159 
 160 ```glsl
 161 uniform sampler2D myTexture; // Sampler asociado a la textura 2D
 162 
 163 void main() {
 164     vec2 textureCoordinates = vec2(0.5, 0.5);
 165     vec4 texelColor = texture(myTexture, textureCoordinates);
 166     gl_FragColor = texelColor;
 167 }
 168 ```
 169 
 170 > 13. ¿Qué son las variables varying en el contexto de los shaders?
 171 
 172 Las variables declaradas de tip `varying` son aquellas que cambian para cada
 173 fragmento. Se utilizan para pasar datos interpolados entre las diferentes etapas
 174 del pipeline gráfico, como el "vertex shader" y el "fragment shader".
 175 
 176 A la variable se le asigna un valor en el "vertex shader" y es automáticamente
 177 interpolado a lo largo de la superficie de una primitiva (por ejemplo la
 178 superficie de un triangulo) antes de que llegue al "fragment shader". El valor
 179 puede ser usado por el "fragment shader" pero no cambiado ya que el propósito
 180 de estas variable es que sea interpolado automáticamente
 181 
 182 > 14. ¿Qué información se comparte entre el vertex shader y el fragment shader a
 183 >     través de las variables varying? 
 184 
 185 Como se menciono antes las variables de tipo `varying` son aquellas que se
 186 interpolan automáticamente a los largo de la superficie de una primitiva.
 187 Algunos ejemplos de datos que se pueden interpolar son colores, coordenadas
 188 de textura o coordenadas de vectores normales.
 189 
 190 > 15. ¿Cómo se realiza la interpolación de valores de los vértices en un
 191 >     fragment shader?
 192 
 193 En un fragment shader, la interpolación de valores de los vértices se realiza
 194 automáticamente por el hardware gráfico durante el proceso de rasterización.
 195 
 196 > 16. ¿Qué es la matriz de vista?
 197 
 198 La matriz de vista se utiliza para transformar los objetos desde su sistema de
 199 coordenadas del mundo al sistema de coordenas de cámara.
 200 
 201 La matriz de vista se utiliza para definir la posición y orientación de la
 202 cámara en relación con los objetos en la escena, simulando así el punto de vista
 203 desde el cual se está observando la escena.
 204 
 205 > 17. ¿Qué es la matriz de modelado?
 206 
 207 La matriz de modelado se utiliza para transformar cada objeto desde sus sistema
 208 de coordenadas de modelado a un sistema de coordenadas de mundo.
 209 
 210 El sistema de coordenadas de modelado, o espacio de modelado, es un sistema en
 211 el cual el objeto esta posicionado en un cero arbitrario (definido por el
 212 diseñador). Cada objeto se modela por separado, por lo que cada objeto posee su
 213 propio espacio de modelado. Mediante la matriz de vista, se posiciona cada
 214 objeto con respecto a un sistema de coordenada común. 
 215 
 216 > 18. ¿Qué es la matriz de proyección?
 217 
 218 La matriz de proyección se utiliza para transformar los objetos de espacio de
 219 cámara a un espacio normalizado entre `(-1.0; 1.0)`
 220 
 221 > 19. ¿Cómo se crea la matriz de transformación de la vista a partir de la
 222 >     posición y orientación de la cámara?
 223 
 224 La matriz de vista transforma de coordenadas de mundo a coordenadas de cámara,
 225 en el espacio de cámara, la cámara se posiciona en el origine y todos los
 226 objetos relativos a esta.
 227 
 228 En `three.js` se puede construir la matriz de vista de la siguiente forma:
 229 
 230 ```js
 231 var viewMatrix = mat4.create();
 232 mat4.lookAt(viewMatrix, cameraPosition, target, [0, 1, 0]);
 233 ```
 234 
 235 > 20. ¿Cómo se transforman las normales en un vertex shader para mantener su
 236 >     coherencia durante las transformaciones de modelo y vista?
 237 
 238 > 21. ¿Cuál es la diferencia entre `gl.LINE_STRIP` y `gl.LINE_LOOP` al dibujar
 239 >     líneas en WebGL?
 240 
 241 > 22. ¿Cómo se dibuja una línea entre un par de vértices utilizando el modo
 242 >     `gl.LINES`? De un ejemplo
 243 
 244 > 23. ¿Cuál es el propósito de `gl.TRIANGLE_FAN` y cómo difiere de
 245 >     `gl.TRIANGLES`? Ejemplifique
 246 
 247 > 24. ¿Qué ocurre cuando se utiliza `gl.TRIANGLE_STRIP` en lugar de
 248 >     `gl.TRIANGLES`? de un ejemplo
 249 
 250 > 25. ¿Cuál es el papel del rasterizador en la transformación de primitivas en
 251 >     píxeles?
 252 
 253 > 26. ¿Cuál es el papel de los núcleos (cores) en una GPU y cómo se organizan?
 254 
 255 > 27. ¿Qué es la memoria de video (VRAM) y cómo se diferencia de la memoria RAM
 256 >     convencional?
 257 
 258 > 28. ¿Cómo se gestionan las variables `uniforms` en un shader y cuál es su
 259 >     propósito?
 260 
 261 > 30. ¿Cómo se puede optimizar el rendimiento en WebGL al minimizar el número de
 262 >     llamadas al pipeline gráfico?
 263 
 264 > 31. ¿Qué papel desempeña el atributo `gl_Position` en un vertex shader y cómo
 265 >     afecta el resultado final del renderizado?
 266 
 267 > 32. ¿Cuál es la diferencia entre el mapeo de texturas en coordenadas UV y
 268 >     coordenadas de proyección en un fragment shader?