OpenGL学习笔记八——使用结构体创建材质
前言
光照基础链接:
OpenGL结构体的创建
OpenGL可支持自定义结构体,其形式与C/C++类似,示例代码如下:
#version 330 core
//创建结构体
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform Material material;//定义一个Material变量
在冯氏光照模型的基础上,我们将冯氏光照模型的三个组成成分封装成为一个结构体,便于对光照参数进行统一管理,这个结构体便是所谓的材质
材质可以简单理解为一个参数集合体,来控制物体的基本属性。
这样,我们就能提高代码的复用性,通过一套shader实现多种效果。
示例程序:
示例程序在冯氏光照模型的基础上进行改动:
顶点着色器
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
片元着色器
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
uniform vec3 viewPos;
uniform vec3 objectColor;
struct Light{
vec3 lightPos;
vec3 lightColor;
float shininess;
};
uniform Light material;
void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * material.lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(material.lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * material.lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = specularStrength * spec * material.lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);
}
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
//#include"camera.h"
#include <iostream>
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
// camera
//Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
// timing
float deltaTime = 0.0f;
float lastFrame = 0.0f;
// lighting
glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
const char *vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec3 aNormal;\n"
"out vec3 FragPos;\n"
"out vec3 Normal;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"void main()\n"
"{\n"
"FragPos = vec3(model * vec4(aPos, 1.0));\n"
"Normal = aNormal;\n"
"gl_Position = projection * view * vec4(FragPos, 1.0);\n"
"}\n";
const char

本文介绍如何在OpenGL中使用结构体创建材质,通过封装冯氏光照模型的参数,实现材质属性的统一管理,提高代码复用性。示例代码展示了顶点与片元着色器的编写,以及如何在C++程序中设置光照与材质参数。
最低0.47元/天 解锁文章
3788

被折叠的 条评论
为什么被折叠?



