(自用)learnOpenGL学习总结-高级光照-blinn-phong and Gamma矫正

本文主要是介绍(自用)learnOpenGL学习总结-高级光照-blinn-phong and Gamma矫正,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

blinn-phong

先说结果,blinn-phong和phong的区别是什么?

Blinn-Phong与冯氏模型唯一的区别就是,Blinn-Phong测量的是法线与半程向量之间的夹角,而冯氏模型测量的是观察方向与反射向量间的夹角。

在之前我们计算视角能看到多少漫反射、镜面反射等多少的时候,会通过计算viewdir和反射dir的点乘来得到多少。但是有一个问题就是,当我视角和光源方向在一侧的时候,会导致点乘的结果为0,也就是黑的。这于我们常识相悖。

所以为了解决这个问题,采用半程向量更好。

不过还有一点区别就是,两种的夹角不是一致。

也就是说为了弥补上差距,需要把反光度调到2-4倍。

gamma矫正



什么是gamma

我们计算完场景的颜色之后就要显示出来,但是是通过电脑屏幕来显示。而电脑屏幕有一个特性,是通过输入的电压大小来产生亮度变化的。但是,两倍的电压不会产生两倍的亮度。而是2.2倍的指数变化。(crt设备)。

因为人眼看到颜色的亮度更倾向于顶部的灰阶,监视器使用的也是一种指数关系(电压的2.2次幂),所以物理亮度通过监视器能够被映射到顶部的非线性亮度;因此看起来效果不错(译注:CRT亮度是是电压的2.2次幂而人眼相当于2次幂,因此CRT这个缺陷正好能满足人的需要)。

监视器的这个非线性映射的确可以让亮度在我们眼中看起来更好,但当渲染图像时,会产生一个问题:我们在应用中配置的亮度和颜色是基于监视器所看到的,这样所有的配置实际上是非线性的亮度/颜色配置。请看下图:

点线代表线性颜色/亮度值(译注:这表示的是理想状态,Gamma为1),实线代表监视器显示的颜色。

如果我们把一个点线线性的颜色翻一倍,结果就是这个值的两倍。比如,光的颜色向量L¯=(0.5,0.0,0.0)代表的是暗红色。如果我们在线性空间中把它翻倍,就会变成(1.0,0.0,0.0)就像你在图中看到的那样。变成了亮红色

然而,当我们把L ‾= ( 0.5 , 0.0 , 0.0 )显示在显示器上时,我们从图里看,会觉得它显示出了( 0.218 , 0.0 , 0.0 ) ,然而我们需要的是( 1.0 , 0.0 , 0.0 ) 。
在这儿问题就出现了:当我们将理想中直线上的那个暗红色翻一倍时,在监视器上实际上需要翻了4.5倍以上才有一样的效果

但是我们实际上是工作在显示器的输出空间上的,所以我们配置的所有颜色和光照变量从物理角度来看都是不正确的,显示器很少显示正确。

出于这个原因,我们(以及艺术家)通常会将光照值设置得比本来更亮一些(因为监视器会将其亮度显示的更暗一些),如果不是这样,在线性空间里计算出来的光照就会不正确。

会发现gamma矫正还是很重要的

那么改怎么做呢?

最通用的思路是把每个颜色的输出都加上翻转的gamma曲线,这样就会变成线性的了。

举个例子: 暗红色(0.5,0,0)在输出到屏幕之前先应用gamma矫正曲线,就会变成(0.73,0,0)然后发给屏幕之后会自动的加上2.2次幂又回到了(0.5,0,0)。

应用gamma矫正的方式

1.在opengl中建立sRGB帧缓冲。在像素着色器中就行gamma矫正

开启GL_FRAMEBUFFER_SRGB,可以告诉OpenGL每个后续的绘制命令里,在颜色储存到颜色缓冲之前先校正sRGB颜色。
sRGB这个颜色空间大致对应于gamma2.2,它也是家用设备的一个标准。
开启GL_FRAMEBUFFER_SRGB以后,每次像素着色器运行后续帧缓冲,OpenGL将自动执行gamma校正,包括默认帧缓冲。

开启GL_FRAMEBUFFER_SRGB简单的调用glEnable就行

但是要知道的是,这一步要在最后才能进行,因为是把线性的颜色变成非线性(这是为了抵消设备带来的影响)

如果我们在最后输出之前就进行gamma校正,所有的后续操作都是在操作不正确的颜色值。

例如,如果我们使用多个帧缓冲,我们会希望这样:
让两个帧缓冲之间传递的中间结果仍然保持线性空间颜色,只是给发送给监视器的最后的那个帧缓冲应用gamma校正。

2.修改着色器

我们可以自己在片段着色器最后输出fragcolor的时候进行gamma矫正

void main()
{// do super fancy lighting [...]// apply gamma correctionfloat gamma = 2.2;fragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));
}

我们也可以在最后的最后,也就是帧缓冲时后处理。fbo

注意点

1.纹理

有一个要注意的点就是 我们看到的图片、纹理都是屏幕上的,经过2.2次幂处理过的结果,所以我们如果要处理这些图片时需要考虑到。

在我们应用gamma校正之前,这不是个问题,因为纹理在sRGB空间创建和展示,同样我们还是在sRGB空间中使用,从而不必gamma校正纹理显示也没问题。

然而,现在我们是把所有东西都放在线性空间中展示的,纹理颜色就会变坏,如下图展示的那样:

纹理图像实在太亮了,发生这种情况是因为,它们实际上进行了两次gamma校正!

想一想,当我们基于监视器上看到的情况创建一个图像,我们就已经对颜色值进行了gamma校正,所以再次显示在监视器上就没错。

由于我们在渲染中又进行了一次gamma校正,图片就实在太亮了。

那么该如何解决呢?

就是重新矫正,在拿到这些sRGB纹理的时候就是变回线性空间,

float gamma = 2.2;
vec3 diffuseColor = pow(texture(diffuse, texCoords).rgb, vec3(gamma));

不过opengl中有函数来帮我们做这些事情。

在创建纹理的时候,我们可以直接设定纹理是什么格式。

glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

这样就会自动把纹理颜色矫正的线性空间中了。

不过要注意的是:漫反射纹理基本都是sRGB的,但是镜面贴图和法线贴图基本都是线性空间中的。

2.衰减

真实世界中的衰减是与距离的平方成反比。

但是我们用平方的时候会发现效果太强了,所以会有之前的那种衰减方程。我们也可以使用双曲线函数,也就是与距离成反比。

总而言之,gamma校正使你可以在线性空间中进行操作。因为线性空间更符合物理世界,大多数物理公式现在都可以获得较好效果,比如真实的光的衰减。你的光照越真实,使用gamma校正获得漂亮的效果就越容易。这也正是为什么当引进gamma校正时,建议只去调整光照参数的原因。

这篇关于(自用)learnOpenGL学习总结-高级光照-blinn-phong and Gamma矫正的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/732622

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter