前置知识
颜色变量相乘
两个颜色变量相乘通常用于计算光照、材质混合、纹理混合等要求
计算结果可以理解为两个颜色叠加在一起的效果 ## 漫反射 漫反射(Diffuse
Reflection)是光线撞击一个物体表面后以各个方向均匀地反射出去的过程
与之相反的则是镜面反射以特定角度反射
这种漫反射可以使物体表面看起来均匀而不闪烁,不会有高亮点
兰伯特光照模型
兰伯特光照模型认为漫反射光的强度仅与入射光的方向和反射点处表面法线的夹角的余弦成正比
入射光强度为L,则反射光强度为:L × cos (θ)
公式:漫反射光照颜色 = 光源的颜色 × 材质的漫反射颜色 × max(0, 标准化后的物体表面法线向量 ⋅ 标准化后的光源方向向量)
其中的点乘其实就是cos (θ)
而max是避免负数,如模型的背面部分是照不到光的,设为0为黑色
模型公式对应信息
- 光源颜色 = Lighting.cginc内置文件中的_LightColor0
- 光源方向 = _WorldSpaceLightPos0 表示光源0在世界坐标下的位置
- 兰伯特光照模型环境光变量
UNITY_LIGHTMODEL_AMBIENT.rgb(模拟环境光对物体的影响,避免阴影部分全黑)
- 法线从模型空间转换到世界空间 UnityObjectToWorldNormal
UnityShader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| Shader "Unlit/Lambert" { Properties { //1材质漫反射颜色属性声明 _MainColor("MainColor",Color) = (1,1,1,1)//白色 } SubShader { Tags { "LightMode"="ForwardBase" }//不透明的向前渲染模式
Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"//引用Unity文件 #include "Lighting.cginc" fixed4 _MainColor;//材质漫反射颜色 struct v2f { float4 pos: SV_POSITION;//裁剪坐标系下顶点位置 float3 color : COLOR;//漫反射光照颜色 }; //逐顶点光照 //所以相关的漫反射光照颜色的计算需要写在顶点着色器回调函数中 v2f vert (appdata_base v)//UnityCG自带结构体包含法线顶点相关CG信息 { v2f v2fData; //_LightColor0//光照颜色 //v.normal//模型空间下的法线 float3 normal = UnityObjectToWorldNormal(v.normal);//世界空间下的法线 float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//光源方向 fixed3 color = _LightColor0.rgb*_MainColor.rgb *max(0,dot(normal, lightDir));//漫反射光照颜色 v2fData.color = color; v2fData.pos = UnityObjectToClipPos(v.vertex);//模型空间转裁剪坐标系下顶点位置 //为了阴影处不全黑,加个兰伯特光照模型环境变量 v2fData.color = UNITY_LIGHTMODEL_AMBIENT.rgb+color; return v2fData; }
fixed4 frag (v2f i) : SV_Target { return fixed4(i.color.rgb,1);//返回漫反射光照颜色 } ENDCG } } }
|