OpenGL 实现色温、色调、亮度、对比度、饱和度、高光

news2024/11/19 5:49:35

1.简介

色温:简单理解是色彩的温度,越低越冷如蓝色,约高越暖如红色。

亮度:增加就是给图片所有色彩加白色,减少加黑色。注意是只加黑白两种颜色,不然容易跟纯度弄混。

对比度:增加就是让白的更白,黑的更黑;减少就是白的不那么白,黑的不那么黑。

饱和度:就是增加图片各种颜色的纯度。比如蓝色,增加纯度就是在蓝色上加蓝色,降低纯度就是加入蓝色的对比色,让它变灰色或者黑色。

高光:增加就是给图片白色的部分再加点白色,减少就是减少点白色。

色调:可以简单理解为色彩倾向,倾向于红橙还是黄绿。

2.效果展示

3.片段着色器源码

#version 330 core

out vec4 FragColor;
uniform sampler2D ourTexture;

in vec2 outTexCoord;

uniform float temperature;  //色温[-1.0, 1.0]
uniform float hue;          //色调[-1.0, 1.0]
uniform float brightness;   //亮度[-1.0, 1.0]
uniform float contrast;     //对比度[-1,1]
uniform float saturation;   //饱和度[-1.0, 1.0]
uniform float highlight;    //高光[0.0, 1.0]

// 用于调整色温的函数
vec3 adjustTemperature(vec3 color, float temp) {
    const vec3 warmFilter = vec3(0.93, 0.54, 0.0); // 设置黄色
    const vec3 coolFilter = vec3(0.0, 0.0, 0.3); // 设置蓝色
    // 根据温度值混合
    color = mix(color, color + warmFilter, max(temperature, 0.0));
    color = mix(color, color + coolFilter, max(-temperature, 0.0));
    return color;
}

// 色调函数
vec3 adjustTint(vec3 color, float hue) {
    float angle = hue * 3.14159265; // 将 -1 到 1 映射到 -PI 到 PI
    float c = cos(angle);
    float s = sin(angle);
    mat3 hueRotateMat = mat3(
        0.299, 0.587, 0.114,
        0.299, 0.587, 0.114,
        0.299, 0.587, 0.114
    ) + mat3(
        0.701 * c - 0.587 * s, -0.299 * c - 0.587 * s, -0.3 * c + 0.413 * s,
        0.168 * c + 0.330 * s, 0.325 * c - 0.5 * s, -0.322 * c - 0.094 * s,
        0.0 * c + 0.035 * s, -0.5 * c - 0.418 * s, 0.5 * c + 0.081 * s
    );
    return color * hueRotateMat;
}

// 亮度函数
vec3 adjustBrightness(vec3 color, float bright) {
    return color + vec3(bright);
}

// 对比度函数
vec3 adjustContrast(vec3 color, float cont) {
    cont += 1.0;
    return ((color - 0.5) * cont + 0.5);
}

// 饱和度函数
vec3 adjustSaturation(vec3 color, float sat) {
    float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
    vec3 grey = vec3(luminance);
    return mix(grey, color, sat + 1.0);
}

// 高光函数
vec3 adjustHighlight(vec3 color, float highlightStrengh) {
    return min(color + vec3(highlightStrengh), vec3(1.0));
}

void main()
{
    vec3 color = texture(ourTexture, outTexCoord).rgb;

    // 应用各种调整
    color = adjustTemperature(color, temperature);
    color = adjustTint(color, hue);
    color = adjustBrightness(color, brightness);
    color = adjustContrast(color, contrast);
    color = adjustSaturation(color, saturation);
    color = adjustHighlight(color, highlight);

    FragColor = vec4(color,1.0f);
}

4.完整工程

https://download.csdn.net/download/wzz953200463/88908054

5.相关参考

1.OpenGL模型控制(旋转、平移)

2.OpenGL ES2加载3D模型

