OpenGL学习笔记八——使用结构体创建材质

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

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 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值