Estoy trabajando en un motor similar a Minecraft como un proyecto de pasatiempo para ver hasta qué punto el concepto de terrenos de voxel se puede impulsar en hardware moderno y OpenGL> = 3. Por lo tanto, toda mi geometría consiste en cuadrículas o casillas preciso.¿Cómo hacer la interpolación bilineal de normales en un quad?
He construido un raycaster para estimar la oclusión ambiental, y uso la técnica de "normales doblados" para hacer la iluminación. Entonces mis normales no son perpendiculares al quad, ni tienen longitud de unidad; más bien, señalan aproximadamente hacia el espacio donde está ocurriendo la menor oclusión, y son más cortos cuando el cuadrante recibe menos luz. La ventaja de esta técnica es que solo requiere un cálculo de una vez de la oclusión, y es esencialmente libre en el tiempo de renderizado.
Sin embargo, me encuentro con problemas cuando trato de asignar diferentes normales a diferentes vértices del mismo quad para obtener una iluminación suave. Debido a que el quad se divide en triángulos, y la interpolación lineal ocurre sobre cada triángulo, el resultado de la interpolación muestra claramente la presencia de los triángulos como artefactos diagonales feas:
El problema es que OpenGL utiliza barycentric interpolación sobre cada triángulo, que es una suma ponderada en 3 de las 4 esquinas. Idealmente, me gustaría utilizar la interpolación bilineal, donde las 4 esquinas se utilizan para calcular el resultado.
puedo pensar en algunas soluciones:
Stuff las normales en una textura 2x2 RGB, y dejar que el procesador de la textura de hacer la interpolación bilineal. Esto ocurre a costa de una búsqueda de textura en el sombreador de fragmentos. También necesitaría empacar todas estas mini texturas en más grandes para mayor eficiencia.
Utilice los atributos de vértice para unir las 4 normales a cada vértice. También adjunte algunos coeficientes [0..1] a cada vértice, al igual que las coordenadas de textura, y realice la interpolación bilineal en el sombreador de fragmentos. Esto ocurre a costa de pasar 4 normales al sombreado en lugar de sólo 1.
creo que estas dos técnicas se pueden hacer para trabajar, pero me parece que sea kludges para algo que debería ser mucho más simple. Tal vez podría transformar las normales de alguna manera, de modo que la interpolación de OpenGL daría un resultado que no depende de la triangulación particular utilizada.
(Tenga en cuenta que el problema no es específico de las normales, sino que es igualmente aplicable a los colores o cualquier otro valor que debe ser interpolado suavemente a través de un quad.)
¿Alguna idea de qué otra manera de abordar este problema? Si no, ¿cuál de las dos técnicas anteriores sería la mejor?
No quiero aumentar la densidad de malla, ya que estoy tratando de expulsar la mayor cantidad de bloques posible. Sé cómo interpolar texturas por mi cuenta, pero no quiero almacenar mis normales en una textura si puedo evitarlo, ¡de ahí esta pregunta! – Thomas