LearnOpenGL_study -- 光照贴图

漫反射贴图

完整代码:https://github.com/DXT00/LearnOpenGL_study/tree/a9082da982458111eb505a22e92bcb4146bd8ee7

在着色器中使用漫反射贴图的方法和纹理教程中是完全一样的。但这次我们会将纹理储存为Material结构体中的一个sampler2D。我们将之前定义的vec3漫反射颜色向量替换为漫反射贴图.

struct Material{
	vec3 ambient;
	sampler2D diffuse;
	vec3 specular;
	float shininess;

};

fragment shader:
 

#type fragment
#version 330 core

struct Material{
	vec3 ambient;
	sampler2D diffuse;
	vec3 specular;
	float shininess;

};

out vec4 FragColor;

	
		
float ambientStrength = 0.1f;
float specularStrength = 1.0f;
//uniform float u_shininessStrength;//反光度因子,可以是2,4,8,16,..256,一个物体的反光度越高,反射光的能力越强,散射得越少,高光点就会越小

in vec2 v_TexCoord;
in vec3 v_Normal;		
in vec3 v_FragPos;		


uniform Material u_Material;
uniform sampler2D u_Texture1;
uniform sampler2D u_Texture2;
uniform float u_MixValue;

uniform vec3 u_LightColor;
uniform vec3 u_LightPos;
uniform vec3 u_CameraViewPos;

//ambient
vec3 ambient = u_LightColor * u_Material.ambient* texture(u_Material.diffuse,v_TexCoord).rgb;//u_LightColor * u_Material.ambient

//diffuse
vec3 lightDir = normalize(u_LightPos-v_FragPos);
vec3 norm = normalize(v_Normal);
float diff = max(dot(lightDir,norm),0.0f);
vec3 diffuse = u_LightColor * diff * texture(u_Material.diffuse,v_TexCoord).rgb;// u_Material.diffuse);u_LightColor

//specular
vec3 reflectDir = normalize(reflect(-lightDir,norm));
vec3 viewDir = normalize(u_CameraViewPos-v_FragPos);
float spec = pow(max(dot(reflectDir,viewDir),0.0),u_Material.shininess);
vec3 specular =  u_LightColor * spec  * u_Material.specular;


void main(){

	FragColor = vec4((diffuse + ambient + specular),1.0);// * mix(texture(u_Texture1, v_TexCoord), texture(u_Texture2, vec2(1.0 - v_TexCoord.x, v_TexCoord.y)), u_MixValue);
}

在Application.cpp中添加一个 DiffuseMap的纹理:

m_DiffuseMap.reset(new Texture("assets/texture/container2.png"));

并设置Uniform

由于之前已经有两个纹理了,所以DiffuseMap绑定为2号纹理:

m_Shader->SetUniform1i("u_Material.diffuse", 2);

renderer loop:

//render loop
	while (!glfwWindowShouldClose(m_Window->GetNativeWindow())) {

		float time = (float)glfwGetTime();
		Timestep ts = time - m_LastFrameTime;
		m_LastFrameTime = time;

		InputCheck(ts);
		if (glfwGetKey(m_Window->GetNativeWindow(), GLFW_KEY_ESCAPE) == GLFW_PRESS)
			glfwSetWindowShouldClose(m_Window->GetNativeWindow(), true);
		// render
		// ------
		//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// bind textures on corresponding texture units
		glActiveTexture(GL_TEXTURE0);
		m_Texture1->Bind();
		glActiveTexture(GL_TEXTURE1);
		m_Texture2->Bind();
		glActiveTexture(GL_TEXTURE2);
		m_DiffuseMap->Bind();

		
		Renderer::BeginScene(*m_Camera);

		glm::mat4 model = glm::mat4(1.0f);
		model = glm::translate(model, m_LightSource->GetPosition());
		model = glm::scale(model, glm::vec3(0.5f));
		Renderer::Submit(m_LightSource->GetVertexArray(), m_LightSource->GetShader(), model);
		glDrawArrays(GL_TRIANGLES, 0, 36);

		for (unsigned int i = 0; i < 10; i++)
		{

			glm::mat4 model = glm::mat4(1.0f);
			model = glm::translate(model, cubePositions[i]);
			model = glm::rotate(model, (float)(glfwGetTime()), glm::vec3(1.0f, (float)i * 20, 0.0f));//(float)(glfwGetTime())
			m_Shader->SetUniformMat4f("u_TranInverseModel", glm::transpose(glm::inverse(model)));
			m_Shader->SetUniformVec3f("u_CameraViewPos", m_Camera->GetPosition());

			//glm::vec3 lightColor;// = m_LightSource->GetLightColor();
			//lightColor.x = sin(glfwGetTime() * 2.0f);
			//lightColor.y = sin(glfwGetTime() * 0.7f);
			//lightColor.z = sin(glfwGetTime() * 1.3f);

			m_Shader->SetUniformVec3f("u_LightColor", m_LightSource->GetLightColor());

			m_Shader->SetUniformVec3f("u_Material.ambient", glm::vec3(0.25,0.20725,0.20725));
			m_Shader->SetUniform1i("u_Material.diffuse", 2);

			//m_Shader->SetUniformVec3f("u_Material.diffuse", glm::vec3(1	,0.829	,0.829));
			m_Shader->SetUniformVec3f("u_Material.specular", glm::vec3(0.5,	0.5,0.5));
			m_Shader->SetUniform1f("u_Material.shininess",64.0f);


			Renderer::Submit(m_VertexArray, m_Shader, model);
			glDrawArrays(GL_TRIANGLES, 0, 36);

		}


		glfwSwapBuffers(m_Window->GetNativeWindow());
		glfwPollEvents();
	}

