Quellcode durchsuchen

feat: 封装 材质和灯光结构体

NiceTry12138 vor 10 Monaten
Ursprung
Commit
cf3c9aa671

+ 2 - 2
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/imgui.ini

@@ -24,7 +24,7 @@ Size=351,197
 Collapsed=0
 
 [Window][Light]
-Pos=453,20
-Size=339,140
+Pos=369,7
+Size=418,267
 Collapsed=0
 

+ 25 - 15
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/res/shader/Light/Fragment.frag

@@ -2,40 +2,50 @@
 
 layout(location = 0) out vec4 o_color;
 
+struct Material {
+    vec3 ambient;
+    vec3 diffuse;
+    vec3 specular;
+    int shininess;
+}; 
+
+struct Light {
+    vec3 ambient;
+    vec3 diffuse;
+    vec3 specular;
+
+	vec3 lightPos;
+}; 
+
+uniform Material cubeMaterial;
+uniform Light light;
+
 in vec3 FragPos;                // 顶点坐标
 in vec3 Normal;					// 法线向量
 
 uniform vec3 viewPos;           // 相机坐标
-uniform vec3 lightPos;          // 灯的坐标
-
-uniform vec3 objectColor;       // 基本颜色
-uniform vec3 lightColor;        // 灯光颜色
-
-uniform float ambientStrength;  // 环境光强度
-uniform float diffuseStrength;  // 漫反射强度
-uniform float specularStrength;	// 镜面反射强度
 
 void main() {
 	// 环境光
-	vec3 ambient = ambientStrength * lightColor;
+	vec3 ambient = light.ambient * cubeMaterial.ambient;
 	
 	vec3 normal = normalize(Normal);
-	vec3 lightDir = normalize(lightPos - FragPos);
+	vec3 lightDir = normalize(light.lightPos - FragPos);
 
-	float lightDis = distance(lightPos, FragPos);
+	float lightDis = distance(light.lightPos, FragPos);
 	float disRate = 1 / lightDis / lightDis;
 
 	// 漫反射
 	float rate = max(dot(lightDir, normal), 0.0);	// 因为光线可能从物体的反面,此时忽略这个,所以用 max(0.0, )
-	vec3 diffuse = disRate * diffuseStrength * rate * lightColor;
+	vec3 diffuse = disRate * cubeMaterial.diffuse * rate * light.diffuse;
 
 	// 镜面反射
 	vec3 enterViewDir = viewPos - FragPos;
 	vec3 halfV = (lightDir + enterViewDir) / length(lightDir + enterViewDir);
 	halfV = normalize(halfV);						// 半程向量
-	float specularRate = pow(max(dot(halfV, normal), 0.0), 32);
-	vec3 specular = disRate * specularStrength * specularRate * lightColor;
+	float specularRate = pow(max(dot(halfV, normal), 0.0), cubeMaterial.shininess);
+	vec3 specular = disRate * cubeMaterial.specular * specularRate * light.specular;
 
-	vec3 result = (ambient + diffuse + specular) * objectColor;
+	vec3 result = ambient + diffuse + specular;
 	o_color = vec4(result, 1.0);
 }

+ 20 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/CommonData.h

@@ -1,4 +1,5 @@
 #pragma once
+#include "glm/glm.hpp"
 
 // 顶点信息 v0 版本 后续根据需要可能新增 v1、v2 ...
 struct Vertex_v0
@@ -17,3 +18,22 @@ struct Vertex_v1
 	float normal[3];			  // 法线贴图
 };
 
+
+// 材质
+struct Material_v0
+{
+	glm::vec3 ambient;		// 环境光颜色
+	glm::vec3 diffuse;		// 漫反射颜色 一般与环境光颜色相同
+	glm::vec3 specular;		// 高光颜色
+
+	int shininesss;			// 反光度
+};
+
+struct LightConfig_v0
+{
+	glm::vec3 ambient;		// 环境光颜色 使用 vec3 可以分别控制每个颜色的强度
+	glm::vec3 diffuse;		// 漫反射光颜色 使用 vec3 可以分别控制每个颜色的强度
+	glm::vec3 specular;		// 高光颜色 使用 vec3 可以分别控制每个颜色的强度
+
+	glm::vec3 lightPos;		// 灯光的坐标
+};

+ 1 - 0
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/Util/Shader.h

@@ -35,3 +35,4 @@ private:
 	GLuint m_ShaderID{ GL_ZERO };
 };
 
+ 

+ 35 - 11
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestLight.cpp

@@ -84,7 +84,7 @@ void TestLight::OnEnter(GLFWwindow* window)
 	m_LightShader.Init("res/shader/Light/LightVertex.vert", "res/shader/Light/LightFragment.frag");
 	m_LightShader.UnBind();
 
-	CreateLight();
+	InitLight();
 
 	m_Camera.SetLocation(glm::vec3(0.0f, 0.0f, 3.0f));
 
@@ -120,21 +120,23 @@ void TestLight::Render(GLFWwindow* window)
 	m_Shader.SetUniformMat4f("view", m_view);
 	m_Shader.SetUniformMat4f("projection", m_proj);
 
-	m_Shader.SetUniform3f("objectColor", 1.0f, 0.5f, 0.31f);
-	m_Shader.SetUniform3f("lightColor", 1.0f, 1.0f, 1.0f);
+	m_Shader.SetUniform3f("light.ambient", m_light.ambient.x, m_light.ambient.y, m_light.ambient.z);		// 设置强度
+	m_Shader.SetUniform3f("light.diffuse", m_light.diffuse.x, m_light.diffuse.y, m_light.diffuse.z);
+	m_Shader.SetUniform3f("light.specular", m_light.specular.x, m_light.specular.y, m_light.specular.z);
+	m_Shader.SetUniform3f("light.lightPos", m_light.lightPos.x, m_light.lightPos.y, m_light.lightPos.z);
 
