El modelo de reflexión Blinn-Phong , también llamado modelo de reflexión Phong modificado, es una modificación desarrollada por Jim Blinn al modelo de reflexión Phong . [1]
Blinn – Phong es el modelo de sombreado predeterminado utilizado en la canalización de funciones fijas de OpenGL y Direct3D (antes de Direct3D 10 y OpenGL 3.1), y se lleva a cabo en cada vértice a medida que pasa por la canalización de gráficos ; Los valores de píxeles entre vértices se interpolan mediante el sombreado Gouraud de forma predeterminada, en lugar del sombreado Phong, más costoso desde el punto de vista computacional . [2]
Descripción
En el sombreado Phong, uno debe recalcular continuamente el producto escalar. entre un espectador ( V ) y el haz de una fuente de luz ( L ) reflejada ( R ) en una superficie.
Si, en cambio, se calcula un vector a medio camino entre el visor y los vectores de fuente de luz,
puede ser reemplazado con , dónde es la superficie normalizada normal. En la ecuación anterior, y son ambos vectores normalizados, y es una solución a la ecuación dónde es la matriz Householder que refleja un punto en el hiperplano que contiene el origen y tiene el valor normal
Este producto escalar representa el coseno de un ángulo que es la mitad del ángulo representado por el producto escalar de Phong si V , L , N y R se encuentran en el mismo plano. Esta relación entre los ángulos permanece aproximadamente verdadera cuando los vectores no se encuentran en el mismo plano, especialmente cuando los ángulos son pequeños. Por lo tanto, el ángulo entre N y H a veces se denomina ángulo medio.
Considerando que es probable que el ángulo entre el vector medio y la normal de la superficie sea menor que el ángulo entre R y V usado en el modelo de Phong (a menos que la superficie se vea desde un ángulo muy pronunciado para el cual es probable que sea más grande), y ya que Phong está usandose puede establecer un exponente tal que está más cerca de la expresión anterior.
Para superficies con iluminación frontal (reflejos especulares en superficies que miran al espectador), dará como resultado reflejos especulares que se asemejan mucho a los reflejos Phong correspondientes. Sin embargo, mientras que los reflejos de Phong son siempre redondos para una superficie plana, los reflejos de Blinn-Phong se vuelven elípticos cuando la superficie se ve desde un ángulo pronunciado. Esto se puede comparar con el caso donde el sol se refleja en el mar cerca del horizonte, o donde una farola lejana se refleja en el pavimento mojado, donde el reflejo siempre será mucho más extendido verticalmente que horizontalmente. [3]
Además, aunque puede verse como una aproximación al modelo de Phong, produce modelos más precisos de funciones de distribución de reflectancia bidireccional determinadas empíricamente que Phong para muchos tipos de superficies. [4]
Eficiencia
Blinn-Phong será más rápido que Phong en el caso de que el espectador y la luz sean tratados como muy remotos, como acercándose o en el infinito. Este es el caso de las luces direccionales y las cámaras ortográficas / isométricas. En este caso, el vector de mitad de camino es independiente de la posición y la curvatura de la superficie simplemente porque el vector de mitad de camino depende de la dirección a la posición del espectador y la dirección a la posición de la luz, que convergen individualmente a esta distancia remota, por lo tanto, se puede pensar en el vector de mitad de camino. de como constante en este caso.por lo tanto, puede calcularse una vez para cada luz y luego usarse para todo el marco, o incluso mientras la luz y el punto de vista permanecen en la misma posición relativa. No ocurre lo mismo con el método de Phong de utilizar el vector de reflexión que depende de la curvatura de la superficie y debe recalcularse para cada píxel de la imagen (o para cada vértice del modelo en el caso de la iluminación de vértices). En escenas 3D con cámaras en perspectiva, esta optimización no es posible.
Muestras de código
Ejemplo de código de lenguaje de sombreado de alto nivel
Esta muestra de High-Level Shading Language es un método para determinar la luz difusa y especular de un punto de luz. Se atraviesa la estructura de luz, la posición en el espacio de la superficie, el vector de dirección de la vista y la normal de la superficie. Se devuelve una estructura de iluminación;
Lo siguiente también debe fijar ciertos productos punto a cero en el caso de respuestas negativas. Sin eso, la luz que se aleja de la cámara se trata de la misma manera que la luz que se dirige hacia ella. Para el cálculo especular, un "halo" incorrecto de luz que rebasa los bordes de un objeto y se aleja de la cámara puede parecer tan brillante como la luz que se refleja directamente hacia la cámara.
struct Lighting { float3 Diffuse ; float3 Specular ; };struct PointLight { posición flotante3 ; float3 diffuseColor ; float diffusePower ; float3 specularColor ; float specularPower ; }; Iluminación GetPointLight ( luz PointLight , float3 pos3D , float3 viewDir , float3 normal ) { Iluminación FUERA ; if ( light . diffusePower > 0 ) { float3 lightDir = light . posición - pos3D ; // Posición 3D en el espacio de la superficie flotante distancia = longitud ( lightDir ); lightDir = lightDir / distancia ; // = normalizar (lightDir); distancia = distancia * distancia ; // Esta línea se puede optimizar usando la raíz cuadrada inversa // Intensidad de la luz difusa. Saturar para mantenerse dentro del rango 0-1. flotar NdotL = punto ( normal , lightDir ); intensidad de flotación = saturar ( NdotL ); // Calcula la luz difusa factorizando el color de la luz, la potencia y la atenuación OUT . Difusa = intensidad * luz . diffuseColor * luz . diffusePower / distancia ;// Calcula el medio vector entre el vector de luz y el vector de vista. // Esto suele ser más lento que calcular el vector de reflexión real // debido a la raíz cuadrada recíproca de la función de normalización float3 H = normalize ( lightDir + viewDir );// Intensidad del flotador de luz especular NdotH = dot ( normal , H ); intensidad = pow ( saturar ( NdotH ), dureza especular );// Suma la factorización de la luz especular OUT . Especular = intensidad * luz . specularColor * claro . specularPower / distancia ; } return OUT ; }
Ejemplo de código de lenguaje de sombreado de OpenGL
Esta muestra en OpenGL Shading Language consta de dos archivos de código o sombreadores . El primero es un llamado sombreador de vértices e implementa el sombreado Phong , que se utiliza para interpolar la normal de la superficie entre los vértices. El segundo sombreador es el llamado sombreador de fragmentos e implementa el modelo de sombreado Blinn-Phong para determinar la luz difusa y especular de una fuente de luz puntual.
Sombreador de vértices
Este sombreador de vértices implementa el sombreado Phong :
atributo vec3 inputPosition ; atributo vec2 inputTexCoord ; atributo vec3 inputNormal ; proyección uniforme mat4 , modelview , normalMat ; variando vec3 normalInterp ; variando vec3 vertPos ;void main () { gl_Position = proyección * modelview * vec4 ( inputPosition , 1.0 ); vec4 vertPos4 = modelview * vec4 ( inputPosition , 1.0 ); vertPos = vec3 ( vertPos4 ) / vertPos4 . w ; normalInterp = vec3 ( normalMat * vec4 ( inputNormal , 0.0 )); }
Sombreador de fragmentos
Este sombreador de fragmentos implementa el modelo de sombreado Blinn – Phong [5] y la corrección de gamma :
flotador mediump de precisión ;en vec3 normalInterp ; en vec3 vertPos ; modo int uniforme ;const vec3 lightPos = vec3 ( 1.0 , 1.0 , 1.0 ); const vec3 lightColor = vec3 ( 1.0 , 1.0 , 1.0 ); const float lightPower = 40.0 ; const vec3 ambientColor = vec3 ( 0.1 , 0.0 , 0.0 ); const vec3 diffuseColor = vec3 ( 0.5 , 0.0 , 0.0 ); const vec3 specColor = vec3 ( 1.0 , 1.0 , 1.0 ); brillo constante del flotador = 16,0 ; const float screenGamma = 2,2 ; // Suponga que el monitor está calibrado al espacio de color sRGB void main () { vec3 normal = normalizar ( normalInterp ); vec3 lightDir = lightPos - vertPos ; distancia de flotación = longitud ( lightDir ); distancia = distancia * distancia ; lightDir = normalizar ( lightDir ); flotar lambertian = max ( punto ( lightDir , normal ), 0.0 ); flotar especular = 0.0 ; si ( lambertiano > 0.0 ) { vec3 viewDir = normalizar ( - vertPos ); // esto es blinn phong vec3 halfDir = normalize ( lightDir + viewDir ); flotador specAngle = max ( punto ( halfDir , normal ), 0.0 ); specular = pow ( specAngle , brillo ); // esto se Phong (para comparación) si ( modo == 2 ) { vec3 reflectDir = reflejan ( - lightDir , normales ); specAngle = max ( punto ( reflectDir , viewDir ), 0.0 ); // note que el exponente es diferente aquí specular = pow ( specAngle , shininess / 4.0 ); } } vec3 colorLinear = ambientColor + diffuseColor * lambertian * lightColor * lightPower / distancia + specColor * specular * lightColor * lightPower / distancia ; // aplicar corrección de gamma (asumir ambientColor, diffuseColor y specColor // han sido linealizados, es decir, no tienen corrección de gamma) vec3 colorGammaCorrected = pow ( colorLinear , vec3 ( 1.0 / screenGamma )); // usa el color corregido por gamma en el fragmento gl_FragColor = vec4 ( colorGammaCorrected , 1.0 ); }
Los colores ambientColor , diffuseColor y No se supone que specColor se corrija por gamma . Si son colores obtenidos de archivos de imagen con corrección de gamma ( JPEG , PNG , etc.), deben linealizarse antes de trabajar con ellos, lo que se hace escalando los valores del canal al rango [0, 1] y elevándolos a el valor gamma de la imagen, que para las imágenes en el espacio de color sRGB se puede suponer que es de aproximadamente 2,2 (aunque para este espacio de color específico, una relación de potencia simple es solo una aproximación de la transformación real ). Las API de gráficos modernas tienen la capacidad de realizar esta corrección gamma automáticamente cuando se muestrea una textura o se escribe en un búfer de fotogramas . [6]
Ver también
- Lista de algoritmos de sombreado comunes
- Modelo de reflexión de Phong para el modelo correspondiente de Phong
- Corrección gamma
- Destacado espectacular
Referencias
- ^ James F. Blinn (1977). "Modelos de reflexión de luz para imágenes sintetizadas por computadora". Proc. 4ª conferencia anual sobre gráficos por ordenador y técnicas interactivas : 192–198. CiteSeerX 10.1.1.131.7741 . doi : 10.1145 / 563858.563893 .
- ^ Shreiner, Dave; El Grupo de Trabajo de Khronos OpenGL ARB (2010). "Las Matemáticas de la Iluminación". Guía de programación de OpenGL: la guía oficial para aprender OpenGL, versión 3.0 y 3.1 (7ª ed.). Pearson Education, Inc. págs. 240–245. ISBN 978-0-321-55262-4.
- ^ Krus, Kristofer (2014), Modelo de olas y modelo de embarcación para la simulación del estado del mar , Universidad de Linköping , p. 97
- ^ Ngan, Addy; Durand, Frédo; Matusik, Wojciech (2004). "Validación experimental de modelos analíticos BRDF" . ACM SIGGRAPH 2004 Bocetos en - SIGGRAPH '04 . Prensa ACM. doi : 10.1145 / 1186223.1186336 . Consultado el 23 de abril de 2019 .
- ^ "Ejemplo de WebGL: Phong / Blinn Phong Shading" . www.mathematik.uni-marburg.de . Consultado el 13 de septiembre de 2019 .
- ^ https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_framebuffer_sRGB.txt