图形学基础 | Phong光照模型

Phong模型

Phong模型是针对局部光照的经验模型。先过一遍原理,从wiki给出的2条公式入手:

I p = k a i a + ∑ m ∈ l i g h t s ( k d ( L ⇀ m ⋅ N ⇀ ) i m , d + k s ( R ⇀ m ⋅ V ⇀ ) α i m , s ) I_p=k_ai_a+\sum_{m\in lights}\left(k_d\left({\overset\rightharpoonup L}_m\cdot\overset\rightharpoonup N\right)i_{m,d}+k_s\left({\overset\rightharpoonup R}_m\cdot\overset\rightharpoonup V\right)^\alpha i_{m,s}\right) Ip=kaia+mlights(kd(LmN)im,d+ks(RmV)αim,s)

其中:

  • k a k_a ka 表示环境光反射系数,常数
  • k d k_d kd 表示漫反射系数,常数
  • k s k_s ks 表示镜面高光反射系数,常数
  • α \alpha α 表示物体材质光滑程度,由材质决定(材质越光滑系数越大),常量
  • R ⇀ m {\overset\rightharpoonup R}_m Rm 表示相对于L的反射光线方向
  • N ⇀ \overset\rightharpoonup N N 表示该点的法线
  • R ⇀ m {\overset\rightharpoonup R}_m Rm 表示反射光的方向
  • V ⇀ \overset\rightharpoonup V V 表示摄像机的方向
  • i m , d i_{m,d} im,d 表示光源m的漫反射反射光照,RGB
  • i m , s i_{m,s} im,s 表示光源m的高光反射光照,RGB
  • i a i_{a} ia 表示环境光的光照
  • I p I_p Ip 表示p的总光照,RGB
    在这里插入图片描述
    根据公式可知,Phong模型实质上是三个小模型的叠加:
  • ambient lighting:环境光,模拟像月光这种弱光对物体的影响,特点是物体各个面的"颜色"是一样的。
  • diffuse lighting:漫反射光,被(直接)光源照射后反射出来的光,特点是根据面的法线和光纤方向的关系,每个面的“颜色”会不同。
  • specular lighting:镜面光,模拟了光滑物体或物体的部分光滑表面被光照时产生的高光现象

在这里插入图片描述
下面给出单光源下的phong shader。

ambient lighting
// fs
void main()
{
    float ka = 0.1;
    vec3 ambient = ka * lightColor;

    vec3 result = ambient * objectColor;
    FragColor = vec4(result, 1.0);
}
ambient+diffuse lighting
// vs
void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = aNormal;
}

// fs
void main()
{
    float ka = 0.1;
    vec3 ambient = ka * lightColor;

    float kd = 1.0;
    vec3 N = normalize(Normal);
    vec3 L = normalize(lightPos - FragPos);  
    float NdotL = max(dot(N, L), 0.0);
    vec3 diffuse = kd * NdotL * lightColor;

    vec3 result = (ambient + diffuse) * objectColor;
    FragColor = vec4(result, 1.0);
}

$$$$ ambient+diffuse+specular lighting

// vs
void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = aNormal;
}

// fs
void main()
{
    float ka = 0.1;
    vec3 ambient = ka * lightColor;

    float kd = 1.0;
    vec3 N = normalize(Normal);
    vec3 L = normalize(lightPos - FragPos);  
    float NdotL = max(dot(N, L), 0.0);
    vec3 diffuse = kd * NdotL * lightColor;

    float ks = 0.5;
    float alpha = 32;
    vec3 V = normalize(viewPos - FragPos);
    vec3 R = reflect(-L, N); 
    float spec = pow(max(dot(V, R), 0.0), alpha);
    vec3 specular = ks * spec * lightColor;  

    vec3 result = (ambient + diffuse + specular) * objectColor;
    FragColor = vec4(result, 1.0);
}

Blinn-Phong

在Phong模型中,R和V的夹角不能超过90度,超过90度,cos就会变负数,进而会出现光照错误。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值