OpenGl学习笔记(十一)光照贴图的使用

光照贴图就是因为所有的材质都有着不同的漫反射光和镜面反射效果,就如钢材和木头就会有区别。
所有我们就要根据具体的材质给予不同的光照贴图。
那么开始上代码:
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);

运行效果图:
在这里插入图片描述
改了一下背景,我忘了!这个你应该会吧!学了这么久,自己改一下!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值