自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(945)
  • 收藏
  • 关注

原创 Preview of “Design Pattern”

对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。《孟子.告子篇》“冬日则饮汤,夏日则饮水”《孟子·离娄》 “不以规矩,不成方圆”《孟子·离娄》“不以六律,不能正五音”“兵来将挡,水来土掩”

2023-09-09 15:22:06 102

原创 《武术与设计模式》行为型

“行为型”原意:对象之间如何通信订阅者程序: 事物之前的通信,通过该机制,一个事物说,另外的事物能知道武林:黄忠与法正在定军山斩杀夏侯渊时,法正举白旗,黄忠收到消息表示不进攻。法正举红旗,黄忠收到进攻指示于是下山斩杀了夏侯渊。(此处通过举旗来进行通信)状态程序:事物有多种状态,经常在状态之前相互切换武林:两个人搏斗,一个人进攻,过了一会累了,他进入防守。(此处进攻和防守就是两种状态)中介程序:不相互联系,统一跟一个人(中介)联系武林:全真教弟子在演练天罡北斗阵时,马钰说一声“繁星

2023-09-03 17:13:41 114

原创 《武术与设计模式》结构性

“结构性”原意:将类或者对象结合在一起形成更大的结构代理程序:用某种方式代理真正的方式来处理事情。武林:比如以前经常有上门踢馆的事情,这个时候掌门人就会说“你要是能过得了我徒弟三招,才有资格跟我打”。徒弟替师傅接招这个事情就是代理,徒弟和师傅的接口一样,使用的都是本门招式和功夫。示例二,如果一个人要了解某个功夫是什么样的,武术家可以表演该功夫里面几个经典的招式。待这个人需要了解所有招式,再详细一一讲解。此处表演几个经典招式就是一种代理。(几个代替所有)适配者程序:源和目标的接口不一致

2023-09-03 15:56:54 118

原创 《武术与设计模式》创建型

“创建型”原意:创建对象的模式单例程序: 一个对象就存在一个武林:所谓“武林至尊,宝刀屠龙,号令天下,莫敢不从”,匠人在打造屠龙宝刀时,决定打造一件世间仅此一件的宝物。简单工厂程序:某种类型指代要创建的某种对象。武林:练习自由格斗或者散打时,教练会喊口号,学员通过相应口号出相应动作。比如“1”代表出前直拳,”2”代表出后直拳。这个学员通过口号来创建某种动作(对象)就是简单工厂。抽象工厂程序:产品族,有很多不同类型的不同产品。武林:少林功夫有大力金刚掌,少林镇山棍,武当派有太极拳、

2023-09-03 14:57:38 67

原创 灯光 (1)平行光(Directional Light)

定义一个光线方向向量而不是位置向量来模拟一个定向光。着色器的计算基本保持不变,但这次我们将直接使用光的direction向量而不是通过position来计算lightDir向量。step3. 定义光源的方向(注意我们将方向定义为从光源出发的方向,你可以很容易看到光的方向朝下)。1.平行光(Directional Light)

2022-09-24 07:46:10 624 1

原创 相机 (2)旋转

用这3个轴外加一个平移向量来创建一个矩阵,并且你可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。在每一帧中我们计算出新的deltaTime以备后用。1.1 LookAt矩阵。

2022-09-23 08:40:52 227

原创 相机 (1)观察空间(Camera/View Space)

位置、观察的方向、一个指向它右侧的向量以及一个指向它上方的向量。细心的读者可能已经注意到我们实际上创建了一个三个单位轴相互垂直的、以摄像机的位置为原点的坐标系。以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。

2022-09-23 08:15:17 345

原创 光照 (5) 法线矩阵(Normal Matrix)

矩阵求逆对于着色器运算开销很大,因为它必须在场景中的每一个顶点上进行,应尽可能避免在着色器中进行求逆运算。先在CPU上计算出法线矩阵,再通过uniform把它传递给着色器(就像模型矩阵一样)。注意,大部分的资源都会将法线矩阵定义为应用到模型-观察矩阵(Model-view Matrix)上的操作,但是由于我们只在世界空间中进行操作(不是在观察空间),我们只使用模型矩阵。Problem: 模型矩阵执行了不等比缩放,顶点的改变会导致法向量不再垂直于表面了。模型矩阵左上角3x3部分的逆矩阵的转置矩阵。

