通过前两篇的学习,我们知道如何计算光照衰减与阴影.
我们知道每一次pass都是一次完整的渲染,unity为我们提供了一次pass同时计算光照衰减+光照的宏
同时atten与shadow也合并为atten. (高光反射+漫反射)* 阴影系数 *光照衰减系数
代码与阴影接收计算相似,最大的区别在于阴影计算的部分
fixed shadow = SHADOW_ATTENUATION(f);
替换为
UNITY_LIGHT_ATTENUATION(atten,f,f.worldPos);
UNITY_LIGHT_ATTENUATION宏被定义在AutoLight.cginc中,参数atten会在宏中定义,参数f为v2f类型的结构体,参数f.worldPos是世界坐标系位置
代码
Shader "Unity/Custom/NewSurfaceShader" {
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 multi_compile_fwdbase//在forwardBase中获取正确的光照变量
#pragma vertex vert//声明顶点处理方法
#pragma fragment frag//声明片段处理方法
#include "Lighting.cginc"//调用光照函数库
#include "AutoLight.cginc"//阴影投射相关的宏在这个库中
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
struct a2v {
float4 vertex : POSITION;//顶点的模型空间位置 在阴影接收的宏中规定了vertex这个字段 名称不可以改
float3 normal : NORMAL;//模型空间法线
};
struct v2f {
float4 pos : SV_POSITION;//输出给剪裁空间的顶点坐标 在阴影接收的宏中规定了pos这个字段 名称不可以改
float3 worldNormal : TEXCOORD0;//世界坐标系法线
float3 worldPos : TEXCOORD1;//世界坐标系坐标
SHADOW_COORDS(2)//声明一个坐标用于阴影纹理采样 2为下一个可用的寄存器索引值 也就是TEXCOORD2
};
v2f vert(a2v v) {
v2f f;
f.pos = UnityObjectToClipPos(v.vertex);//模型空间到剪裁空间转换
f.worldNormal = UnityObjectToWorldNormal(v.normal);//模型空间到世界坐标系法线
f.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;//模型空间到世界坐标系位置
TRANSFER_SHADOW(f);//计算阴影纹理坐标
return f;
}
fixed4 frag(v2f f) : SV_Target{
fixed3 worldNormal = normalize(f.worldNormal);//单位化
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);//获取光照方向 并单位化
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//环境光颜色
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir));//漫反射颜色
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - f.worldPos.xyz);//朝向相机的方向
fixed3 halfDir = normalize(worldLightDir + viewDir);//h方向 用于计算高光反射补偿度
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);//高光反射
UNITY_LIGHT_ATTENUATION(atten,f,f.worldPos);//光照衰减 * 阴影 atten在宏里定义了
return fixed4(ambient + (diffuse + specular) * atten, 1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}