3.OpenGL Assimp加载各类型模型(.obj、.fbx、.glb、.3ds)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488135.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信如何设置自动回复消息,提升沟通效率的?

在日常微信聊天过程中,我们可能会频繁遇到相同问题的客户提问,特别是对于从事销售工作的朋友们而言,客户添加好友后的第一句话常常为“在吗”或“你好”。当我们拥有大量好友,手动逐一回复可能会耗费大量时间。因此,自…

Conda笔记--移动Conda环境后pip使用异常的解决

1--概述 由于各种原因,需要将Anaconda转变为Minicoda,为了保留之前安装的所有环境,直接将anaconda3/envs的所有环境拷贝到Miniconda/envs中,但在使用移动后环境时会出现pip的错误:bad interpreter: No such file or di…

Acwing---1497. 树的遍历

树的遍历 1.题目2.基本思想3.代码实现 1.题目 一个二叉树,树中每个节点的权值互不相同。 现在给出它的后序遍历和中序遍历,请你输出它的层序遍历。 输入格式 第一行包含整数 N,表示二叉树的节点数。 第二行包含 N个整数,表示二…

数字经济的下一步:Web3的潜力与前景

引言: 随着区块链技术的迅速发展,数字经济正迎来新的变革时代。在这个数字化时代,Web3作为区块链技术的延伸和演进,正在成为全球数字经济发展的重要方向。本文将深入探讨Web3的潜力与前景,以及它对数字经济发展的深远…

物联网边缘计算云边协同

文章目录 一、物联网云边协同1.IoT云边协同设计2.物联网平台设计3.物联网平台实现 二、部署环境1.节点配置2.版本信息 三、IoT云边协同部署1.部署Kubernetes集群2.部署KubeEdge3.部署ThingsBoard集群4.部署Node-RED边缘网关4.1.边缘网关功能4.2.部署EMQX4.2.部署Node-RED 5.配置…

文案如何让产品卖点看得见、摸得着?

好的电影能够让人记忆犹新,而好的文案也能让卖点可视化,卖点可视化就是让传播目的、产品优势、品牌形象等信息变得可感知,可视化的文案能够让产品功能、优势的展现可以更加直观、生动,从而缩短用户的购买决策时间。今天媒介盒子就…

成功的交易没有对错,只有逻辑

大部分人将交易失败归咎于心态,但其实我们是否认真思考过自己的基本功是否扎实呢?这篇文章将引导你换个角度看待交易,让你明白自己应该努力的方向。 曾经,你或许认为资金体量小、信息不对称、技术不过关、心态不过硬是阻碍交易发展…

【数据结构】一步一步实现AVL树