2022-09-22 22:54:35 370

原创 光照 (4) 漫反射光照

b. 对norm和lightDir向量进行点乘,计算光源对当前片段实际的漫发射影响。光的方向向量是光源位置向量与片段位置向量之间的向量差。step1. 在片段着色器中声明一个静态变量uniform作为光源位置:uniform vec3 lightPos,在世界空间中进行所有的光照计算,把顶点位置属性乘以模型矩阵(不是观察和投影矩阵)来把它变换到世界空间坐标。step2. 在渲染循环中(渲染循环的外面也可以,因为它不会改变)更新uniform。a. 计算光源和片段位置之间的方向向量。

2022-09-21 22:57:12 186

原创 光照 (3) 法向量(Normal Vector)

step4. 将法向量由顶点着色器传递到片段着色器(光照的计算都是在片段着色器里进行)step1. 把法线数据手工添加到顶点数据中。修改顶点属性指针来适应新的顶点数组的大小。垂直于片段表面的一个向量(黄色箭头表示)step2. 更新光照的顶点着色器。step3. 更新顶点属性指针。

2022-09-18 23:30:41 369

原创 光照 (2)全局光

用光的颜色乘以一个很小的常量环境因子,再乘以物体的颜色,然后将最终结果作为片段的颜色。全局照明(Global Ilumination) = 直接照射 + 间接照明。

2022-09-18 23:26:42 148

原创 光照 (4) 镜面光贴图示例

也可以在镜面光贴图中使用真正的颜色,不仅设置每个片段的镜面光强度,还设置了镜面高光的颜色。从现实角度来说,镜面高光的颜色大部分(甚至全部)都是由光源本身所决定的,所以这样并不能生成非常真实的视觉效果(这也是为什么图像通常是黑白的,我们只关心强度)。通过使用镜面光贴图我们可以可以对物体设置大量的细节,比如物体的哪些部分需要有闪闪发光的属性,我们甚至可以设置它们对应的强度。镜面光贴图能够在漫反射贴图之上给予我们更高一层的控制。

2022-09-18 21:15:41 243

原创 光照 (5) 光照贴图

在片段着色器中,我们接下来会取样对应的颜色值并将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮。镜面高光的强度可以通过图像每个像素的亮度来获取。镜面光贴图上的每个像素都可以由一个颜色向量来表示,比如说黑色代表颜色向量。允许我们对物体的漫反射分量(以及间接地对环境光分量,它们几乎总是一样的)和镜面光分量有着更精确的控制。使用一张覆盖物体的图像,让我们能够逐片段索引其独立的颜色值。表现了物体所有的漫反射颜色的纹理图像。物体的某些部分以不同的强度显示镜面高光。

2022-09-18 21:12:16 191

原创 光照 (1) 定义

物体的颜色:物体从一个光源反射各个颜色分量的大小。eg. 白色光照到物体上,仅反射Coral 颜色,其他吸收。所以人眼看到的是Coral颜色。使用绿色的光源又会发生什么呢?

2022-09-18 16:18:40 160

原创 初识OpenGL (-)纹理过滤(Texture Filtering)

GL_NEAREST产生了颗粒状的图案,我们能够清晰看到组成纹理的像素,而GL_LINEAR能够产生更平滑的图案,很难看出单个的纹理像素。一个纹理像素的中心距离纹理坐标越近,那么这个纹理像素的颜色对最终的样本颜色的贡献越大。当进行放大(Magnify)和缩小(Minify)操作的时候可以设置纹理过滤的选项,比如你可以在纹理被缩小的时候使用邻近过滤,被放大时使用线性过滤。给模型顶点设置的那个数组,OpenGL以这个顶点的纹理坐标数据去查找纹理图像上的像素,然后进行采样提取纹理像素的颜色。

2022-09-13 06:07:21 1039

原创 初识OpenGL (-)VAO&VBO

比如说,我们有一个线段,上面的端点是绿色的,下面的端点是蓝色的。如果一个片段着色器在线段的70%的位置运行,它的颜色输入属性就会是一个绿色和蓝色的线性结合;我们有3个顶点,和相应的3个颜色,从这个三角形的像素来看它可能包含50000左右的片段,片段着色器为这些像素进行插值颜色。片段插值会被应用到片段着色器的所有输入属性上。为获得数据队列中下一个属性值(比如位置向量的下个x分量)我们必须向右移动6个float,其中3个是位置值,另外3个是颜色值。对于每个顶点来说,位置顶点属性在前,所以它的偏移量是0。

