光照贴图
光照贴图,及使用纹理代替物体颜色,物体的实际颜色由物体材质和光照决定。
漫反射贴图
使用一张覆盖物体的图像,让我们能够逐片段索引其独立的颜色值。
方式
1 将纹理传入
GLuint texture1 = loadTexture("./container2.png");//加载纹理
lightShader.setInt("material.sampler", 0);//将着色器中采样器分配到GL_TEXTURE0纹理单元
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);//将0号纹理单元与纹理绑定
2 用纹理颜色代替物体顶点颜色。
vec3 objectColor = texture(material.sampler, TexCoords).rgb;
其他 同上节。
镜面光贴图
专门用于镜面高光的纹理贴图,用于显示物体高光部分的颜色值。
如
在如下贴图中
为了让木箱周边能散发金属光泽,我们使用镜面光贴图
让光线的反射位置显示镜面光贴图,以达到高光反射的效果。
这可能不能明显的看出镜面光贴图的原理,如果我们将镜面光贴图改为如下贴图
再来看效果
就可以很好的理解镜面光贴图的原理了。
代码
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
in vec2 TexCoords;
struct Material {
sampler2D sampler;
sampler2D sampler1;
float shininess;
float ambientStrength;
float diffuseStrength;
float specularStrength;
};
struct Light {
vec3 position;
vec3 color;
};
uniform Material material;
uniform Light light;
uniform vec3 viewPos;
void main()
{
//纹理颜色
vec3 objectColor = texture(material.sampler, TexCoords).rgb;
vec3 specularColor = texture(material.sampler1, TexCoords).rgb;
// ambient
vec3 ambient = (material.ambientStrength * light.color) * objectColor;
// diffuse
vec3 norm = normalize(Normal);//单位法向量
vec3 lightDir = normalize(light.position - FragPos);//该渲染点指向光源
float diff = max(dot(norm, lightDir), 0.0);//向量点乘,角度越大数值越小.(不为负数)
vec3 diffuse = (material.diffuseStrength * light.color) * diff * objectColor;//漫反射强度与光线到该点与该平面的夹角有关,夹角越小,光照越弱.
// specular
vec3 viewDir = normalize(viewPos - FragPos);//绘制点指向摄像机
vec3 reflectDir = reflect(-lightDir, norm); //reflect(入射光线,法线),返回反射向量
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);//两向量点乘后的32次方,次方数大--集中程度高
vec3 specular = (material.specularStrength * light.color) * spec * specularColor; //反光强度*反光角度权值*光照颜色
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
贴图的使用
在如上高光部分都使用了镜面光贴图。
贴图的不真实感
相对于简单光滑的物体,使用贴图并不能看出和真实物体的差别,但如果是较为复杂的形状,用简单的形状搭配贴图以模拟层次感会有较大的不真实感。如上方的盒子。
且镜面光贴图并不是物理意义上的高光,只是达到了这种效果,为了达到逼真效果往往需要很大工作量,而使用物理引擎,则能很大程度减小人力。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容