庄懂/技术美术课程学习笔记/OldSchoolPro

光照模型主要分为两个部分:光源和环境

1.光源部分

(1)光源漫反射

//光源漫反射
float3 baseCol = var_MainTex.rgb * _MainCol;
float lambert = max(0.0, ndotl);

 采用Lambert光照模型,baseCol通过基本贴图采样的值和基本色相乘得到。

(2)光源镜面反射

//光源镜面反射
float3 specCol = var_SpecTex.rgb;
float specPow = lerp(1, _SpecPow, var_SpecTex.a);
float phong = pow(max(0.0, vdotr), specPow);

采用Phong光照模型,高光指数则是按照高光贴图a通道的值再和1做插值得到,a通道的值越大,高光指数越大,镜面反射越强。

(3)光源反射混合

//光源反射混合
float shadow = MainLightRealtimeShadow(SHADOW_COORDS);
float3 dirLighting = (baseCol * lambert + specCol * phong) * light.color * shadow;

光源反射混合的值 = (漫反射 + 镜面反射) * 光照颜色 * 光照衰减系数。

2.环境部分

(1)环境漫反射

//环境漫反射
float upMask = max(0.0, nDirWS.g);
float downMask = max(0.0, -nDirWS.g);
float sideMask = 1 - upMask - downMask;
float3 envCol = _EnvUpCol * upMask + _EnvSideCol * sideMask + _EnvDownCol * downMask;
float3 envDiff = baseCol * envCol * _EnvDiffInt;

环境漫反射分为三个部分:环境天顶颜色、环境水平颜色、环境地表颜色。因此需要三个遮罩来处理对应的颜色,向上的遮罩由世界法线的g通道和0取最大值得到,向下的遮罩是对g通道取负再和0取最大值得到,水平的遮罩则是由1减去向上的遮罩和向下的遮罩得到。

(2)环境镜面反射

//环境镜面反射
float fresnel = pow(max(0.0, 1.0 - vdotn), _FresnelPow);
float3 envSpec = var_Cubemap * fresnel * _EnvSpecInt;

镜面反射可以简单用环境球和菲涅尔效果模拟。

(3)环境反射混合

//环境反射混合
float occlusion = var_MainTex.a;
float3 envLighting = (envDiff + envSpec) * occlusion;

环境反射混合的值 = (环境漫反射 + 环境镜面反射) * 环境光遮蔽。

3.自发光部分

//自发光
float emitInt = _EmitInt * (sin(frac(_Time.z)) * 0.5 + 0.5);
float3 emission = var_EmitTex * emitInt;

_Time的值使自发光的强弱程度发生变化。

4.最终结果

把上面三个部分的值相加:

//最终混合
float3 finalRGB = dirLighting + envLighting + emission;

实现效果: 

猜你喜欢

转载自blog.csdn.net/qq_63133691/article/details/130220099
今日推荐