2022-09-13 05:39:15 297

原创 初识OpenGL (-)多级渐远纹理(Mipmap)

有一个包含着上千物体的大房间,每个物体上都有纹理。由于远处的物体可能只产生很少的片段,OpenGL从高分辨率纹理中为这些片段获取正确的颜色值就很困难,因为它需要对一个跨过纹理很大部分的片段只拾取一个纹理颜色。就像普通的纹理过滤一样,切换多级渐远纹理级别时你也可以在两个不同多级渐远纹理级别之间使用NEAREST和LINEAR过滤。这样没有任何效果,因为多级渐远纹理主要是使用在纹理被缩小的情况下的:纹理放大不会使用多级渐远纹理,为放大过滤设置多级渐远纹理的选项会产生一个GL_INVALID_ENUM错误代码。

2022-09-12 21:00:17 993

原创 初识OpenGL (-)纹理(Texture)

纹理映射(Map)到三角形时,指定三角形的每个顶点各自对应纹理的哪个部分。这样每个顶点就会关联着一个纹理坐标,用来标明该从纹理图像的哪个部分采样(译注:采集片段颜色)。纹理坐标在x和y轴上,范围为0到1之间(注意我们使用的是2D纹理图像)。使用纹理坐标获取纹理颜色叫做采样(Sampling)。纹理坐标起始于(0, 0),也就是纹理图片的左下角,终始于(1, 1),即纹理图片的右上角。0.0f, 0.0f, // 左下角。1.0f, 0.0f, // 右下角。0.5f, 1.0f // 上中。

2022-09-06 07:55:36 345

原创 GLSL (4)Uniform

eg. 在片段着色器中声明了一个uniform vec4的ourColor,并把片段着色器的输出颜色设置为uniform值的内容。注意,查询uniform地址不要求你之前使用过着色器程序,但是更新一个uniform之前你必须先使用程序(调用glUseProgram),因为它是在当前激活的着色器程序中设置uniform的。这个函数有一个特定的后缀,标识设定的uniform的类型。1. Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式。step1. 声明一个GLSL的uniform。

2022-09-05 23:55:21 708

原创 GLSL (3)输入和输出

着色器使用in和out两个关键字设定输入和输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。既是一个着色器向另一个着色器发送数据,我们必须在发送方着色器中声明一个输出,在接收方着色器中声明一个类似的输入。你也可以忽略layout (location = 0)标识符,通过在OpenGL代码中使用glGetAttribLocation查询属性位置值(Location),但在着色器中设置会节省你(和OpenGL)的工作量。顶点着色器的输入特殊在,它从顶点数据中直接接收输入。

2022-09-05 23:06:00 600

原创 初识OpenGL (-)api(待扩展)

之后的绘制调用会一直以线框模式绘制三角形,直到我们用glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)将其设置回默认模式。// 线框模式(Wireframe Mode)参数一: 表示打算将其应用到所有的三角形的正面和背面。配置OpenGL如何绘制图元。参数二:用线来绘制。

2022-09-05 22:46:36 160

原创 初识OpenGL (-)VAO顶点数组对象

好处:当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO。定义一个储存了顶点属性配置和应使用的VBO的顶点数组对象。生成/配置所有的VAO(和必须的VBO及属性指针),然后储存它们供后面使用。当我们打算绘制物体的时候就拿出相应的VAO,绑定它,绘制完物体后,再解绑VAO。OpenGL的通过VAO知道如何处理顶点输入。step3. 绑定和配置对应的VBO和属性指针,之后解绑VAO供之后使用。可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在VAO中。

2022-09-05 22:41:20 382

原创 GLSL (2)数据类型

一个向量的分量可以通过vec.x这种方式获取,这里x是指这个向量的第一个分量。你可以分别使用.x、.y、.z和.w来获取它们的第1、2、3、4个分量。GLSL也允许你对颜色使用rgba,或是对纹理坐标使用stpq访问相同的分量。GLSL中的向量是一个可以包含有2、3或者4个分量的容器,分量的类型可以是前面默认基础类型的任意一个。大多数时候我们使用vecn,因为float足够满足大多数要求了。2.1 重组(Swizzling)

