光照贴图就是因为所有的材质都有着不同的漫反射光和镜面反射效果,就如钢材和木头就会有区别。
所有我们就要根据具体的材质给予不同的光照贴图。
那么开始上代码:
fragmentSource.txt
#version 330 core
out vec4 FragColor;
in vec3 FragPos;
in vec3 Normal;
in vec2 Texcoord;//要上贴图就需要贴图位值函数
struct Material{
vec3 ambient;
sampler2D diffuse;//将diffuse的纯色改为贴图
sampler2D specular;//将specular的纯色改为贴图
float shininess;
};
uniform Material material;
uniform vec3 objColor;//模型颜色
uniform vec3 ambientColor;//环境光颜色
uniform vec3 lightPos;//灯光位置
uniform vec3 lightColor;//灯光颜色
uniform vec3 CameraPos;
void main()
{
vec3 norm=normalize(Normal);
vec3 lightDir=normalize(lightPos-FragPos);//灯光位置减去渲染位置
vec3 diffuse =texture(material.diffuse,Texcoord).rgb*max(dot(norm,lightDir), 0.0f) * lightColor;//跟前面使用贴图一样,直接将这些向量相乘就可以了。
vec3 reflectVec=reflect(-lightDir,norm);
vec3 CameraVec=normalize(CameraPos-FragPos);
vec3 specular=pow(max(dot(reflectVec,CameraVec),0.0f),material.shininess)*lightColor*texture(material.specular,Texcoord).rgb;//specular也是直接乘上就可以了
vec3 ambient=ambientColor*texture(material.diffuse,Texcoord).rgb;//ambient也要上贴图,直接使用漫反射的贴图就可以了
vec3 result=(ambient+diffuse+specular)*objColor;
FragColor = vec4(result,1.0f);
}
然后是vertexSource.txt
#version 330 core
//out vec4 vertexColor;
out vec3 FragPos;
out vec3 Normal;
out vec2 Texcoord;//输出Texcoord数据
layout(location = 3) in vec3 aPos;
layout(location = 4) in vec3 normal;
layout(location = 5) in vec2 aTexcoord;//导入texcoord数据
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main(){
gl_Position = projMat*viewMat*modelMat*vec4(aPos.x, aPos.y, aPos.z, 1.0);
FragPos=(modelMat*vec4(aPos,1.0f)).xyz;
Normal= (modelMat*vec4(normal,0.0f)).xyz;
Texcoord=aTexcoord;//将导入的texcoord的数据输出
}
Shader.h增加下面的代码
public:
enum Slot
{
DIFFUSE,
SPECULAR
};
void SetUniform1i(const char* paramNameString, int slot);
修改一下Shader.cpp
void Shader::SetUniform1i(const char* paramNameString, int slot)//从几号贴图栏位拿贴图
{
glUniform1i(glGetUniformLocation(ID, paramNameString), slot);
}
Material.h
将diffuse和specular的类型修改一下
unsigned int diffuse;
unsigned int specular;
Material.cpp
也是修改一下类型
Material::Material(Shader* _shader, glm::vec3 _ambient, unsigned int _diffuse, unsigned int _specular, float _shininess)
:shader(_shader),ambient(_ambient),diffuse(_diffuse),specular(_specular),shininess(_shininess)
{
}
接下来是main.cpp
因为需要导入新的Texcoord数据,
所以想改数据:
GLfloat vertices[] = {
// Positions // Normals // Texture Coords
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
然后将数据导入vertexShader的代码,很熟了,就不写注释了
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 8* sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
下载好下面的两张图片:
木箱图片
镜面贴图(Specular Map)
修改一下Material声明的代码
Material* myMaterial = new Material(myShader,
glm::vec3(1.0f, 1.0f, 1.0f),
LoadImageToGpu("container2.png", GL_RGBA, GL_RGBA, Shader::DIFFUSE),
LoadImageToGpu("container2_specular.png", GL_RGBA, GL_RGBA, Shader::SPECULAR),
64.0f
);
绑定一下槽位,虽然我好想不绑定也能用,但是还是绑定一下,比较好!
glActiveTexture(GL_TEXTURE0+Shader::DIFFUSE);
glBindTexture(GL_TEXTURE_2D, myMaterial->diffuse);//绑定
glActiveTexture(GL_TEXTURE0+Shader::SPECULAR);
glBindTexture(GL_TEXTURE_2D, myMaterial->specular);//绑定
然后在在那堆导入uniform量的地方导入新的material.diffuse和material.specular
myMaterial->shader->SetUniform1i("material.diffuse",Shader::DIFFUSE);
myMaterial->shader->SetUniform1i("material.specular", Shader::SPECULAR);
运行效果图:
改了一下背景,我忘了!这个你应该会吧!学了这么久,自己改一下!