texto
(Copió una imagen a mano)
Los modelos de iluminación Phong y Blinn-Phong se utilizan para lograr el efecto de la luz que brilla sobre el objeto, y el rendimiento del objeto produce una parte destacada. Los dos modelos también son muy similares. Después de todo, el último es una optimización computacional de la ex. Aunque los dos modelos de iluminación tienen un paquete de funciones de código listo para usar, especialmente el complemento shaderforge y la nueva versión del shadergraph de la unidad, puede arrastrar y soltar directamente algunos controles gráficos para lograr las dos luces. El efecto del modelo es simplemente demasiado. Pero después de comprender el principio, no me sentiré vacío cuando otros me pregunten.
Modelo de iluminación Phong
Idealmente, la luz emitida por la fuente de luz se refleja en el espejo y se observa en la dirección de la luz reflejada. El observador puede recibir la mayor cantidad de luz reflejada. Luego, el ángulo entre el observador y la dirección reflejada determina la cantidad de luz que se puede iluminar. observado. Cuanto mayor sea el ángulo, menor será el resaltado y cuanto menor sea el ángulo, mayor será el resaltado. Otro factor que afecta el tamaño de la iluminación es la suavidad de la superficie: cuanto más suave es la superficie, más intensa es la iluminación, más rugosa y más débil la iluminación. L representa la dirección de la fuente de luz, N representa la dirección normal del vértice, V representa la dirección del observador y R representa la dirección de la luz reflejada. Primero, se debe calcular la dirección R de la luz reflejada. La dirección R de la luz reflejada se puede obtener a partir de la dirección de la luz incidente y el vector normal, R + L = 2dot (N, L) N, y luego R = 2 puntos (N, L) NL. (En cuanto a cómo calcular esta fórmula, hay muchos blogs en CSDN que tienen notas, que es una conversión simple de función vectorial y trigonométrica. Si no lo entiende, puede descargarlo en Baidu o leerlo directamente aquí )
(Copie otra imagen a mano)
Modelo de iluminación Blinn-Phong
El modelo de iluminación Phong puede realizar el efecto de iluminación muy bien, pero la desventaja de la iluminación Blinn-Phong es que es computacionalmente costosa. Por lo tanto, en 1977, Jim Blinn mejoró la iluminación Phong y la llamó modelo de iluminación Blinn-Phong.
La iluminación Blinn-Phong introduce un concepto, vector de medio ángulo, representado por H. El vector de medio ángulo es fácil de calcular. El vector de medio ángulo se puede obtener normalizando la suma de la dirección L de la fuente de luz y la dirección V de la línea de visión. La iluminación Phong compara el ángulo entre la dirección de reflexión R y la dirección de la línea de visión V, mientras que Blinn-Phong compara el ángulo entre el vector de medio ángulo H y la dirección normal N en su lugar. La complejidad de cálculo del vector de medio ángulo es mucho más simple que el cálculo de la luz reflejada, por lo que el rendimiento de Blinn-Phong es mucho mayor y el efecto es similar al de la fotografía de luz Phong, por lo que el modelo de iluminación de la tubería fija en OpenGL es el modelo de iluminación Blinn-Phong.
La fórmula de cálculo del modelo de iluminación BlinnPhong es la siguiente:
I (spcular) = I * k * pow (max (0, dot (N, H)), brillo), donde I es el vector de color de la luz incidente, k es el coeficiente de reflexión especular y el brillo es el grado de suavidad.
================================================ ================
Pegue el código de shaderlab de los dos modelos de iluminación a continuación
Shader "Custom/Phong" {
Properties{
_Specular("Specular", Color) = (1,1,1,1)
_Diffuse("Diffuse",Color) = (1,1,1,1)
_Gloss("Gloss",Range(1,255)) = 10
}
SubShader{
Pass{
Tags {"LightMode" = "ForwardBase" }
LOD 200
CGPROGRAM
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos:SV_POSITION;
float3 worldNormal:NORMAL;
float3 worldPos:TEXCOORD1;
};
v2f vert(a2v v)
{
v2f o;
//矩阵变换 获取投影坐标下的顶点
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
//获取世界坐标下的法线坐标
o.worldNormal = normalize(mul(v.normal, (float3x3)_World2Object));
//o.worldNormal=normalize(mul((float3x3)_Object2World,v.normal));//与上面等价
o.worldPos = mul(_Object2World, v.vertex).xyz;
return o;
}
fixed4 frag(v2f i) :SV_Target
{
//获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*_Diffuse;
//获取灯光方向 并归一化
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
//归一化世界坐标下的法线
fixed3 worldNormal = normalize(i.worldNormal);
//获取漫反射
fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLight));
//获取反射光的方向 入射光方向为-worldLight,通过reflect函数获取反射光方向
fixed3 reflectDir = normalize(reflect(-worldLight, worldNormal));
//获取点在摄像机的观察位置,并归一化 (相机坐标-像素位置)
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
//phong的高光公式
fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0, dot(reflectDir, viewDir)), _Gloss);
fixed3 color = diffuse + ambient + specular;
return fixed4(color, 1.0);
}
ENDCG
}
}
FallBack "Specular"
}
================================================ ====================
Shader "Custom/Blinn_Phong" {
Properties{
_Specular("Specular",color) = (1,1,1,1)
_Diffuse("Diffuse",color) = (1,1,1,1)
_Gloss("Gloss",Range(1,100)) = 20
}
SubShader{
Pass{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#include "Lighting.cginc"
#pragma vertex vert
#pragma fragment frag
float3 _Specular;
float3 _Diffuse;
float _Gloss;
struct a2v {
float4 vertex:POSITION;
float3 normal:NORMAL;
};
struct v2f {
float4 pos:SV_POSITION;
float3 worldNormal:NORMAL;
float3 worldPos:TEXCOORD0;
};
v2f vert(a2v a)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, a.vertex);
o.worldNormal = mul(_Object2World, a.normal);
o.worldPos = mul(_Object2World, a.vertex).xyz;
return o;
}
float4 frag(v2f i):SV_Target
{
//获取环境光
float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*_Diffuse;
//获取灯光 并且归一化
float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
//获取法线并归一化
float3 worldNormal = normalize(i.worldNormal);
//获取视线方向(摄像头位置-像素对应位置) 并归一化
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
//获取漫反射灯光
float3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLight));
//获取半角向量(光线方向+视线方向) 并归一化
float3 halfDir = normalize(worldLight + viewDir);
//高光公式
float3 specular = _LightColor0.rgb*_Specular.rgb*pow(saturate(dot(halfDir, worldNormal)),_Gloss);
float3 color = ambient + diffuse + specular;
return float4(color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}
================================================ =====================================
Algunos códigos clave ya están comentados en el código, por lo que no los repetiré demasiado. Y Blinn-Pong introduce un vector de medio ángulo para reemplazar el vector reflejado, por lo que la cantidad de cálculo del sombreador es mucho menor El siguiente es un resumen directo del código de sombreado de Blinn-Phong.
Sombreador de iluminación Blinn-Pong
Consulte el modelo de iluminación "Lighting.cginc"
Definir la estructura a2v para obtener los vértices y las normales del modelo.
Definir la estructura v2f y almacenar la información del vértice (SV_POSITION) La normal mundial y la posición del vértice en la coordenada mundial
Necesito entrar en la función de vértice
Coordenadas de proyección de vértices
Vertex world normal
Coordenadas mundiales de vértices
Necesito entrar en la función de fragmento
Luz ambiental, es necesario multiplicar la luz ambiental en el modelo de iluminación (UNITY_LIGHTMODEL_AMBIENT.xyz) con Difusa
Mundo normalizado normal
Posición de luz normalizada (_WorldSpaceLightPos0.xyz)
La posición del ángulo de visión del punto normalizado (_WorldSpaceCameraPos.xyz-worldPos)
漫 反射 (_LightColor0.rgb * Diffuse.rgb * saturate (dot (worldNormal, lightDir)))
Vector de medio ángulo normalizado (viewDir + lightDir)
La fórmula de resaltado final LightColor0.rbg * _Specular.rbg * pow (dot (halfDir, worldNormal), _ Gloss)
Volver a resaltar + luz ambiental + luz difusa
para resumir
Estos dos modelos de iluminación en realidad tienen un nombre chino, a saber, modelo Feng Guangzhao y modelo Brin-Feng Guangzhao, pero después de cambiar al chino, se siente muy confuso. Desde la perspectiva de la comprensión, el modelo Phong puede sacar conclusiones de manera más intuitiva, y no sé cómo calcular un vector de medio ángulo de este último, pero siento que el código es mucho más simple sin una operación de multiplicación de puntos. sentimiento de posteridad.
Llevo casi un año perezoso y solo recientemente tuve tiempo de sofocar este entendimiento personal Parece que perseverancia es todavía una palabra que no es fácil de realizar. Aunque suelo tener la costumbre de tomar notas, siento que después de tomar notas, las pongo ahí. Después de mucho tiempo, básicamente me olvido de todo. Tarda mucho en darme cuenta después de mirar hacia atrás. De esta manera, escribir un blog es un recuerdo de mí mismo. Revisémoslo y esperamos seguir manteniéndolo. . .