学习OpenGL——第十天

11 阅读3分钟

材质与光照属性详解

在图形渲染中,合理设置材质和光照属性对于实现真实感效果至关重要。本文将从材质定义、光的属性,以及光照贴图三个方面进行系统梳理。


一、材质的基本属性

当描述一个表面时,通常为三个光照分量分别定义材质颜色(Material Color):

  • 环境光照(Ambient Lighting)
  • 漫反射光照(Diffuse Lighting)
  • 镜面光照(Specular Lighting)

通过为每个分量指定颜色,可以对表面颜色输出进行细致控制。此外,还需添加反光度(Shininess),共同组成完整的材质属性:

#version 330 core 
struct Material { 
    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
    float shininess; 
}; 
uniform Material material;
  • ambient:定义表面在环境光下的反射颜色,通常与表面本身颜色一致。
  • diffuse:定义漫反射光照下的表面颜色,通常设置为期望的物体颜色。
  • specular:定义表面镜面高光的颜色,可用于表现特殊表面效果。
  • shininess:影响镜面高光的散射程度和半径。

二、光的属性

一个光源对其环境光(ambient)、**漫反射光(diffuse)和镜面光(specular)**分量有不同的强度设置:

  • 环境光一般设置为较低强度,避免主导整体色彩。
  • 漫反射分量通常为光源本身的颜色,常见为明亮白色。
  • 镜面光分量建议设为vec3(1.0),以获得最大强度高光。

可以通过结构体统一管理光源属性:

struct Light { 
    vec3 position; 
    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
} 
uniform Light light;

三、光照贴图的应用

现实世界的物体常常由多种材质构成,因此需要引入漫反射贴图与镜面光贴图,以便对物体的不同光照分量进行精细控制。

1. 漫反射贴图

  • 在着色器中,将漫反射贴图作为sampler2D存储于Material结构体中,替代原有的vec3漫反射颜色向量。

image.png

注意:sampler2D属于不透明类型(Opaque Type),只能通过uniform定义,不能直接实例化或作为函数参数,否则GLSL会报错。这一规则同样适用于封装了不透明类型的结构体。

为简化,通常移除环境光材质颜色向量,直接使用漫反射贴图的颜色:

struct Material { 
    sampler2D diffuse; 
    vec3 specular; 
    float shininess; 
}; 
in vec2 TexCoords;
  • 采样漫反射颜色:

vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

  • 设置环境光颜色与漫反射一致:

vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));


2. 镜面光贴图

  • 可为镜面高光单独使用一张贴图(黑白或彩色),以定义不同部位的镜面光强度。

image.png

  • 镜面强度由贴图像素亮度决定:黑色为vec3(0.0),灰色为vec3(0.5),越白镜面分量越强。
  • 通常可通过Photoshop或Gimp将漫反射贴图转为镜面光贴图(黑白化、调整亮度/对比度)。
  • 更新材质结构体以支持镜面光贴图:
struct Material { 
    sampler2D diffuse; 
    sampler2D specular; 
    float shininess; 
};
  • 在片段着色器中采样镜面光贴图:
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords)); 
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords)); 
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords)); 
FragColor = vec4(ambient + diffuse + specular, 1.0);

通过上述方法,可以灵活且精确地控制物体的材质表现和光照效果,实现更高质量的渲染结果。