首页 > 系统相关 >OpenGL3.3_C++_Windows(9)

OpenGL3.3_C++_Windows(9)

时间:2024-06-15 10:28:48浏览次数:13  
标签:OpenGL3.3 float Windows light material C++ specular vec3 TexCoord

最终效果

demo演示

多光源

  1. 原理:
  2. 所有投光物分别计算,对当前片段的影响,再+求和,渲染出物体的材质效果
  3. 每个投光物:根据冯氏光照(环境,漫反射,镜面)分解计算对片段的强度影响,再与当前片段颜色值(单一颜色 / 纹理颜色)* 相乘
  4. 每个投光物也会对(环境,漫反射,镜面)有不同的影响程度
  5. 通过struct和函数,进行整理归纳,比如绘制多个点光源,有不同的位置,之间把每次的位置传入点光源结构体中

Fragment_glsl

#version 330 core
layout(location = 0) out vec4 FragColor;

//in
in vec3 v_Position;
in vec2 v_TexCoord;
in vec3 v_Normal;

//材质
struct Material {
    //
    sampler2D texture1;
    sampler2D texture2;
    //
    sampler2D specular_Texture;
    //光泽度
    float shininess;
}; 
//平行光
struct DirLight {
    vec3 direction;//位置

	//冯氏光照
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
//点光
struct PointLight {
    vec3 position;
    vec3 color;
	
    //冯氏光照
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
//聚光
struct SpotLight {
    //聚光范围
    float cutOff;
    float outerCutOff;

    //冯氏光照
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;       
};
struct ConstVal{
    //camera
    vec3 camera_Position;
    vec3 camera_Direction;

    //衰减
    float constant;
    float linear;
    float quadratic;
};
//
uniform Material material;
uniform DirLight dirLight;
uniform PointLight pointLights[10];
uniform SpotLight spotLight;
uniform ConstVal constVal;

// function prototypes声明在此处,main可以用
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);

//
void main()
{
    vec3 viewPos = normalize(constVal.camera_Position - v_Position);
    vec3 norm = normalize(v_Normal);

    vec3 result = CalcDirLight(dirLight, norm, viewPos);

    for(int i = 0; i < 10; i++)
        result += CalcPointLight(pointLights[i], norm, v_Position, viewPos);

    result += CalcSpotLight(spotLight, norm, v_Position, viewPos);    
    
    FragColor = vec4(result, 1.0);//最终片段颜色

}

//
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
{
    vec3 lightDir = normalize(-light.direction);//平行光向量   
    //漫反射
    float diff = max(dot(normal, lightDir), 0.0);//漫反射
    // 镜面
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    //计算影响
    vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 diffuse = light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 specular = light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));

    return (ambient + diffuse + specular);
}
//
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    vec3 lightDir = normalize(light.position - fragPos);//当前点光向量 
    //漫反射
    float diff = max(dot(normal, lightDir), 0.0);
    // 镜面
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // 衰减
    float distance = length(light.position - fragPos);
    float attenuation = 1.0 / (constVal.constant + constVal.linear * distance + constVal.quadratic * (distance * distance));    
    //计算影响
    vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 diffuse = light.color * light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 specular = light.color * light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));
    ambient *= attenuation;
    diffuse *= attenuation ;
    specular *= attenuation ;
    return (ambient + diffuse + specular);
}
//
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
{
    vec3 lightDir = normalize(constVal.camera_Position - fragPos);//摄像机向量
    //漫反射
    float diff = max(dot(normal, lightDir), 0.0);
    // 镜面
    vec3 reflectDir = reflect(-lightDir, normal);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
    // 衰减
    float distance = length(constVal.camera_Position - fragPos);
    float attenuation = 1.0 / (constVal.constant + constVal.linear * distance + constVal.quadratic * (distance * distance));    
    // 范围
    float theta = dot(lightDir, normalize(-constVal.camera_Direction)); 
    float epsilon = light.cutOff - light.outerCutOff;
    float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
    //计算影响
    vec3 ambient = light.ambient * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 diffuse = light.diffuse * diff * mix(texture(material.texture1, v_TexCoord), texture(material.texture2, v_TexCoord), 0.0).rgb;
    vec3 specular = light.specular * spec * vec3(texture(material.specular_Texture, v_TexCoord));
    ambient *= attenuation * intensity;
    diffuse *= attenuation * intensity;
    specular *= attenuation * intensity;
    return (ambient + diffuse + specular);
}