镜面光贴图:

你可能会注意到,镜面高光看起来有些奇怪,因为我们的物体大部分都是木头,我们知道木头不应该有这么强的镜面高光的。我们可以将物体的镜面光材质设置为vec3(0.0)来解决这个问题,但这也意味着箱子钢制的边框将不再能够显示镜面高光了,我们知道钢铁应该是有一些镜面高光的。所以,我们想要让物体的某些部分以不同的强度显示镜面高光。

镜面光贴图上的每个像素都可以由一个颜色向量来表示,比如说黑色代表颜色向量vec3(0.0),灰色代表颜色向量vec3(0.5)。在片段着色器中,我们接下来会取样对应的颜色值将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮

由于箱子大部分都由木头所组成,而且木头材质应该没有镜面高光,所以漫反射纹理的整个木头部分全部都转换成了黑色。箱子钢制边框的镜面光强度是有细微变化的,钢铁本身会比较容易受到镜面高光的影响,而裂缝则不会。

把u_Material 的 specular设置为贴图--》Sampler2D

struct Material{
	vec3 ambient;
	sampler2D diffuse;
	sampler2D specular;
	float shininess;

};

Application 添加 SpecularMap

	m_Shader->SetUniform1i("u_Material.specular", 3);
	m_SpecularMap.reset(new Texture("assets/texture/container2_specular.png"));

 

放射光贴图

对物体的发光部分贴图

完整代码:https://github.com/DXT00/LearnOpenGL_study/tree/e0127d6525036402a0d32319ddbe2144d4226a3a

//ambient
vec3 ambient = u_LightColor * u_Material.ambient* texture(u_Material.diffuse,v_TexCoord).rgb;//u_LightColor * u_Material.ambient

//diffuse
vec3 lightDir = normalize(u_LightPos-v_FragPos);
vec3 norm = normalize(v_Normal);
float diff = max(dot(lightDir,norm),0.0f);
vec3 diffuse = u_LightColor * diff * texture(u_Material.diffuse,v_TexCoord).rgb;// u_Material.diffuse);u_LightColor

//specular
vec3 reflectDir = normalize(reflect(-lightDir,norm));
vec3 viewDir = normalize(u_CameraViewPos-v_FragPos);
float spec = pow(max(dot(reflectDir,viewDir),0.0),u_Material.shininess);
vec3 specular =  u_LightColor * spec  * texture(u_Material.specular,v_TexCoord).rgb;

//emission
vec3 emission = texture(u_Material.emission,v_TexCoord).rgb;
void main(){

	FragColor = vec4((diffuse + ambient + specular + emission),1.0);// * mix(texture(u_Texture1, v_TexCoord), texture(u_Texture2, vec2(1.0 - v_TexCoord.x, v_TexCoord.y)), u_MixValue);
}
	m_EmissionMap.reset(new Texture("assets/texture/matrix.jpg"));
	m_Shader->SetUniform1i("u_Material.emission", 4);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值