2022-09-04 06:56:03 839

原创 初识OpenGL (-)坐标系统(Coordinate System)

将特定范围内的坐标转化到标准化设备坐标系的过程(而且它很容易被映射到2D观察空间坐标)被称之为投影(Projection),因为使用投影矩阵能将3D坐标投影(Project)到很容易映射到2D的标准化设备坐标系中。观察矩阵(View Matrix),用来将世界坐标变换到观察空间,一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。顶点坐标起始于局部空间(Local Space),局部坐标对象相对于局部原点的坐标,也是物体起始的坐标。裁剪空间(Clip Space)

2022-09-04 06:40:36 267

原创 GLSL (1)基本概念

类C语言,着色器的开发语言。为图形计算量身定制,包含一些针对向量和矩阵操作的有用特性。

2022-09-04 06:07:26 304

原创 初识OpenGL (-)EBO元素缓冲对象

同样,和VBO类似,我们会把这些函数调用放在绑定和解绑函数调用之间,缓冲的类型为GL_ELEMENT_ARRAY_BUFFER。之后的绘制调用会一直以线框模式绘制三角形,直到我们用glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)将其设置回默认模式。参数四: 指定EBO中的偏移量(或者传递一个索引数组,当不在使用索引缓冲对象的时候),但是我们会在这里填写0。EBO是一个缓冲区,就像一个顶点缓冲区对象一样,它存储 OpenGL 用来决定要绘制哪些顶点的索引。

2022-09-03 23:32:46 521

原创 欧拉角(Euler Angle)

/ 译注:direction代表摄像机的前轴(Front),这个前轴是和本文第一幅图片的第二个摄像机的方向向量是相反的。分别绕着原坐标z轴(蓝),一次旋转以后的x轴(绿)以及两次旋转以后的z轴(红)旋转,最终产生的红色坐标系即表示出目标方向。// 注意我们先把角度转为弧度。2. 一共有3种欧拉角:俯仰角(Pitch)、偏航角(Yaw)和滚转角(Roll)...

2022-08-30 06:11:09 20720 9

原创 右手坐标系(Right-handed System)

OpenGL是一个右手坐标系。

2022-08-30 05:40:35 190

原创 初识OpenGL (-)顶点之“链接顶点属性“

由于我们知道这个数组是紧密排列的(在两个顶点属性之间没有空隙)我们也可以设置为0来让OpenGL决定具体步长是多少(只有当数值是紧密排列时才可用)。一旦我们有更多的顶点属性,我们就必须更小心地定义每个顶点属性之间的间隔(译注: 这个参数的意思简单说就是从这个属性第二次出现的地方到整个数组0位置之间有多少字节)。参数五: 步长(Stride),在连续的顶点属性组之间的间隔。参数三:指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。参数二:指定顶点属性的大小: 3。...

2022-08-30 05:25:49 184

原创 GLSL (0)编程思想

在OpenGL中一个对象(Object)是指一些选项的集合,它代表OpenGL状态的一个子集。比如,我们可以用一个对象来代表绘图窗口的设置,之后我们就可以设置它的大小、支持的颜色位数等等。假设当我们想告诉OpenGL去画线段而不是三角形的时候,我们通过改变一些上下文变量来改变OpenGL状态,从而告诉OpenGL如何去绘图。OpenGL自身是一个巨大的状态机(State Machine),OpenGL的状态通常被称为OpenGL上下文(Context)。这类函数会根据当前OpenGL的状态执行一些操作。..

2022-08-30 05:02:48 134

原创 图形学 (-)数学基础

向量的w分量也叫齐次坐标。想要从齐次向量得到3D向量,我们可以把x、y和z坐标分别除以w坐标。单位矩阵(Identity Matrix)。单位矩阵是一个除了对角线以外都是0的N×N矩阵。如果一个向量的齐次坐标是0,这个坐标就是方向向量(Direction Vector)N×1矩阵,N表示向量分量的个数,N维(N-dimensional)向量。向量来表示位置,表示颜色,甚至是纹理坐标。1.4 四元数(Quaternion)缩放变量:(S1,S2,S3)位移向量:(Tx,Ty,Tz)任意向量:(x,y,z)..

2022-08-27 22:40:35 266

原创 初识OpenGL (-)坐标空间

