本文主要是介绍Unity Shader - 高光反射(Phong、Blinn-Phong),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
高光反射光照模型分为Phong模型和Blinn-Phong模型:
Phong 模型公式:
高光反射 = 光源颜色 * 反射颜色 ∗ pow( max(0, 视角v与光反射向量r的余弦值) , 光泽度)
如下图:
Blinn-Phong 模型公式:
高光反射 = 光源颜色 * 反射颜色 ∗ pow( max(0, 半角向量h与法线n的余弦值) , 光泽度)
如下图:
逐顶点高光反射:
Shader "Unlit/003"
{Properties{_Specular ("_Specular",Color) = (1,1,1,1)// 高光反射值_Gloss ("_Gloss",range(1,100)) = 5}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"float4 _Specular;half _Gloss;struct v2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 vertex : POSITION;float3 color : Color;};v2f vert (v2v v){v2f o;// 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间o.vertex = UnityObjectToClipPos(v.vertex);// 光源方向float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);// 将法向量转到世界坐标法向量float3 normal = UnityObjectToWorldNormal(v.normal);// 视野方向float3 viewDir = normalize(_WorldSpaceCameraPos.xyz- UnityObjectToWorldDir(v.vertex));// 反射方向float3 reflectDir = normalize(mul(normal,2) - lightDir);// float3 reflectDir = normalize(reflect(-lightDir,normal));// Phong 模型公式高光反射计算float3 specular = _LightColor0.rab * _Specular.rgb * pow(max(0,dot(reflectDir,viewDir)),_Gloss);// 半角向量float3 _half = normalize(mul(lightDir + viewDir,0.5)); // Blinn-Phong 模型公式高光反射计算//float3 specular = _LightColor0.rab * _Specular.rgb * pow(max(0,dot(_half,normal)),_Gloss); o.color = specular;return o; }fixed4 frag (v2f i) : SV_Target{float4 color = float4(i.color,1);return color;}ENDCG}}
}
逐片元:
Shader "Unlit/004"
{Properties{_Specular ("_Specular",Color) = (1,1,1,1)// 高光反射值_Gloss ("_Gloss",range(1,256)) = 5}SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"float4 _Specular;half _Gloss;struct v2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 vertex : POSITION;float3 normal : TEXCOORD0;float3 worldPos : TEXCOORD1;};v2f vert (v2v v){v2f o;// 将对象空间中的点变换到齐次坐标中的摄像机裁剪空间o.vertex = UnityObjectToClipPos(v.vertex);o.normal = UnityObjectToWorldNormal(v.normal);o.worldPos = UnityObjectToWorldDir(v.vertex);return o; }fixed4 frag (v2f i) : SV_Target{float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);float3 reflectDir = normalize(mul(i.normal , 2) - _WorldSpaceLightPos0.xyz);// Phong 模型公式高光反射计算float3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(reflectDir,viewDir)),_Gloss);// 半角向量float3 _half = normalize(mul(normalize(_WorldSpaceLightPos0.xyz) + viewDir,0.5)); // Blinn-Phong 模型公式高光反射计算//float3 specular = _LightColor0.rab * _Specular.rgb * pow(max(0,dot(_half,i.normal)),_Gloss); return float4(specular,1);}ENDCG}}
}
看下效果 左边是逐顶点,右边是逐片源
phong 模型:
Blinn-Phong 模型:
可以看到逐顶点渲染和逐像素渲染的区别:逐片元更加细腻
这篇关于Unity Shader - 高光反射(Phong、Blinn-Phong)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!