LearnOpenGL学习总结
文章平均质量分 94
OpenGL
M͏͏r.D
这个作者很懒,什么都没留下…
展开
-
Learn OpenGL 32 IBL
基于图像的光照(Image based lighting, IBL)是一类光照技术的集合。其光源不是如中描述的可分解的直接光源,而是将周围环境整体视为一个大光源。IBL 通常使用(取自现实世界或从3D场景生成的)环境立方体贴图 (Cubemap) ,我们可以将立方体贴图的每个像素视为光源,在渲染方程中直接使用它。这种方式可以有效地捕捉环境的全局光照和氛围,使物体其环境。由于基于图像的光照算法会捕捉部分甚至全部的环境光照,通常认为它是一种更精确的环境光照输入格式,甚至也可以说是一种全局光照的粗略近似。原创 2024-04-01 17:10:32 · 699 阅读 · 0 评论 -
Learn OpenGL 32 PBR光照
在本章节中,我们把重点放在将之前讨论的理论转化为实际的渲染器,这个渲染器将使用直接的(或解析的)光源:比如点光源,定向灯或聚光灯。我们先来看看上一个章提到的反射方程的最终版:我们大致上清楚这个反射方程在干什么,但我们仍然留有一些迷雾尚未揭开。比如说我们究竟将怎样表示场景上的辐照度(Irradiance), 辐射率(Radiance) L我们知道辐射率L(在计算机图形领域中)表示光源的辐射通量(Radiant flux),或光源在给定立体角ω下发出的光能。原创 2024-03-27 22:05:00 · 1001 阅读 · 0 评论 -
Learn OpenGL 31 PBR理论
PBR,或者用更通俗一些的称呼是指基于物理的渲染(Physically Based Rendering),它指的是一些在不同程度上都基于与现实世界的物理原理更相符的基本理论所构成的渲染技术的集合。正因为基于物理的渲染目的便是为了使用一种更符合物理学规律的方式来模拟光线,因此这种渲染方式与我们原来的Phong或者Blinn-Phong光照算法相比总体上看起来要更真实一些。原创 2024-03-27 20:09:22 · 597 阅读 · 0 评论 -
Learn OpenGL 30 SSAO
AO的原理是通过将褶皱、孔洞和非常靠近的墙面变暗的方法近似模拟出间接光照但是环境光遮蔽这一技术会带来很大的性能开销,因为它还需要考虑周围的几何体。我们可以对空间中每一点发射大量光线来确定其遮蔽量,但是这在实时运算中会很快变成大问题。在2007年,Crytek公司发布了一款叫做屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)的技术,这一技术使用了屏幕空间场景的深度而不是真实的几何体数据来确定遮蔽量。原创 2024-03-26 21:29:31 · 1147 阅读 · 0 评论 -
Learn OpenGL 29 延迟着色法
我们现在一直使用的光照方式叫做或者,它是我们渲染物体的一种非常直接的方式,在场景中我们根据所有光源照亮一个物体,之后再渲染下一个物体,以此类推。它非常容易理解,也很容易实现,但是同时它对程序性能的影响也很大,因为对于每一个需要渲染的物体,程序都要对每一个光源每一个需要渲染的片段进行迭代,这是多的!因为大部分片段着色器的输出都会被之后的输出覆盖,正向渲染还会在场景中因为高深的复杂度(多个物体重合在一个像素上)浪费大量的片段着色器运行时间。,为了解决上述问题而诞生了,它大幅度地改变了我们渲染物体的方式。原创 2024-03-25 22:13:19 · 1116 阅读 · 0 评论 -
Learn OpenGL 28 Bloom(泛光)
明亮的光源和区域经常很难向观察者表达出来,因为监视器的亮度范围是有限的。一种区分明亮光源的方式是使它们在监视器上发出光芒,光源的光芒向四周发散。这样观察者就会产生光源或亮区的确是强光区。(译注:这个问题的提出简单来说是为了解决这样的问题:例如有一张在阳光下的白纸,白纸在监视器上显示出是出白色,而前方的太阳也是纯白色的,所以基本上白纸和太阳就是一样的了,给太阳加一个光晕,这样太阳看起来似乎就比白纸更亮了)光晕效果可以使用一个后处理特效泛光来实现。泛光使所有明亮区域产生光晕效果。原创 2024-03-25 15:54:19 · 879 阅读 · 0 评论 -
Learn OpenGL 27 HDR
一般来说,当存储在帧缓冲(Framebuffer)中时,亮度和颜色的值是默认被限制在0.0到1.0之间的。这个看起来无辜的语句使我们一直将亮度与颜色的值设置在这个范围内,尝试着与场景契合。这样是能够运行的,也能给出还不错的效果。但是如果我们遇上了一个特定的区域,其中有多个亮光源使这些数值总和超过了1.0,又会发生什么呢?答案是这些片段中超过1.0的亮度或者颜色值会被约束在1.0,从而导致场景混成一片,难以分辨:这是由于大量片段的颜色值都非常接近1.0,在很大一个区域内每一个亮的片段都有相同的白色。原创 2024-03-25 11:23:37 · 767 阅读 · 0 评论 -
Learn OpenGL 26 视差贴图
视差贴图(Parallax Mapping)技术和法线贴图差不多,但它有着不同的原则。和法线贴图一样视差贴图能够极大提升表面细节,使之具有深度感。它也是利用了视错觉,然而对深度有着更好的表达,与法线贴图一起用能够产生难以置信的效果。视差贴图和光照无关,我在这里是作为法线贴图的技术延续来讨论它的。需要注意的是在开始学习视差贴图之前强烈建议先对法线贴图,特别是切线空间有较好的理解。视差贴图属于位移贴图(Displacement Mapping)技术的一种,它对根据储存在纹理中的几何信息对顶点进行位移或偏移。原创 2024-03-24 21:29:17 · 868 阅读 · 0 评论 -
Learn OpenGL 25 法线贴图
关于法线贴图还有最后一个技巧要讨论,它可以在不必花费太多性能开销的情况下稍稍提升画质表现。当在更大的网格上计算切线向量的时候,它们往往有很大数量的共享顶点,当法向贴图应用到这些表面时将切线向量平均化通常能获得更好更平滑的结果。这样做有个问题,就是TBN向量可能会不能互相垂直,这意味着TBN矩阵不再是正交矩阵了。法线贴图可能会稍稍偏移,但这仍然可以改进。使用叫做格拉姆-施密特。原创 2024-03-24 16:56:38 · 1022 阅读 · 0 评论 -
Learn OpenGL 24 点光源阴影
上个教程我们学到了如何使用阴影映射技术创建动态阴影。效果不错,但它只适合定向光,因为阴影只是在单一定向光源下生成的。所以它也叫定向阴影映射,深度(阴影)贴图生成自定向光的视角。本节我们的焦点是在各种方向生成动态阴影。这个技术可以适用于点光源,生成所有方向上的阴影。这个技术叫做点光阴影,过去的名字是万向阴影贴图(omnidirectional shadow maps)技术。本节代码基于前面的阴影映射教程,所以如果你对传统阴影映射不熟悉,还是建议先读一读阴影映射教程。原创 2024-03-24 15:20:16 · 588 阅读 · 0 评论 -
Learn OpenGL 23 阴影映射
阴影是光线被阻挡的结果;当一个光源的光线由于其他物体的阻挡不能够达到一个物体的表面的时候,那么这个物体就在阴影中了。阴影能够使场景看起来真实得多,并且可以让观察者获得物体之间的空间位置关系。场景和物体的深度感因此能够得到极大提升,下图展示了有阴影和没有阴影的情况下的不同:你可以看到,有阴影的时候你能更容易地区分出物体之间的位置关系,例如,当使用阴影的时候浮在地板上的立方体的事实更加清晰。阴影还是比较不好实现的,因为当前实时渲染领域还没找到一种完美的阴影算法。原创 2024-03-21 21:55:04 · 566 阅读 · 0 评论 -
Learn OpenGL 22 高级光照与Gamma校正
冯氏光照不仅对真实光照有很好的近似,而且性能也很高。但是它的镜面反射会在一些情况下出现问题,特别是物体反光度很低时,会导致大片(粗糙的)高光区域。下面这张图展示了当反光度为1.0时地板会出现的效果:可以看到,在镜面高光区域的边缘出现了一道很明显的断层。出现这个问题的原因是观察向量和反射向量间的夹角不能大于90度。如果点积的结果为负数,镜面光分量会变为0.0。你可能会觉得,当光线与视线夹角大于90度时你应该不会接收到任何光才对,所以这不是什么问题。然而,这种想法仅仅只适用于漫反射分量。原创 2024-03-20 17:56:37 · 794 阅读 · 0 评论 -
Learn OpenGL 21 抗锯齿
将一个多重采样的纹理图像不进行还原直接传入着色器也是可行的。GLSL提供了这样的选项,让我们能够对纹理图像的每个子样本进行采样,所以我们可以创建我们自己的抗锯齿算法。在大型的图形应用中通常都会这么做。// 第4个子样本我们不会深入探究自定义抗锯齿技术的细节,这里仅仅是给你一点启发。原创 2024-03-20 17:35:27 · 708 阅读 · 0 评论 -
Learn OpenGL 20 实例化
假设你有一个绘制了很多模型的场景,而大部分的模型包含的是同一组顶点数据,只不过进行的是不同的世界空间变换。想象一个充满草的场景:每根草都是一个包含几个三角形的小模型。你可能会需要绘制很多根草,最终在每帧中你可能会需要渲染上千或者上万根草。因为每一根草仅仅是由几个三角形构成,渲染几乎是瞬间完成的,但上千个渲染函数调用却会极大地影响性能。如果像这样绘制模型的大量实例(Instance),你很快就会因为绘制调用过多而达到性能瓶颈。原创 2024-03-19 20:08:35 · 684 阅读 · 0 评论 -
Learn OpenGL 19 几何着色器
在顶点和片段着色器之间有一个可选的几何着色器(Geometry Shader),几何着色器的输入是一个图元(如点或三角形)的一组顶点。几何着色器可以在顶点发送到下一着色器阶段之前对它们随意变换。然而,几何着色器最有趣的地方在于,它能够将(这一组)顶点变换为完全不同的图元,并且还能生成比原来更多的顶点。在几何着色器的顶部,我们需要声明从顶点着色器输入的图元类型。这需要在in关键字前声明一个布局修饰符(Layout Qualifier)。原创 2024-03-19 14:20:12 · 1062 阅读 · 0 评论 -
Learn OpenGL 18 高级数据与高级GLSL
我们在OpenGL中大量使用缓冲来储存数据已经有很长时间了。操作缓冲其实还有更有意思的方式,而且使用纹理将大量数据传入着色器也有更有趣的方法。这一节中,我们将讨论一些更有意思的缓冲函数,以及我们该如何使用纹理对象来储存大量的数据(纹理的部分还没有完成)。OpenGL中的缓冲只是一个管理特定内存块的对象,没有其它更多的功能了。在我们将它绑定到一个缓冲目标(Buffer Target)时,我们才赋予了其意义。原创 2024-03-18 14:53:32 · 827 阅读 · 2 评论 -
Learn OpenGL 17 立方体贴图
我们已经使用2D纹理很长时间了,但除此之外仍有更多的纹理类型等着我们探索。在本节中,我们将讨论的是将多个纹理组合起来映射到一张纹理上的一种纹理类型:立方体贴图(Cube Map)。简单来说,立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体的一个面:一个有纹理的立方体。你可能会奇怪,这样一个立方体有什么用途呢?为什么要把6张纹理合并到一张纹理中,而不是直接使用6个单独的纹理呢?立方体贴图有一个非常有用的特性,它可以通过一个方向向量来进行索引/采样。原创 2024-03-18 14:32:28 · 1073 阅读 · 0 评论 -
Learn OpenGL 16 帧缓冲
到目前为止,我们已经使用了很多屏幕缓冲了:用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许我们根据一些条件丢弃特定片段的模板缓冲。这些缓冲结合起来叫做帧缓冲(Framebuffer),它被储存在内存中。OpenGL允许我们定义我们自己的帧缓冲,也就是说我们能够定义我们自己的颜色缓冲,甚至是深度缓冲和模板缓冲。我们目前所做的所有操作都是在默认帧缓冲的渲染缓冲上进行的。默认的帧缓冲是在你创建窗口的时候生成和配置的(GLFW帮我们做了这些)。有了我们自己的帧缓冲,我们就能够有更多方式来渲染了。原创 2024-03-17 10:51:53 · 848 阅读 · 0 评论 -
Learn OpenGL 15 面剔除
尝试在脑子中想象一个3D立方体,数数你从任意方向最多能同时看到几个面。如果你的想象力不是过于丰富了,你应该能得出最大的面数是3。你可以从任意位置和任意方向看向这个球体,但你永远不能看到3个以上的面。所以我们为什么要浪费时间绘制我们不能看见的那3个面呢?如果我们能够以某种方式丢弃这几个看不见的面,我们能省下超过50%的片段着色器执行数!我说的是50%而不是50%,因为从特定角度来看的话只能看见2个甚至是1个面。在这种情况下,我们就能省下超过50%了。原创 2024-03-16 20:19:54 · 906 阅读 · 0 评论 -
Learn OpenGL 14 混合
OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。一个有色玻璃窗是一个透明的物体,玻璃有它自己的颜色,但它最终的颜色还包含了玻璃之后所有物体的颜色。这也是混合这一名字的出处,我们混合(Blend)(不同物体的)多种颜色为一种颜色。所以透明度能让我们看穿物体。原创 2024-03-16 18:40:36 · 1109 阅读 · 0 评论 -
Learn OpenGL 13 模板测试
当片段着色器处理完一个片段之后,(Stencil Test)会开始执行,和深度测试一样,它也可能会丢弃片段。接下来,被保留的片段会进入深度测试,它可能会丢弃更多的片段。模板测试是根据又一个缓冲来进行的,它叫做(Stencil Buffer),我们可以在渲染的时候更新它来获得一些很有意思的效果。一个模板缓冲中,(通常)每个模板值(Stencil Value)是8位的。所以每个像素/片段一共能有256种不同的模板值。原创 2024-03-16 16:46:00 · 874 阅读 · 0 评论 -
Learn OpenGL 12 深度测试
深度缓冲就像颜色缓冲(Color Buffer)(储存所有的片段颜色:视觉输出)一样,在每个片段中储存了信息,并且(通常)和颜色缓冲有着一样的宽度和高度。深度缓冲是由窗口系统自动创建的,它会以16、24或32位float的形式储存它的深度值。在大部分的系统中,深度缓冲的精度都是24位的。当深度测试(Depth Testing)被启用的时候,OpenGL会将一个片段的深度值与深度缓冲的内容进行对比。OpenGL会执行一个深度测试,如果这个测试通过了的话,深度缓冲将会更新为新的深度值。原创 2024-03-15 14:01:34 · 821 阅读 · 0 评论 -
Learn OpenGL 11 Assimp+网格+模型
一个非常流行的模型导入库是,它是(开放的资产导入库)的缩写。Assimp能够导入很多种不同的模型文件格式(并也能够导出部分的格式),它会将所有的模型数据加载至Assimp的通用数据结构中。原创 2024-03-14 22:32:50 · 1137 阅读 · 0 评论 -
Learn OpenGL 10 第一章和第二章复习
第一章颜色向量(Color Vector):一个通过红绿蓝(RGB)分量的组合描绘大部分真实颜色的向量。一个物体的颜色实际上是该物体所不能吸收的反射颜色分量。 冯氏光照模型(Phong Lighting Model):一个通过计算环境光,漫反射,和镜面光分量的值来估计真实光照的模型。 环境光照(Ambient Lighting):通过给每个没有被光照的物体很小的亮度,使其不是完全黑暗的,从而对全局光照进行估计。 漫反射着色(Diffuse Shading):一个顶点/片段与光线方向越接近,光照会越原创 2024-03-13 21:08:07 · 815 阅读 · 0 评论 -
Learn OpenGL 09 投光物+多光源
将光(Cast)到物体的光源叫做投光物(Light Caster)。投光物主要分为点光源,聚光灯,平行光。原创 2024-03-13 20:46:47 · 1451 阅读 · 0 评论 -
Learn OpenGL 08 颜色+基础光照+材质+光照贴图
我们在现实生活中看到某一物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的(Reflected)颜色。物体的颜色为。原创 2024-03-12 22:33:33 · 932 阅读 · 1 评论 -
Learn OpenGL 07 摄像机
/摄像机位置//摄像机方向,指向z轴正方向//摄像机右方向//上方向。原创 2024-03-11 22:01:31 · 919 阅读 · 0 评论 -
Learn OpenGL 06 坐标系统
局部坐标是对象相对于局部原点的坐标,也是物体起始的坐标。下一步是将局部坐标变换为世界空间坐标,世界空间坐标是处于一个更大的空间范围的。这些坐标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。接下来我们将世界坐标变换为观察空间坐标,使得每个坐标都是从摄像机或者说观察者的角度进行观察的。坐标到达观察空间之后,我们需要将其投影到裁剪坐标。裁剪坐标会被处理至-1.0到1.0的范围内,并判断哪些顶点将会出现在屏幕上。原创 2024-03-10 20:06:47 · 789 阅读 · 0 评论 -
Learn OpenGL 05 变换
万向节死锁(Gimbal Lock)是用欧拉角定义旋转时,产生的在某一情况下旋转轴重合导致的系统丢失自由度的情况,一种最简单的解决方式是调整三维软件中的旋转轴顺序来避免该情况发生。也就是说当中间轴旋转至90°的时候就会 导致另外两个轴重合,这时候就可以把最不可能旋转90°的轴放到中间。先平移和先旋转的旋转中心点是不一样的,先旋转的话中心就是(0.5,0.5),先平移的话中心就是(0.75,0.25),所以结果很大差异。某些位置状态并不唯一确定一组欧拉角坐标。画完第一个三角形以后接着输入下面这些代码。原创 2024-03-10 16:48:56 · 367 阅读 · 0 评论 -
Learn OpenGL 04 纹理
GL_LINEAR(也叫线性过滤,(Bi)linear Filtering)它会基于纹理坐标附近的纹理像素,计算出一个插值,近似出这些纹理像素之间的颜色。GL_NEAREST产生了颗粒状的图案,我们能够清晰看到组成纹理的像素,而GL_LINEAR能够产生更平滑的图案,很难看出单个的纹理像素。激活纹理单元之后,接下来的glBindTexture函数调用会绑定这个纹理到当前激活的纹理单元,纹理单元GL_TEXTURE0默认总是被激活,所以我们在前面的例子里当我们使用。那么这两种纹理过滤方式有怎样的视觉效果呢?原创 2024-03-09 22:51:49 · 938 阅读 · 0 评论 -
Learn OpenGL 03 着色器
参考解答顶点着色器的x坐标加上一个随时间增加的偏移量即可//main.cpp// 位置变量的属性位置值为 0// 颜色变量的属性位置值为 1。原创 2024-03-09 15:39:33 · 1033 阅读 · 0 评论 -
Learn OpenGL 02 你好,三角形
所以,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个三角形的时候最后的像素颜色也可能完全不同。几何着色器的输出会被传入光栅化阶段(Rasterization Stage),这里它会把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader)使用的片段(Fragment)。图元装配(Primitive Assembly)阶段将顶点着色器输出的所有顶点作为输入(如果是GL_POINTS,那么就是一个顶点),并所有的点装配成指定图元的形状;图形渲染管线的每个阶段的抽象展示。原创 2024-03-08 21:34:45 · 803 阅读 · 0 评论 -
Learn OpenGL 01 你好,窗口
一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。OpenGL规范严格规定了每个函数该如何执行,以及它们的输出值。至于内部具体每个函数是如何实现(Implement)的,将由OpenGL库的开发者自行决定(译注:这里开发者是指编写OpenGL库的人)。原创 2024-03-07 21:39:44 · 1070 阅读 · 0 评论