-	m_Shader.SetUniform1f("ambientStrength", m_ambientStrength);		// 设置强度
-	m_Shader.SetUniform1f("diffuseStrength", m_diffuseStrength);
-	m_Shader.SetUniform1f("specularStrength",m_specularStrength);
+	m_Shader.SetUniform3f("cubeMaterial.ambient", m_cubeMaterial.ambient.x, m_cubeMaterial.ambient.y, m_cubeMaterial.ambient.z);
+	m_Shader.SetUniform3f("cubeMaterial.diffuse", m_cubeMaterial.diffuse.x, m_cubeMaterial.diffuse.y, m_cubeMaterial.diffuse.z);
+	m_Shader.SetUniform3f("cubeMaterial.specular", m_cubeMaterial.specular.x, m_cubeMaterial.specular.y, m_cubeMaterial.specular.z );
+	m_Shader.SetUniform1i("cubeMaterial.shininess", m_cubeMaterial.shininesss);
 
 	m_Shader.SetUniform3f("viewPos", m_Camera.GetCameraLocation().x, m_Camera.GetCameraLocation().y, m_Camera.GetCameraLocation().z);
-	m_Shader.SetUniform3f("lightPos", m_LightPos.x, m_LightPos.y, m_LightPos.z);
 
 	glBindVertexArray(m_VAO);
 	glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
 
 	auto lightModule = glm::mat4(1.0f);
-	lightModule = glm::translate(lightModule, m_LightPos);
+	lightModule = glm::translate(lightModule, m_light.lightPos);
 	lightModule = glm::scale(lightModule, glm::vec3(0.2f)); // a smaller cube
 
 	m_LightShader.Bind();
@@ -152,9 +154,16 @@ void TestLight::UpdateImGUI(GLFWwindow* window)
 
 	ImGui::Begin("Light");
 
-	ImGui::SliderFloat("Light ambientStrength", &m_ambientStrength, 0.0f, 1.0f);
-	ImGui::SliderFloat("Light diffuseStrength", &m_diffuseStrength, 0.0f, 5.0f);
-	ImGui::SliderFloat("Light specularStrength", &m_specularStrength, 0.0f, 5.0f);
+	ImGui::SliderFloat3("Light ambient", &m_light.ambient.x, 0.0f, 1.0f);
+	ImGui::SliderFloat3("Light diffuse", &m_light.diffuse.x, 0.0f, 5.0f);
+	ImGui::SliderFloat3("Light specular", &m_light.specular.x, 0.0f, 5.0f);
+	ImGui::SliderFloat3("Light position", &m_light.lightPos.x, -5.0f, 5.0f);
+
+	ImGui::SliderFloat3("Cube Material ambient", &m_cubeMaterial.ambient.x, 0.0f, 1.0f);
+	ImGui::SliderFloat3("Cube Material diffuse", &m_cubeMaterial.diffuse.x, 0.0f, 5.0f);
+	ImGui::SliderFloat3("Cube Material specular", &m_cubeMaterial.specular.x, 0.0f, 5.0f);
+	ImGui::SliderInt("Cube Material position", &m_cubeMaterial.shininesss, 1, 100);
+
 
 	if (ImGui::Button("Close Window"))
 		glfwSetWindowShouldClose(window, true);
@@ -211,3 +220,18 @@ void TestLight::CreateLight()
 	GL_CALL(glEnableVertexAttribArray(0));
 	GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_v1), (void*)offsetof(Vertex_v1, position)));
 }
+
+void TestLight::InitLight()
+{
+	CreateLight();
+
+	m_light.lightPos = glm::vec3(1.2f, 1.0f, 2.0f);
+	m_light.ambient = glm::vec3(1.0f) * 0.1f;
+	m_light.diffuse = glm::vec3(1.0f) * 1.0f;
+	m_light.specular = glm::vec3(1.0f) * 0.5f;
+
+	m_cubeMaterial.ambient = glm::vec3(1.0f, 0.5f, 0.31f);
+	m_cubeMaterial.diffuse = glm::vec3(1.0f, 0.5f, 0.31f);
+	m_cubeMaterial.specular = glm::vec3(0.5f, 0.5f, 0.5f);
+	m_cubeMaterial.shininesss = 32;
+}

+ 4 - 5
图形学/OpenGL学习/src/OpenGLDemo/OpenGLDemo/src/testModule/TestLight.h

@@ -30,6 +30,8 @@ public:
 protected:
 	void CreateLight();
 
+	void InitLight();
+
 private:
 	GLuint m_VBO{ GL_ZERO };
 	GLuint m_VAO{ GL_ZERO };
@@ -44,17 +46,14 @@ private:
 	glm::mat4 m_view = glm::mat4(1.0f);			// 视图矩阵
 	glm::mat4 m_proj = glm::mat4(1.0f);			// 投影矩阵
 
-	glm::vec3 m_LightPos = glm::vec3(1.2f, 1.0f, 2.0f);
-
 	float m_CameraMoveSpeed = 0.1f;
 	float m_CameraRotateSpeed = 0.1f;
 
 	Camera m_Camera;
 	bool m_bLeftAltPress = false;
 
-	float m_ambientStrength = 0.1f;
-	float m_diffuseStrength = 1.0f;
-	float m_specularStrength = 0.5f;
+	Material_v0 m_cubeMaterial;
+	LightConfig_v0 m_light;
 
 	static TestLight _self;
 };