图形学理论
专栏主要讲解整理图形学方面的知识。
皮皮虾图形学
shader mathematica
mathgraphic@163.com
展开
-
深度测试
应用场景:加亮物体的边缘。 深度缓存会记录场景中物体与视点的距离。深度缓存主要用途是隐藏表面的消除。void glPolygonOffset(GLfloat factor, GLfloat units);//设定偏移值void glPolygonMode();//设定多边形的光栅化方式。/*GL_POLYGON_FILL /LINE /POINT*/ offset = m * factor原创 2017-12-03 09:39:40 · 363 阅读 · 0 评论 -
融混
融混 受alpha值影响的有融混,和顺序无关透明算法OIT(order-independent transparency)。 开始融混,glEnable(GL_BLEND); 融混参数 源混合参数:对应于片元着色器输出颜色。 目标混合参数:帧缓存中已有的颜色值。 最终颜色值:(RdDr+SrRs,GdDg+SgGs,DbBd+SbBs,DaAd+SaAs)\left(R_d D_r+S_原创 2017-12-03 18:32:44 · 375 阅读 · 0 评论 -
抖动
opengl 默认情况下抖动是开启的。 glEnable(GL_DITHER);原创 2017-12-03 18:36:42 · 378 阅读 · 0 评论 -
逻辑操作
输入的片元数据为源。 当前颜色缓存中的数据为目标。 开启 glEnable(GL_COLOR_LOGIC_OP); glLogicOp(GLenum opcode); 默认的操作为GL_COPY s 数据源 d 目标 GL_CLEAR 0 GL_COPY s GL_NOOP d GL_SET 1 GL_COPY_INVERTED ¬\原创 2017-12-03 18:52:18 · 384 阅读 · 0 评论 -
遮挡查询
遮挡查询步骤 1.为每个遮挡查询对象生成一个ID。glGenQueries(GLsizei n, GLuint * ids); glIsQueries(id); 2.glBeginQuery() ,开始遮挡查询。3.渲染几何体,完成遮挡查询测试。 4.glEndQuery(); 完成查询。5.获取本次通过深度测试的样本数量。** GLuint Query;glGenQueries(1,原创 2017-12-04 10:07:45 · 2067 阅读 · 0 评论 -
逐图元的反走样
线段的反走样glPolygonMode(GL_FRONT, GL_LINE);// glEnable(GL_LINE_SMOOTH);// glEnable(GL_BLEND);// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE); Nv原创 2017-12-04 12:59:44 · 341 阅读 · 0 评论 -
帧缓存对象
帧缓存对象的存在意义就是在不同的缓存之间大量迁移数据。将数据的拷贝最小话,达到性能提升的目的。步骤://创建帧缓存对象标识符GLuint id;glGenFrameBuffers(1, &id);//创建对象//GL_DRAW_FRAMEBUFFER写源 GL_READ_FRAMEBUFFER读源 GL_FRAMEBUFFERif(glIsFramebuffer(id)) glBindF原创 2017-12-04 13:52:36 · 667 阅读 · 0 评论 -
多重渲染的同步写入
定义:在一个片元着色器中同时写到多个渲染缓存的能力。MRT设置片元的out变量与帧缓存附件的对应关系。layout (location = 0) out vec4 color; //输出颜色与颜色附件0对应layout (location = 1) out vec4 normal;//输出颜色与颜色附件1对应 选择颜色缓存来进行读写操作设置可以进行写入或者清除操作的颜色缓存。glDrawBuffe原创 2017-12-04 17:59:52 · 418 阅读 · 0 评论 -
双源融混
所谓的双源融混就是片元的两个输出元,作用于同一个帧缓存。 GPU:layout(location = 0, index = 0) out vec4 first_output;layout(location = 0, index = 1) out vec4 second_color;CPU: CHECK_GL_ERROR(); glClear(GL_COLOR_BUFFER_BIT);原创 2017-12-05 10:07:10 · 662 阅读 · 0 评论 -
像素数据的读取和拷贝
glReadPixels(0, 0, mRenderWidth, mRenderHeight, GL_RGBA, GL_UNSIGNED_BYTE, mPixels); 将像素从目标缓存回读到CPU应用程序当中。glMapBuffer()返回缓存对象管理的显存指针映射区域。 效率更高。矩形像素区域的拷贝: glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFb原创 2017-12-05 10:35:33 · 879 阅读 · 0 评论 -
法线变换
当法线在物体表面平移的时候,并不会改变法线的值。发现代表着一个空间向量,知道大小相等,方向相同就可以了。 M = mat3(mViewMatrx); n′=nMTn'=\frac{n}{M^T}原创 2017-12-05 10:44:20 · 209 阅读 · 0 评论 -
剪切平面设置
CPU: glEnable(GL_CLIP_PLANE0); GPU:float gl_ClipDistance[1];//使用一个剪切平面void main(void){ gl_Position = uViewProjMatrix * vec4(aPosition.x, aPosition.y, 0.0, 1.0); gl_ClipDistance[0] = dot(vec原创 2017-12-05 11:03:14 · 2684 阅读 · 0 评论 -
传输反馈 transfrom feedback
可以利用GPU对数据的顶点进行处理。然后返回到CPU内存中,或是用作GPU 端其它用途。 transform feedback 状态是封装在传输反馈对象当中。 状态包括:记录顶点数据的缓存对象,标识缓存对象充满程度计数器,以及当前是否启用。 glGenTransformFeedbacks(numFeedbacks,m_transformFeedback); glDeleteTransfo原创 2017-12-06 09:23:02 · 476 阅读 · 0 评论 -
glTexStorage* 与 glTexImage*的优势与劣势
glTexStorage* 为指定的纹理创建固定存储。也就是分配的存储空间不可改变,这样就可以让纹理对象停止跟踪纹理的某些方面。 而纹理中的内容可以使用glTexSubImage* 来改变。 实验: 将一个从文件读取的图像数据,进行处理,之后进行输出流程。 CPU: 初始化 读取纹理数据。 创建纹理对象。 分配存储空间。 将纹素数据导入纹理对象。 绘制将纹理对象绑定到纹理单元。原创 2017-12-06 10:49:40 · 6092 阅读 · 0 评论 -
将图像数据存储进纹理的几种方法
1.显示方式static const GLubyte texdata1[] = { 0xFF,0x00,0xFF,0x00};static const GLfloat tex_color_data[] = {1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,};g原创 2017-12-06 13:10:02 · 1174 阅读 · 0 评论 -
纹理对象 缓存对象 纹素直接的数据流向关系
数据流向关系图原创 2017-12-06 13:35:20 · 325 阅读 · 0 评论 -
阴影贴图
阴影贴图的原理:就是利用阴影采样器获取一个[0,1.0]之间的浮点值,来控制模型表面光照强度。假设最终输出色outColor,模型在一点处的光照值P。阴影强度值I 。有outColor = I*P; 1.生成一张离眼睛距离的深度信息图。 2.将模型在局部坐标下的位置变换到光锥坐标系下,再进行投影变换。变换到NDC坐标系下。将范围调整到【0,1】.3.利用这个坐标对深度纹理进行采样。采样的时候会原创 2017-12-07 18:01:48 · 443 阅读 · 0 评论 -
高级纹理查询函数
sampler ——-> texture samplerBuffer —–>textelFetch 对于具有细节层次贴图的纹理 textureLod(gsmapler* tex, vec, float lod);//lod 为细节层次,显示控制细节层次。计算mipmap级别: minMap:滤波后的图像存储为完整的低分辨率版本。 细节层级由像素和纹理中的纹素的比值决定的。 使用m原创 2017-12-09 10:03:15 · 3021 阅读 · 0 评论 -
绘制天空盒
原理: 创建一个立方体,并且视点在立方体的中心。在立方体的每个面上贴上大小相同的六个立方体纹理。 这个也可以用作目前比较流行的全景图。 方法: 1.创建一个以人眼为中心的立方体。 2.创建构建这个立方体的索引。 3.创建一个立方体纹理。 4.使用立方体着色器采样这个纹理。立方体纹理的创建: init()GLuint tex; glGenTextures(1, &tex);glBi原创 2017-12-09 10:38:32 · 839 阅读 · 0 评论 -
HLSL 与 GLSL 之间的映射关系参考
系统参数与內建的输入参数Direct3D有很多系统参数,而相应的,GLSL也有內建的输入参数的概念。他们的对应关系如下:HLSLGLSLSV_ClipDistancegl_ClipDistanceSV_CullDistance当存在ARB_cull_distance情况下gl_CullDistanceSV_Coveragegl_SampleMaskIn & gl_SampleMaskSV_Depth转载 2017-12-09 10:50:16 · 2154 阅读 · 0 评论 -
基于索引绘制glDrawElement
GPU: vertex shaderuniform mediump mat4 uViewProjMatrix;varying lowp vec4 vColor;void main(void){ gl_Position = uViewProjMatrix * vec4(aPosition.x, aPosition.y, 0.0, 1.0); vColor = vec4(aPosit原创 2017-12-09 18:24:30 · 1219 阅读 · 0 评论 -
glVertexAttribPointer 用法简介
在内存中采用交叉模式存储,向gpu传入顶点数据的方法 GPU:#version 100attribute highp vec2 aPosition;attribute highp vec2 aTexcoord;CPU: init()//将顶点数组元素都存入一个缓存对象中 static const float position[] = { -1.0f, -1.0f,原创 2017-12-09 19:09:41 · 24597 阅读 · 0 评论 -
投影纹理与最小细节层级的混合应用
void Basic::genfloorTex(){ m_sourceImage = NvImage::CreateFromDDSFile("textures/flower1024.dds"); GLint w = m_sourceImage->getWidth(); GLint h = m_sourceImage->getHeight(); GLint intFo原创 2017-12-09 21:58:39 · 278 阅读 · 0 评论 -
glBufferSubData
glBufferSubDataglBufferSubData用来更新一个已有缓冲区对象中的一部分数据void glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);参数: target: 可以参考glBufferData中的描述,用来指定需转载 2017-12-12 15:44:35 · 3685 阅读 · 0 评论 -
法线贴图的生成
计算法线贴图,就需要找到一个合适的坐标空间进行计算。这里选择模型表面坐标空间,也就是切空间。因为纹理是贴合到模型表面上的,所以可以认为纹理u的方向为切线方向,v为副法线方向。cross(u,v)计算出法线方向。纹理u的水平变化方向为dFdx(u),垂直dFdy(v). 因为计算出的法线值为-1 1。所以还要进行偏移。 RGB=dFdx(u),dFdy(v),cross(dFdx(u),dFdy(v)原创 2017-12-19 09:52:01 · 2027 阅读 · 1 评论 -
opengl 独立着色器对象的使用
独立着色器对象,可以对管线的各个阶段进行动态组合,使得对某一个管线阶段的代码进行复用。注意的问题: 获取uniform变量和设置uniform变量。设置的是某个程序对象的uniform而不是管线对象的。例子代码: 创建createShaderPipelineProgram(GLuint target, const char * src){ GLuint object; GLin原创 2017-12-21 11:57:52 · 946 阅读 · 0 评论 -
关于模型视图矩阵的相机
模型视图矩阵就是以眼睛为坐标系的原点建立的空间参考直角坐标系。建立模型视图矩阵的过程,就是建立让相机模型与世界坐标系重合的过程。第一人称是先进行缩放变换*再进行平移变换,变换到与世界坐标系重合*再进行旋转变换。return xf.m_rotateMat * xf.m_translateMat * xf.m_scaleMat;轨道相机:先进行缩放,在进行旋转,再平移到与世界坐标系原创 2017-12-22 11:43:18 · 667 阅读 · 0 评论 -
glsl 细分着色器
注意问题:1.glDrawElements(GL_PATCHES, 4, GL_UNSIGNED_SHORT, (const GLvoid *)0); 最后指针要转换为const GLvoid * 形式,避免用NULL,否则会引起可能的调用崩溃问题。2.采用独立着色器时候,要注意重新定义块。详细见下面代码。 四边形细分域的演示:定义一个四边形。static const float positio原创 2017-12-22 13:36:16 · 1058 阅读 · 0 评论 -
在glsl 中模拟包含头文件的方法
小技巧:1.可以利用宏定义来控制着色器所使用的uniform块和C++中结构体定义的不同地方进行分离。2.可以在应用程序中控制要定义和使用哪些宏定义来在编译着色器的时候动态设置开关。因为着色器的源码最后可以由多个字符串进行拼接而成。 3.在着色器中设置一个标识符,之后在程序中进行替换 例如 #UNIFORMS。#UNIFORMS//设置输出每个面片的控制点数目layout (vertices原创 2017-12-22 17:23:42 · 858 阅读 · 0 评论 -
opengl glsl 几何着色器 1
几何着色器的作用是: 1.增强多顶点的访问属性。 2.控制输出数据的数量。 3.在管线中改变几何体类型。 4.将顶点数据流切分为多个子数据流。 使用方法: 设置输入图元类型,输出图元类型,以及输出的顶点数量。 layout(triangles) in; layout(triangle_strip,max_vertices = 3) out; 几何着色器的输出只能为条带。 poin原创 2017-12-24 12:35:49 · 811 阅读 · 0 评论 -
glsl 原子操作 基础(一)
layout( r32ui) uniform uimage2D overdraw_count;void main(){ uint count = imageLoad(overdraw_count,ivec2(gl_FragCoord.xy)); count = count + 1; imageStore(output_buffer, ivec2(gl_FragCoord.原创 2017-12-25 10:15:20 · 1137 阅读 · 0 评论 -
glsl 高性能原子计数器
主要讲解知识点: 1.GL_ATOMIC_COUNTER_BUFFER 使用。 2.采用原子计数器记录片元中的红色通道分量大于绿色分量的个数。 效果验证图: 可以看到统计结果,并且得出当我们放大图片的时候,处理的片元数量是增大的,缩小的时候GPU处理的片元数量减少。实现: 初始化原子缓存对象glBindBuffer(GL_ARRAY_BUFFER, 0); GLuint *co原创 2017-12-29 09:59:04 · 638 阅读 · 0 评论 -
opengl Order-Independent Transparency 顺序无关的透明 (一)
Order-independent transparency (OIT) is a class of techniques in rasterisational computer graphics for rendering transparency in a 3D scene, which do not require rendering geometry in sorted order for原创 2018-01-02 10:05:59 · 4609 阅读 · 1 评论 -
glsl 计算着色器基础 一
计算着色器主要是利用着色器的资源来处理一些与渲染不相关的其它计算工作。 任务以组为单位执行,称为工作组。拥有邻居的工作组称为本地工作组,本地工作组组成最大的组称为全局工作组。计算着色器会被全局工作组中的每一个本地工作组的每个单元调用一次,执行的单元之间可以通过变量和显存进行通信,并且可以通过同步操作进行同步。 本地工作组大小设置: local_size_x /y /z 全局工作组的布局,g原创 2018-01-04 22:09:16 · 960 阅读 · 0 评论 -
glsl 可编程着色器可能的应用范围
现在可编程流水线还能处理所有像素、顶点、纹理的位置、色调、饱和度、明度、对比度并实时地绘制图像。着色器还能产生如模糊、高光、有体积光源、失焦、卡通渲染、色调分离、畸变、凹凸贴图、边缘检测、运动检测等效果。这些应用领域将会在之后逐渐推出,敬请关注。原创 2018-01-04 22:14:26 · 363 阅读 · 0 评论 -
glsl内置函数 1
Radians degrees sinh cosh exp e^x exp 2^x log2 log sqrt inversesqrt abs sign floor ceil trunc 2.1–>2 -2.5—>-2 round 返回一个最接近x的整数值。 Ceil fract 取小数部分 Mod x = y*(x/y) modf(x,out i) re原创 2018-01-05 21:46:50 · 841 阅读 · 0 评论 -
glsl应用 计算着色器 之 简单的图像写入
这个例子主要简单的往图像中写入数据。然后将写入的数据进行渲染。 在计算着色器中,对每个本地工作组的每个运行单元写入其在本地工作组的位置进行归一化,然后将这个数据作为输出颜色的x,y通道。所以对一个本地工作组内计算的片元颜色变化规律为: 这个计算着色器程序的整体任务分配布局为: 最后输出的效果为: 总结: 可以看到有颜色的地方为计算着色器工作的区域。每个小块为一个本地工作组。每个计算原创 2018-01-06 16:57:01 · 710 阅读 · 0 评论 -
瑞利散射 Rayleigh theory
一种光学现象,属于散射的一种情况。又称“分子散射”。粒子尺度远小于入射光波长时(小于波长的十分之一),其各方向上的散射光强度是不一样的,该强度与入射光的波长四次方成反比,这种现象称为瑞利散射。中文名瑞利散射外文名Rayleighscattering相关术语大气散射学科分支大气物理学描述瑞利散射规律是由英国物理学家瑞利勋爵(Lord Rayleigh)于190转载 2018-01-16 16:14:44 · 7983 阅读 · 0 评论 -
mie 散射理论
由基础物理知识可知,光与物质的相互作用会引起光的吸收、色散和散射现象。所谓光 的散射可以这样理解:当光束通过存在不均匀性的透明或半透明介质(比如硅胶中悬浮着荧 光粉),光线就会从各个方向散开。1908年G.Mie最先解出了入射到悬浮着球形粒子的介质 的平面光波的麦克斯韦方程组的严格解,关于这方面的讨论就是Mie散射理论的主要内容。 按照Mie散射理论,第一,当散射粒子的半径远小于入射光的波长时,总转载 2018-01-16 16:15:59 · 11469 阅读 · 0 评论