Phong高光反射
标准光照模型也被称为Phong光照模型,早期的游戏引擎中往往只有一个光照模型,就是标准光照模型。标准光照模型只关心直接光照,也就是那些直接从光源发射出来照射到物体表面后经过物体表面的一次反射直接进入摄像机的光线。
如图,反射光与视角的夹角越小,光强越大 ---->> 反射光与视角夹角的余弦值cosΘ,即 R向量(反射光)*V向量(视角方向)
已知视角方向有现成的值,需要求反射光向量
反射光向量
注意:各个向量都当做单位向量
如图可得:
R向量(反射光) + L向量 = 2 * |L| * cosΘ * n向量(这里n向量表明方向,因为n向量为单位向量,不用除以它的模)
= 2 * cosΘ * n向量
= 2 * (L向量 * n向量) * n向量 //cosΘ = L向量*n向量,漫反射已经说过
所以: r向量 = 2 * (L向量 * n向量) * n向量 - L向量
unity内置函数reflect(i, n) 返回入射光线i对表面法线n的反射光线 可以直接得到反射光线, 注意:入射光线i与unity光源方向是相反的,需要用"-"号
高光反射 = 光源颜色 * 物体表面颜色 * (法线与光源方向的点乘)
= 光源颜色 * 物体表面颜色 * saturate( pow(dot(反射光, 视角), 高光光泽度) )
顶点高光反射
Shader "Custom/VertexPhong" { Properties { _Diffuse("Diffuse", Color) = (1,1,1,1) //漫反射颜色 _Specular("Specolor", Color) = (1,1,1,1)//高光颜色 _Gloss("Gloss", Range(1, 200)) = 5 //高光光泽度 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Diffuse; fixed4 _Specular; float _Gloss; struct v2f { float4 vertex : SV_POSITION; fixed3 color : COLOR; }; v2f vert (appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); //环境光 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //漫反射 fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate((dot(worldNormal, worldLight))); //高光反射 fixed3 reflectDir = normalize(reflect(-worldLight, worldNormal)); //入射光线与unity光源方向是相反的,需要用"-"号 fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - UnityObjectToWorldDir(v.vertex));//摄像机位置 - 起点 = 视角方向 fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss); o.color = diffuse + ambient + specular; return o; } fixed4 frag (v2f i) : SV_Target { return fixed4(i.color, 1); } ENDCG } } }
片元高光反射
Shader "Custom/FragPhong" { Properties { _Diffuse("Diffuse", Color) = (1,1,1,1) _Specular("Specular", Color) = (1,1,1,1) _Gloss("Gloss", Range(1,200)) = 5 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _Diffuse; fixed4 _Specular; float _Gloss; struct v2f { float4 vertex : SV_POSITION; fixed3 worldNormal : NORMAL; float3 worldPos : TEXCOORD0; }; v2f vert (appdata_base v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); o.worldNormal = worldNormal; o.worldPos = UnityObjectToWorldDir(v.vertex); return o; } fixed4 frag (v2f i) : SV_Target { //环境光 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //漫反射 fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldLightDir, i.worldNormal)); //高光反射 fixed3 reflectDir = normalize(reflect(-worldLightDir, i.worldNormal)); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)),_Gloss); fixed3 color = ambient + diffuse + specular; return fixed4(color, 1); } ENDCG } } }
//Blinn-Phong高光反射 fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); fixed3 hDir = normalize(worldLightDir + viewDir); fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(i.worldNormal, hDir)),_Gloss);
原文:https://www.cnblogs.com/xianguoguo/p/12214776.html