创建一个透视投影矩阵创建了一个定义了可视空间的大平截头体,任何在这个平截头体以外的东西最后都不会出现在裁剪空间体积内,并且将会受到裁剪。aspect: 视口宽高比,第三、四个参数分别为近平面和远平面的深度。2. 透视(Perspective)fovy: 视锥上下面之间的夹角。bottom:视口下坐标。left: 视口左坐标。right:视口右坐标。......

2022-08-12 08:31:57 388

原创 初识OpenGL (4)链接着色器

如果要使用刚才编译的着色器我们必须把它们链接(Link)为一个着色器程序对象,然后在渲染对象的时候激活这个着色器程序。已激活着色器程序的着色器将在我们发送渲染调用的时候被使用。就快要完成了,但还没结束,OpenGL还不知道它该如何解释内存中的顶点数据,以及它该如何将顶点数据链接到顶点着色器的属性上。当链接着色器至一个程序的时候,它会把每个着色器的输出链接到下个着色器的输入。在glUseProgram函数调用之后,每个着色器调用和渲染调用都会使用这个程序对象(也就是之前写的着色器)了。...

2022-07-21 08:22:44 271

原创 初识OpenGL (3)片段着色器(Fragment Shader)

计算像素最后的颜色输出。片段着色器只需要一个输出变量,这个变量是一个4分量向量,它表示的是最终的输出颜色,我们应该自己将其计算出来。声明输出变量可以使用out关键字,这里我们命名为FragColor。step2.编译片段着色器。step1.片段着色器。...

2022-07-21 08:19:11 904

原创 初识OpenGL (2)编译着色器

首先我们定义一个整型变量来表示是否成功编译,还定义了一个储存错误消息(如果有的话)的容器。如果编译失败,我们会用glGetShaderInfoLog获取错误消息,然后打印它。检测调用glCompileShader后编译是否成功了,如果没成功的话,你还会希望知道错误是什么,这样你才能修复它们。eg.顶点着色器,传递的参数是GL_VERTEX_SHADER。如果编译的时候没有检测到任何错误,顶点着色器就被编译成功了。第二参数指定了传递的源码字符串数量,这里只有一个。第一个参数要编译的着色器对象。......

2022-07-21 08:10:07 786

原创 初识OpenGL (1)VBO顶点缓冲对象

eg.说一个缓冲中的数据将频繁被改变,那么使用的类型就是GL_DYNAMIC_DRAW或GL_STREAM_DRAW,这样就能确保显卡把数据放在能够高速写入的内存部分。从这一刻起,我们使用的任何(在GL_ARRAY_BUFFER目标上的)缓冲调用都会用来配置当前绑定的缓冲(VBO)。OpenGL有很多缓冲对象类型,顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER。参数一目标缓冲的类型,顶点缓冲对象当前绑定到GL_ARRAY_BUFFER目标上。GL_DYNAMIC_DRAW数据会被改变很多。.....

2022-07-19 07:55:10 428

原创 OpenGL渲染管道

在所有对应颜色值确定以后,最终的对象将会被传到最后一个阶段,本阶段检测片段的对应的深度(和模板(Stencil))值(后面会讲),用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。几何着色器的输出会被传进来,这里它会把图元映射为最终屏幕上相应的像素,生成供片段着色器(FragmentShader)使用的片段(Fragment)。顶点着色器接着会处理我们在内存中指定数量的顶点。将顶点着色器输出的所有顶点作为输入(如果是GL_POINTS,那么就是一个顶点),并所有的点装配成指定图元的形状。...

2022-07-16 20:40:27 250

原创 ui属性系统(1)VSProperty

ui属性

2022-07-05 09:02:17 110

原创 c++新特性11 (5) stdarray

std::array 对象的大小是固定的,如果容器大小是固定的,那么可以优先考虑使用 std::array 容器。 另外由于 std::vector 是自动扩容的,当存入大量的数据后,并且对容器进行了删除操作, 容器并不会自动归还被删除元素相应的内存。// CPP program to demonstrate working of array#include <algorithm>#include <array>#include <iostream>#inc.

2022-05-13 07:52:26 237

原创 GLFW (3)简单示例

#include <GLFW/glfw3.h>int main(void){ GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(640, 480, "Hello

2022-04-28 22:34:51 665

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除