标签:OpenGL3.3,float,Windows,light,material,C++,specular,vec3,TexCoord
From: https://blog.csdn.net/sengyongan/article/details/139697367

相关文章

  • C/C++中的extern关键词
    于《C++Primer》的学习中遇到extern关键词的详细解释以下将抛开复杂的解释,仅于简单上手的使用方面进行非专业的介绍。倘若我们有多个文件如头文件,文件1,文件2...,而我们想将一个变量或者一个函数于多个文件中同时使用(如文件2中定义了一个函数或者变量,则可在文件1或其他文件直接调......
  • 【华为OD机试真题】159、星际篮球争霸赛 | 机试真题+思路参考+代码解析(C++、Java、Py
    文章目录一、题目......
  • 【华为OD机试真题】155、计算数组中心位置 | 机试真题+思路参考+代码解析(C++、Java、P
    文章目录一、题目......
  • 计算机毕业设计项目推荐,32762 外卖app系统设计与实现(开题答辩+程序定制+全套文案 )上万
    摘 要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,餐饮外卖当然也不例外。外卖app系统主要功能模块包括后台首页,轮播图,资源管理(餐饮新闻,新闻分类),系统用户(注册用户,配送员,注册商家)模块管理(美食信息,外卖点餐,配......
  • 计算机毕业设计项目推荐,32650在线教培管理系统的设计与实现(开题答辩+程序定制+全套文
    目 录摘要Abstract1绪论1.1研究意义1.2开发现状1.3论文结构与章节安排2 在线教培管理系统 系统分析2.1可行性分析2.2系统流程分析2.2.1数据增加流程2.2.2数据修改流程2.2.3数据删除流程2.3 系统功能分析2.3.1功能性分析2.3.2非功......
  • 设置Windows10休眠
    From: https://g.pconline.com.cn/x/1581/15810434.html很多用户在使用电脑的时候,总是会有遇到电脑长时间不用的情况,这时候将其进行休眠是最好的方法,不仅能够让电脑寿命更长,还不会费电,但一些新用户却不清楚如何去设置,那么下面就和小编一起来看看Win10设置休眠的方法吧。......
  • 在C++中,namespace关键字
    在C++中,namespace是一个关键字,用于定义一个命名空间,这是C++标准为了帮助程序员避免命名冲突而引入的一种机制。在大型项目或当多个程序员同时工作在一个项目中时,命名空间尤其有用,因为它们允许你将相关的类、函数、变量和其他标识符分组到一个逻辑单元中。以下是一些关键点,说明......
  • c++_0基础_讲解4 变量定义
    变量C++中的变量是存储数据值的容器,这些值可以在程序执行过程中被修改和使用。在C++中,变量必须先声明后使用,声明变量也可以称之为定义变量,它告诉编译器在何处以及如何去分配存储空间。接下来我将对C++中的变量定义进行详细的介绍。在C++中,变量的定义由以下几个部分组......
  • c++_0基础_讲解5 判断语句
    判断语句C++是一种计算机编程语言,其提供了多种判断语句来控制程序的执行流程。判断语句允许程序根据条件判断的结果来选择不同的执行路径。在C++中,常用的判断语句有if语句、switch语句和三元运算符。if语句是最常用的判断语句之一。它的基本形式是if(条件表达式){执行语句},其中......
  • Windows: 使用PowerShell管理Hyper-V虚拟机
    Hyper-V是Windows操作系统中强大的虚拟化平台,通过Hyper-V,用户可以创建和管理虚拟机(VM)。作为计算机专业人士,我们可能更倾向于使用命令行工具来高效地管理系统。在Windows上,PowerShell是一个功能强大的命令行工具,可以用来管理Hyper-V虚拟机。本文将详细介绍如何使用PowerShell......