公式:Specular = 直射光 * pow( max(cosβ,0) ,范围系数)
β角指的是法线和x的夹角,x指的是直射光和视野方向的平分线
公式的改变就只有夹角不同,这个效果的反光范围会比较大
//计算高光 fixed3 reflectDir = normalize( reflect(-lightDir,normalDir) ); fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld,v.vertex)); fixed3 specularColor = _LightColor0.rgb * _Specular * (pow( max( dot(reflectDir,viewDir) ,0),_Gloss) ); f.color = diffuseColor + specularColor;
主要计算两个方向,反射光的方向和视野方向
_Specular是自定义属性,为高光颜色
反射光方向主要用reflect()方法得到,两个参数为入射光的方向和法线
视野方向用摄像机位置-点的位置来得到。
公式:specular = 直射光 * pow( max(cosβ,0) ,范围系数)
β角指的是反射光的方向和该点到相机(视野)方向的夹角。
使用兰伯特光照模型计算的模型背面颜色都是全黑色这样子不好。所有演变了一个半兰伯特模型
公式:diffuse = 直射光颜色 * ( cosβ * 0.5 + 0.5)
cosβ的范围为[-1,1],乘于0.5后为[-0.5,0.5],在加上0.5后就变成[0,1]了,刚好满足颜色的范围。
颜色之间相乘,表示融合两种颜色
颜色之间相加,表示加强
Tags{ "LightMode"="ForwardBase" } CGPROGRAM #include "Lighting.cginc" fixed4 _Diffuse;//假装是物体的自身颜色 struct a2v{ float4 v:POSITION; float3 nor:NORMAL; }; struct v2f{ float4 position:SV_POSITION; float3 col:COLOR0; }; #pragma vertex vert #pragma fragment frag v2f vert(a2v v){ v2f f; f.position = UnityObjectToClipPos(v.v); //计算光颜色 fixed3 norDir = normalize((fixed3) mul(unity_ObjectToWorld,float4(v.nor,0))); fixed3 lightDir = normalize( _WorldSpaceLightPos0.xyz ); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//环境光 f.col = _LightColor0.rgb * max(dot(norDir,lightDir),0) * _Diffuse + ambient; return f; } fixed4 frag(v2f f):SV_Target{ return fixed4(f.col,1); } ENDCG
内置变量和方法:
UnityObjectToClipPos(pos) 其实就是:mul(UNITY_MATRIX_MVP,pos),变换模型坐标到裁剪坐标
unity_ObjectToWorld就是_Object2World,模型坐标到世界坐标的变换矩阵
_WorldSpaceLightPos0.xyz 就是第一个平行光的位置(方向)
_LightColor0.rgb 就是第一个平行光的颜色
UNITY_LIGHTMODEL_AMBIENT.rgb 环境光的颜色
normalize() 单位化向量的方法
max() 返回参数中的较大值
dot() 向量的点积
这里针对只有平行环境光的情况下,点受光照的影响与光的位置方向有关
已知a·b = |a||b|*cosβ,a就是单位点的法向量,b是光的单位方向
那么a·b = cosβ,cosβ的值是-1~1的,那么可以用cosβ也就是a·b来表示该点受光影响的强度系数(负数的时候视为0)。
公式:diffuse = 直射光的颜色 * max(a·b,0)
UnityCG.cginc 包含了最常用的帮助函数、宏和结构体
UnityShaderVariables.cginc 在编译的时候自动包含,包含许多内置的全局变量(UNITY_MATRIX_MVP)
Lighting.cginc 包含了各种内置的关照模型,如果是Surface Shader的话会自动包含
HLSLSupport.cginc 自动包含,用来跨平台
光照模型就是一个公式,使用这个公式来计算某个点的光照效果。
能进入摄像机的光照模型的分类:
自发光
高光反射(模拟镜子等光滑面)
漫反射(粗糙面,默认四周发散)
环境光
从应用程序传递到顶点函数的语义a2v
从顶点函数传递给片元函数v2f
片元函数传递给系统
SV_Target 颜色值,显示到屏幕上的颜色