树和节点的定义 template<class K,class V> class AVLTreeNode {AVLTreeNode<K, V>* _left;AVLTreeNode<K, V>* _right;AVLTreeNode<K, V>* _parent;pair<K, V> _kv;int _bf;AVLTreeNode(const pair<K,V>& kv):_left(nullptr),_right…

Mybatis框架相关问题

HashMap相关问题 Mybatis框架相关问题 一、MyBatis框架是如何实现分页的&#xff1f;二、MyBatis框架里面的缓存机制是怎么回事&#xff1f;一级缓存二级缓存 一、MyBatis框架是如何实现分页的&#xff1f; 分页分为两种&#xff1a; 逻辑分页&#xff1a;将所有数据查询出来…

CBA全明星急需改革但先不谈!不如先学学如何尊重球迷

直播吧指定地址&#xff1a;www.bjcenn.com 3月4日讯 昨晚CBA全明星正赛&#xff0c;南区明星队138-122击败北区明星队。 媒体人三土带刺更博长文总结了本次全明星&#xff0c;原文如下&#xff1a; 如何总结这次全明星&#xff1f; 又一届CBA全明星周末结束&#xff0c;关…

9.10目标和(LC494-M)

算法&#xff1a; 加法的绝对值的集合left 减法的绝对值的集合right nums集合的总和sum 这里的left和right都是绝对值&#xff1a; leftrightsum → rightsum-left left-righttarget → left-(sum-left) target → left (target sum)/2 &#xff0c;target …

充电桩组装行业生产管理MES系统解决方案

充电桩组装行业MES系统是一个综合生产管理系统&#xff0c;融合了工厂企业必要的销售、物流和制造管理等全公司基础业务以及生产计划和现场监测管理。通过结合工业物联网(IIoT)解决方案&#xff0c;将所有重要生产设备进行关联&#xff0c;实现工厂数字化、可视化管理。通过系统…

云计算 2月28号 (linux的磁盘分区)

一 存储管理 主要知识点: 基本分区、逻辑卷LVM、EXT3/4/XFS文件系统、RAID 初识硬盘 机械 HDD 固态 SSD SSD的优势 SSD采用电子存储介质进行数据存储和读取的一种技术&#xff0c;拥有极高的存储性能&#xff0c;被认为是存储技术发展的未来新星。 与传统硬盘相比&#xff0c…

Python - getpass

文章目录 关于 getpass基本使用语法说明其它 关于 getpass getpass 是 Python 自带标准库 Python 官方文档 - getpass https://docs.python.org/3/library/getpass.html 基本使用 我们在看视频教程中&#xff0c;老师如果不想在代码中暴露 token、密码之类的信息&#xff0c…

day03_Vue_Element

文章目录 01.Ajax1.1 Ajax 概述1.2 同步异步1.3 原生Ajax 2. Axios2.1 Axios的基本使用2.2 Axios快速入门2.3请求方法的别名2.4 案例 3 前后台分离开发3.1 前后台分离开发介绍 04 YAPI4.1 YAPI介绍4.2 接口文档管理 05 前端工程化5.1 前端工程化介绍5.2 前端工程化入门5.2.1 环…

深度学习GPU环境安装(WINDOWS安装NVIDIA)

1.检测是否支持GPU环境 1.1.打开设备管理器 winows下面搜索设备管理器&#xff08;或者从桌面"此电脑"——>右键点击——>"管理"打开&#xff09; 1.2.查看本地显卡 在"设备管理器"——"显示适配器"中&#xff0c;如果没有&…

Jupyter Notebook运行Python代码如何传参

在Jupyter Notebook中&#xff0c;运行Python源代码非常方便&#xff0c;但是如何模拟命令行方式运行时的输入参数呢&#xff1f; 如果直接使用sys.argv会出现错误。例如使用argv[1]时出现&#xff1a; 导致上述错误的原因为&#xff1a;在Jupyter Notebook中运行Python代码时&…

python--开心篇--print--多种多样的print输出

文章目录 名言输出绕口令输出《水浒传》中的梁山好汉输出轨道交通充值信息输出对联字符画输出长春地铁1号线运行图模拟12306查询界面模拟企业网站登录界面 名言 print("& "*15) print("& &") print("& …

还在犹豫学不学?鸿蒙技术是否有前途的最强信号来了

2024年3月3日 上午10 点&#xff0c;深圳官方账号发布了一篇关于鸿蒙技术发展的重要文章&#xff0c;看到这篇文章后我非常激动&#xff0c;忍不住和大家分享一下&#xff01; 华为鸿蒙系统自提出以来&#xff0c;网友们的态度各不相同&#xff0c;有嘲笑“安卓套壳”的&#x…

SpringBoot整合rabbitmq-重复消费问题

说明&#xff1a;重复消费的原因大致是生产者将信息A发送到队列中&#xff0c;消费者监听到消息A后开始处理业务&#xff0c;业务处理完成后&#xff0c;监听在告知rabbitmq消息A已经被消费完成途中中断&#xff0c;也就时说我已经处理完业务&#xff0c;而队列中还存在当前消息…