- 博客(64)
- 收藏
- 关注
原创 OpenGL:PCF柔和阴影
本文探讨了阴影渲染中出现的锯齿问题及其解决方法。阴影锯齿主要源于深度贴图分辨率限制,导致多个片段采样相同深度值。解决方案包括:1)提高深度贴图分辨率;2)优化光源视锥;3)使用PCF(百分比渐进滤波)技术。PCF通过多次采样深度贴图并混合结果来生成柔和阴影。文章展示了不同采样密度的PCF效果对比,从3×3采样(9次)到8×8采样(64次),采样次数越多阴影越柔和。文末提供了GLSL代码实现,演示了如何通过纹理采样和混合计算来改善阴影质量。
2025-11-23 21:44:05
299
转载 OpenGL:阴影过采样
现在如果我们采样深度贴图[0,1]范围以外的区域,纹理函数总会返回一个1.0的深度值,由此得到的阴影值始终为0.0。但是图中还是有一部分是阴影区域,这是因为那部分区域的坐标超出的光的视锥的远平面。这是因为当投影坐标超出光的视锥范围时,其值会比1.0大,此时采样的深度纹理就会超出他默认的范围[0,1]。根据纹理环绕方式,我们将会得到不正确的深度结果,它不是基于真实的来自光源的深度值。我们希望超出深度范围的坐标,深度值为1.0,这样超出的坐标将永远不在阴影之中(深度值最大为1.0)。
2025-11-23 21:39:03
15
原创 OpenGL:阴影失真与阴影悬浮
本文分析了阴影渲染中的失真问题(Shadow Acne)及其解决方案。阴影失真主要由深度纹理精度不足导致,表现为摩尔纹和闪烁现象。解决方法包括引入阴影偏移(shadow bias)技术,通过添加深度偏差值来减少误判。进一步优化提出了根据光线与表面角度动态调整偏移量的方法。然而过大的偏移会导致阴影悬浮问题,表现为阴影偏离实际物体。最终解决方案是在生成深度贴图时启用正面剔除,增大记录的深度值,从而避免误判。文章通过图示和代码示例详细说明了问题成因及解决步骤。
2025-11-23 21:01:57
1241
原创 OpenGL:几何着色器
几何着色器是一种可编程着色器,用于处理输入的图元(点、线或三角形),可以修改、转换或生成新的图元。它通过声明输入/输出图元类型和最大顶点数来控制处理流程,支持输出不同类型或数量的图元。文中以可视化法线为例,展示了从顶点着色器传递法线数据,在几何着色器中生成法线向量线,最后通过片段着色器着色的完整流程。这种技术可以用于调试或增强渲染效果,通过两次绘制(主场景和法线)实现可视化。几何着色器提供了灵活的图元处理能力,扩展了图形渲染的可能性。
2025-11-20 22:05:52
429
原创 OpenGL:Normal Mapping
法线贴图是一种 “存储表面法线信息” 的纹理贴图,用 RGB 颜色值编码法线方向,让低多边形(低模)模型呈现高多边形(高模)的凹凸细节。原理贴图的 RGB 通道对应法线的 X、Y、Z 轴方向(默认蓝色通道 Z 值占比高,所以法线贴图多呈蓝紫色)。不需要增加模型面数,仅通过修改法线方向,就能模拟出划痕、褶皱、纹路等细节,大幅提升渲染效率。法线贴图通常会呈现蓝紫色,因为法线贴图中的法线通常是从XY平面出发,指向+Z方向的。在贴图中的RGB分量分别对应法线的XYZ分量。
2025-11-20 20:15:23
1121
原创 OpenGL:Cube Map
摘要: Cube Map是包含6个2D纹理的立方体贴图,使用3D坐标(s,t,r)索引,其纹理坐标等于方向坐标。它不仅用于天空盒,还可实现环境反射/折射效果。创建时需为立方体6个面分别绑定纹理数据,并设置纹理参数。
2025-11-16 20:55:03
281
原创 OpenGL:Uniform Block
摘要:OpenGL中的Uniform Block Object(UBO)通过共享uniform数据提升渲染性能。
2025-11-15 19:35:21
439
原创 OpenGL:Framebuffer实现Shadow mapping
本文介绍了使用OpenGL Framebuffer实现阴影渲染的技术。首先创建Framebuffer并绑定深度纹理附件,从光源视角进行离屏渲染获取场景深度信息。然后正常渲染场景时,通过比较当前片段深度与深度贴图数据来计算阴影因子。关键技术包括:1) 创建只存储深度信息的Framebuffer;2) 从光源视角渲染场景获取深度贴图;3) 在正常渲染时进行深度比较判断阴影区域。该方法利用深度测试实现阴影效果,是实时渲染中常用的阴影生成技术。
2025-11-15 11:51:32
558
原创 OpenGL:FrameBuffer
帧缓冲对象(FBO)是OpenGL中的自定义缓冲,可附加纹理或渲染缓冲对象存储颜色、深度和模板信息。纹理附件支持读写和着色器采样,适合后处理;渲染缓冲主要用于深度/模板测试,具有硬件优化优势。使用FBO需要创建对象、附加存储、检查完整性,通过绑定FBO渲染场景后再使用存储数据。关键函数包括glBindFramebuffer、glRenderbufferStorage等,广泛应用于离屏渲染、屏幕特效等场景。
2025-11-15 11:40:31
1149
原创 C++自定义迭代器
对于官方定义的迭代器结构,有5个参数,在后续实现自己的迭代器使需要设置。public:// 标准写法// 迭代器的类型// 数据类型// 迭代器之间的逻辑距离// 指针// 引用// 构造函数// 实现运算符重载// 解引用// 成员访问// 前++运算符// 后++运算符return tmp;// 前--运算符// 后--运算符return tmp;// 比较运算符return!
2025-03-31 20:11:59
448
原创 OpenGL:中点直线算法
中点直线算法是通过在像素中确定与理想直线最靠近的像素来进行扫描转换的。在上图中,假设直线的斜率0≤m≤1。假设当前最近的像素已经确认为Pxkyk,由于x位最大的位移方向,因此直线在x方向上每次增加一个像素单位,而在y方向上是否增加一个像素单位,即P点的下一个点是选P1xk1yk还是P2xk1yk1,取决于两个备选像素哪一个离理想像素最近设Mxk1yk0.5位P1P2的中点,
2024-06-23 09:13:51
1080
原创 DDA直线算法
假设给定直线段的起点坐标x0y0和终点坐标x1y1ykxb其中kx2−x1y1−y2by0−kx0DDA直线算法就是在上一个点的基础上x和y加上一个增量,求下一个点的坐标:::info由xiyi求xi1yy1的过程:当∣k∣≤1xi1xi1yi1kxi1bkxi1byib当∣。
2024-06-22 08:38:06
927
原创 OpenGL绘制Bezier曲面
贝塞尔曲面是贝塞尔曲线在二维上的扩展。它由一组控制点定义,通过这些控制点生成光滑的曲面。贝塞尔曲面通常用两个参数u和v来表示,这两个参数的取值范围都在 [0, 1] 之间。
2024-06-20 10:29:20
1527
原创 OpenGL绘制B样条曲线
B样条曲线(B-spline curves)是一种基于样条函数(spline function)的分段多项式函数,广泛用于计算机图形学、数据拟合和数值分析中。B样条曲线有许多优点,如局部控制、平滑性和灵活性。
2024-06-19 11:28:53
1874
原创 OpenGL绘制Bezier曲线
贝塞尔曲线还可以用德卡斯特里奥算法(De Casteljau’s algorithm)递归地计算。对于给定的控制点集P0P1PnP0P1...Pn和参数tttPi0P_i^{(0)}Pi0PiP_iPiPir1−tPir−1tPi1r−1,其中r12nP_i^{(r)}=(1-t)P_i^{(r-1)} +tP_{i+1}^{(r-1)},其中r=1,2,...,nPir1−tP。
2024-06-18 15:59:54
1701
原创 OpenGL超级宝典 纹理(一)
1. 创建纹理对象2. 分配纹理缓存空间3. 绑定纹理对象到OpenGL上下文,告诉OpenGL纹理的类型4. 更新纹理数据5. 控制纹理数据的读取方式 5.1 创建采样器对象 5.2 设置纹理过滤方式
2022-03-24 00:10:15
1775
原创 OpenGL超级宝典 完整渲染管线画圆
圆的画法直接上代码吧。Shader类是上一篇文章的shadervertex shader#version 450 corelayout(location = 0) in vec3 aPos;void main(){ gl_Position = vec4(aPos, 1.0);}tec shader#version 450 corelayout(vertices = 3) out;void main(){ if(gl_InvocationID == 0) { /
2022-03-05 11:54:56
762
原创 OpenGL超级宝典 使用缓冲为顶点着色器提供数据
1. 创建vao并且绑定过到OpenGL上下文2. 创建vbo3. 为vbo分配内存空间4. 将vbo绑定到OpenGL上5. 将vbo绑定到vao上6. 设置数据的布局和格式7. 指示vao的顶点属性应该从哪个绑定点获取数据8. 启用顶点数据
2022-03-05 11:44:48
1433
原创 OpenGL超级宝典 插值以及bezier曲线
插值概念bezier曲线vertex shadertesc shadertese shaderfragment shaderShader类在前面的文章中有,这里不在提源代码效果图概念插值(Interpolation)表示寻找一系列已知点之间的值的过程。穿过A点和B点的直线的公式如下:P = A + tD其中,D=(B-A)因此该公式可写成P = A + t(B - A)或 P = (1-t)A + tBGLSL中有mix()函数可以进行插值计算bezier曲线vertex shad
2022-03-02 00:01:05
1053
原创 OpenGL超级宝典 渲染管线(四)
渲染管线渲染管线总图顶点着色器细分曲面控制着色器细分曲面引擎细分曲面评估着色器几何着色器基元装配裁剪剔除光栅化片段着色器帧缓存还有很多不懂的,所以写的很粗糙。欢迎大家提出改正。渲染管线总图顶点着色器顶点着色器作为管线的第一个阶段,它的作用其实很简单,就是接收外界输入的数据。这些数据是渲染图形必不可少的,所以说顶点着色器是管线中必需的一个阶段。并且数据可以传递到下一个着色器中。细分曲面控制着色器1.细分曲面控制着色器的数据从顶点着色器中获取,顶点着色器将数据作为输出,细分曲面控制着色器作为输
2022-02-28 23:13:37
517
原创 OpenGL超级宝典 渲染管线(二)
细分曲面分成了三部分,首先是细分曲面控制着色器,这个着色器主要是设置细分因子,也就是细分的程度。然后是固定的细分曲面引擎,将接收到的贴片(patch)细分成点、线或者三角形最后是细分曲面评估着色器,这里进行细分算法的编写,并且输出
2022-02-26 10:31:54
483
原创 OpenGL超级宝典 渲染管线(一)
自己封装的Shader类(后面继续改进)shader.h#pragma once#include "sb7.h"#include <string>class Shader{public: Shader(); Shader(const std::string vertexPath, const std::string fragmentPath); //program对象使用 void use();private: GLuint program; //源代码 std
2022-02-24 23:07:24
337
原创 OpenGL超级宝典 绘制第一个三角形
顶点着色器#version 450void main(){ //三角形的顶点 const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0), vec4(-0.25, -0.25, 0.5, 1.0), vec4(0.25, 0.25, 0.5, 1.0)); //gl_Vert.
2022-02-22 23:32:31
228
原创 OpenGL超级宝典 绘制第一个点
#include "sb7.h"#include <math.h>GLint complie_shaders(){ GLuint vertex_shader, fragment_shader, program; //顶点着色器源代码 static const char* vertex_shader_source[] = { "#version 450 \n" " \n" "void main() \n"
2022-02-22 23:11:00
251
原创 OpenGL超级宝典(第7版)环境配置和相关问题
资源获取资源可以去异步社区或者官网下载,自行去网上找。环境配置资源处理将资源压缩到合适的位置,注意目录中不能含有中文使用CMAKE,生成VS项目来编译glfw打开项目,分别生成Debug和Release的项目解决方案将glfw编译生成的Debug文件中的glfw3.lib文件复制到资源第一级目录下的lib文件夹中去将Debug文件夹复制过来的glfw3.lib改名为glfw_d.lib同理,将glfw编译生成的Release中的glfw3.lib复制到lib文件夹中,此时不需要
2022-02-22 11:39:24
1857
10
原创 SQL创建存储过程
创建SQL存储过程需要使用到的语法- 创建存储过程CREATE 存储过程的名称(参数)BEGIN...需要执行的SQL语句END- 调用CALL 存储过程的名称(参数)个人看法,这就是一个函数...无参数CREATE PROCEDURE p_student_select()BEGIN SELECT * FROM student;ENDCALL p_student_select()带参# out其实就是cpp里的引用变量,in就是值传递CREATE PROCEDUR
2021-11-18 10:44:09
25971
原创 C++线程启动、结束,创建线程方法
线程启动、结束,创建线程方法、join,detach* 程序运行起来,生成一个进程,该进程的主线程自动开始运行* 主线程从main函数开始执行,那么自己创建的线程,也需要从一个函数开始运行(初始函数)。一旦这个函数运行完毕,代表该线程结束。* 整个进程是否执行完成完毕的标志是 主线程是否执行完毕,如果主线程执行完毕了,代表整个进程执行完毕。 此时,一般情况下,如果其他子线程没有执行完毕,那么这些子线程就会被操作系统强行终止。 所以,一般情况下,如果想要保持子线程的运行状态,那么要让主线程一直保持,
2021-11-02 09:14:30
3037
2
原创 OpenGL(可编程管线):Shader + Bezier曲面 +QT
Bezier曲面前面的博客已经介绍,本次绘制Bezier曲面使用了细分着色器直接上代码#pragma once#include <vector>#include <qopenglfunctions_4_4_core.h>#include <iostream>#include <qmatrix4x4.h>#include "Shader.h"#include <string>using namespace std;class B
2021-08-25 21:19:52
585
原创 OpenGL(可编程管线):Bezier曲面
Bezier曲面Bezier线de Casteljau算法Bezier曲面bezier曲面编程思想实例代码运行结果Bezier线贝塞尔曲线由一组参数方程定义,方程组中使用控制点指定特定的曲线的形状,每个控制点都是2D空间中的一个点。de Casteljau算法其中B(t)为Bernstein多项式,另外了解,这里不做解释(主要是没有深入研究…)。此图来自《计算机图形学编程(使用OpenGL和C++)》Bezier曲面Bezier曲面定义了3D空间中的曲面,从Bezier曲线拓展,需要将b
2021-07-23 16:23:27
4219
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