Text
(Bild von Hand kopiert)
Sowohl das Phong- als auch das Blinn-Phong-Beleuchtungsmodell werden verwendet, um den Effekt des auf das Objekt strahlenden Lichts zu erzielen, und die Objektleistung erzeugt einen Highlight-Teil. Die beiden Modelle sind auch sehr ähnlich. Letzteres ist schließlich eine rechnerische Optimierung des ehemalige. Obwohl die beiden Beleuchtungsmodelle über eine vorgefertigte Codefunktionsverpackung verfügen, insbesondere das Shaderforge-Plug-In und die neue Version des Shadergraphen der Einheit, können Sie einige grafische Steuerelemente direkt ziehen und ablegen, um die beiden Beleuchtungsmodelle zu erzielen. Der Modelleffekt ist einfach zu viel. Aber nachdem ich das Prinzip verstanden habe, fühle ich mich nicht leer, wenn ich von anderen gefragt werde.
Phong Beleuchtungsmodell
Idealerweise wird das von der Lichtquelle emittierte Licht vom Spiegel reflektiert und in Richtung des reflektierten Lichts beobachtet. Der Betrachter kann das am meisten reflektierte Licht empfangen. Dann bestimmt der Winkel zwischen dem Betrachter und der reflektierten Richtung, wie viel Glanzlichter sein können beobachtet. Je größer der Winkel, desto kleiner die Hervorhebung und je kleiner der Winkel, desto größer die Hervorhebung. Ein weiterer Faktor, der die Größe des Glanzlichts beeinflusst, ist die Glätte der Oberfläche. Je glatter die Oberfläche, desto stärker das Glanzlicht, desto rauer die Oberfläche und desto schwächer das Glanzlicht. L repräsentiert die Lichtquellenrichtung, N repräsentiert die Scheitelpunktnormalenrichtung, V repräsentiert die Beobachterrichtung und R repräsentiert die Richtung des reflektierten Lichts. Zunächst muss die Richtung R des reflektierten Lichts berechnet werden. Die Richtung R des reflektierten Lichts kann aus der Richtung des einfallenden Lichts und dem Normalenvektor R + L = 2dot (N, L) N und dann R = erhalten werden 2dot (N, L) NL. (Wie man diese Formel berechnet, gibt es auf CSDN viele Blogs mit Notizen, bei denen es sich um eine einfache Vektor- und trigonometrische Funktionskonvertierung handelt. Wenn Sie dies nicht verstehen, können Sie sie unter Baidu herunterladen oder direkt hier lesen. )
(Kopieren Sie ein anderes Bild von Hand)
Blinn-Phong Beleuchtungsmodell
Das Phong-Beleuchtungsmodell kann den Hervorhebungseffekt sehr gut ausführen, aber der Nachteil der Blinn-Phong-Beleuchtung besteht darin, dass es rechenintensiv ist. Daher verbesserte Jim Blinn 1977 die Phong-Beleuchtung und nannte sie das Blinn-Phong-Beleuchtungsmodell.
Die Blinn-Phong-Beleuchtung führt ein Konzept ein, einen Halbwinkelvektor, dargestellt durch H. Der Halbwinkelvektor ist einfach zu berechnen. Der Halbwinkelvektor kann durch Normalisieren der Addition der Lichtquellenrichtung L und der Sichtlinienrichtung V erhalten werden. Phong-Beleuchtung vergleicht stattdessen den Winkel zwischen der Reflexionsrichtung R und der Sichtlinienrichtung V, während Blinn-Phong stattdessen den Winkel zwischen dem Halbwinkelvektor H und der Normalenrichtung N vergleicht. Die Berechnungskomplexität des Halbwinkelvektors ist viel einfacher als die Berechnung des reflektierten Lichts, daher ist die Leistung von Blinn-Phong viel höher und der Effekt ähnelt dem der Phong-Lichtfotografie, also des Beleuchtungsmodells der festen Pipeline in OpenGL ist das Blinn-Phong-Beleuchtungsmodell.
Die Berechnungsformel des BlinnPhong-Beleuchtungsmodells lautet wie folgt:
I (spcular) = I * k * pow (max (0, Punkt (N, H)), Glanz), wobei I der Farbvektor des einfallenden Lichts ist, k der Spiegelreflexionskoeffizient ist und Glanz der Grad von ist Glätte.
================================================== ================
Fügen Sie den Shaderlab-Code der beiden folgenden Beleuchtungsmodelle ein
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"
}
================================================== =====================================
Einige Schlüsselcodes sind bereits im Code kommentiert, sodass ich sie nicht zu oft wiederhole. Und Blinn-Pong führt einen Halbwinkelvektor ein, um den reflektierten Vektor zu ersetzen, sodass der Rechenaufwand für den Shader viel geringer ist. Das Folgende ist eine direkte Zusammenfassung des Blinn-Phong-Shader-Codes.
Blinn-Pong Licht Shader
Verweisen Sie auf das Beleuchtungsmodell "Lighting.cginc"
Definieren Sie die a2v-Struktur, um die Eckpunkte und Normalen des Modells zu erhalten
Definieren Sie die v2f-Struktur und speichern Sie die Scheitelpunktinformationen (SV_POSITION). Die Weltnormalen und die Position des Scheitelpunkts in der Weltkoordinate
Müssen in die Scheitelpunktfunktion bekommen
Projektionskoordinaten von Eckpunkten
Scheitelpunktwelt normal
Weltkoordinaten von Eckpunkten
Müssen in die Fragmentfunktion bekommen
Umgebungslicht müssen Sie das Umgebungslicht im Beleuchtungsmodell (UNITY_LIGHTMODEL_AMBIENT.xyz) mit Diffuse multiplizieren
Normalisierte Welt normal
Normalisierte Lichtposition (_WorldSpaceLightPos0.xyz)
Die Betrachtungswinkelposition des normalisierten Punkts (_WorldSpaceCameraPos.xyz-worldPos)
漫 反射 (_LightColor0.rgb * Diffuse.rgb * gesättigt (Punkt (worldNormal, lightDir)))
Normalisierter Halbwinkelvektor (viewDir + lightDir)
Die endgültige Hervorhebungsformel LightColor0.rbg * _Specular.rbg * pow (Punkt (halfDir, worldNormal), _ Gloss)
Zurück zur Hervorhebung + Umgebungslicht + diffuses Licht
um zusammenzufassen
Diese beiden Beleuchtungsmodelle haben tatsächlich einen chinesischen Namen, nämlich das Modell Feng Guangzhao und das Modell Brin-Feng Guangzhao, aber nach dem Wechsel zu Chinesisch ist es sehr verwirrend. Aus der Perspektive des Verstehens kann das Phong-Modell intuitiver Schlussfolgerungen ziehen, und ich weiß nicht, wie man einen Halbwinkelvektor des letzteren berechnet, aber es scheint, dass der Code ohne eine Punktmultiplikationsoperation viel einfacher ist Gefühl der Nachwelt.
Ich bin seit fast einem Jahr faul und hatte erst vor kurzem Zeit, dieses persönliche Verständnis zu ersticken. Es scheint, dass Ausdauer immer noch ein Wort ist, das nicht leicht zu realisieren ist. Obwohl ich normalerweise die Angewohnheit habe, Notizen zu machen, habe ich das Gefühl, dass ich sie nach dem Notieren dort ablege. Nach einer langen Zeit vergesse ich im Grunde alles. Es dauert lange, bis ich es nach einem Rückblick realisiere. Auf diese Weise schreibe ich einen Blog ist eine Erinnerung an mich. Lassen Sie es uns überprüfen und hoffen, weiterhin daran festzuhalten. . .