网站后台怎么上传文章百度文库个人登录
基本计算公式如下:
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);
需要4个参数,入射光线的颜色和强度lightColor
,材质的高光反射系数Specular
,视角方向viewDir
和反射方向reflectDir
。
逐顶点光照的高光反射
Shader "Specular Vertex-Level"
{Properties{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)_Specular ("Specular", Color) = (1, 1, 1, 1)//控制材质的高光反射颜色_Gloss ("Gloss", Range(8.0, 256)) = 20//控制高光区域的大小}SubShader{pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;//gloss范围较大 使用floatstruct a2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;float3 color: COLOR;};v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));//从模型空间的法线转换到世界空间的法线。fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));//cg的reflect函数的入射方向要求由光源指向交点处,所以取反fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex).xyz);//_WorldSpaceCameraPos摄像机的世界位置, 把顶点坐标从模型空间转换到世界坐标下,再通过和_WorldSpaceCameraPos//相减得到世界空间下的视角方向。fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);o.color = ambient + diffuse + specular;return o;}fixed4 frag(v2f i) : SV_TARGET0{return fixed4(i.color,1.0);}ENDCG}}FallBack "DIFFUSE"
}
效果如下:
逐像素光照的高光反射
原理和上面的相似,只是把关键计算放到了片元着色器里面:
Shader "Specular Vertex-Level"
{Properties{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)_Specular ("Specular", Color) = (1, 1, 1, 1)//控制材质的高光反射颜色_Gloss ("Gloss", Range(8.0, 256)) = 20//控制高光区域的大小}SubShader{pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;//gloss范围较大 使用floatstruct a2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;//float3 worldNormal: TEXCOORD0;float3 worldPos : TEXCOORD1;};v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);o.worldPos = mul(_Object2World,v.vertex).xyz;return o;}fixed4 frag(v2f i) : SV_Target{fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT;fixed3 worldNormal = normalize(i.worldNormal);fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)),_Gloss);return fixed4(ambient + diffuse + specular, 1.0);}ENDCG}}FallBack "Specular"
}
Blinn-Phong光照模型
基本计算公式如下:
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,halfDir)),_Gloss);
相比于Phone模型,如果摄像机和光源距离模型足够远的话,Blinn模型会快于Phone模型,因为此时worldLightDir
和viewDir
可认为是定制 halfDir
将是一个常量。
Shader "Specular Vertex-Level"
{Properties{_Diffuse ("Diffuse", Color) = (1, 1, 1, 1)_Specular ("Specular", Color) = (1, 1, 1, 1)//控制材质的高光反射颜色_Gloss ("Gloss", Range(8.0, 256)) = 20//控制高光区域的大小}SubShader{pass{Tags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"fixed4 _Diffuse;fixed4 _Specular;float _Gloss;//gloss范围较大 使用floatstruct a2v{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float4 pos : SV_POSITION;//float3 worldNormal: TEXCOORD0;float3 worldPos : TEXCOORD1;};v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal = UnityObjectToWorldNormal(v.normal);o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;return o;}fixed4 frag(v2f i) : SV_Target{fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT;fixed3 worldNormal = normalize(i.worldNormal);//fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));//fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));fixed3 halfDir = normalize(worldLightDir + viewDir);fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,halfDir)),_Gloss);return fixed4(ambient + diffuse + specular, 1.0);}ENDCG}}FallBack "Specular"
}