opengl灯光基础:2.2 ADS模型和Phong 光照模型的关联,以及具体实现

前言:

ADS光照模型:

	ADS模型是一种光照模型,由环境光照(Ambient)、漫反射光照(Diffuse)和镜面光照(Specular)三个部分组成。
	它在计算表面的颜色和明暗度时分别考虑了这三种光照的影响。

Phong 光照模型:

	它由环境光照、漫反射光照和镜面光照组成,与ADS模型的三个部分相同。
	然而,Phong光照模型还包括了一个镜面反射指数(Specular Exponent)的参数,用于调整镜面高光的大小和锐利度。

	可以说,ADS模型是Phong光照模型的一个特例,当Phong光照模型中的镜面反射指数为1时,就等同于ADS模型。
	也就是说,ADS模型可以看作是Phong光照模型中镜面反射指数为1时的简化形式。

镜面反射指数:

	镜面反射指数(Specular Exponent)用于调整镜面光照效果的大小和锐利度。它是一个控制镜面高光反射散射程度的参数。
	具体来说,镜面反射指数影响了光照模型中的镜面光照计算,其中包括Phong光照模型和Blinn-Phong光照模型。
	较小的镜面反射指数会产生较宽的散射高光,使高光区域的亮度扩散到周围较大的区域。
	而较大的镜面反射指数会产生较窄的散射高光,使高光区域的亮度集中在一个较小的区域。
	
	通过调整镜面反射指数的值,可以达到不同的效果。
	较小的值可以用于模拟光滑表面(如金属)上的小而锐利的高光,
	而较大的值适用于模拟粗糙表面(如皮肤或木材)上的宽散的高光。

环境光照(Ambient)、漫反射光照(Diffuse)和镜面光照(Specular):


在这里插入图片描述

环境光照:

在这里插入图片描述

    表示物体表面受到周围环境光线的照射。环境光照的颜色通常是固定值,与物体的材质和位置无关

漫反射光照:

在这里插入图片描述
在这里插入图片描述

diffuse = Kd * L * max(dot(N, L), 0)

其中,Kd 是物体表面材质的漫反射系数,L 是入射光线的漫反射系数,N 是物体表面的法向量,L 和 N 的点积表示光线和法向量之间的夹角,max(dot(N, L), 0) 的值保证该夹角在 0 到 90 度之间。

镜面反射光照:

在这里插入图片描述

specular = Ks * L * pow(max(dot(R, V), 0), shininess)

其中,Ks 是物体表面材质的镜面反射系数,L 是入射光线的强度,R 是光线在物体表面反射的方向,V 是视线方向,R 和 V 的点积表示反射光线和视线方向之间的夹角,pow(max(dot(R, V), 0), shininess) 的值表示反射光线

代码展示:

    这块主要是在着色器中实现, 真正代码并没有太多:
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out vec3 FragPos;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

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

片段着色器:

#version 330 core
out vec4 FragColor;

in vec3 Normal;  
in vec3 FragPos;  
struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 
struct Light {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

uniform vec3 viewPos; 
uniform Material material;
uniform Light light;
void main()
{
    // ambient

    vec3 ambient = material.ambient * light.ambient;
  	
    // diffuse 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(light.position - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = (diff * material.diffuse) * light.diffuse;
    
    // specular
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    vec3 specular = (material.specular * spec) * light.specular;  
        
    vec3 result = (ambient + diffuse + specular);
    FragColor = vec4(result, 1.0);
}  

代码链接地址:https://github.com/heisai/Learn-opengl/tree/master/opengl8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值