我的世界GLSL吃鸡需要多少显存存

glsl 缓冲帧怎样访问已经渲染好的像素_百度知道
glsl 缓冲帧怎样访问已经渲染好的像素
我有更好的答案
2以后可以同时使用多种资源.7;资源包/resourcepacks的里面,也可以在游戏中的选项&#47,有凹凸质感的材质这是R3D材质包,添加了对应的法线贴图的效果天空贴图材质是把MC的天空渲染的更真实的材质还有声音材质,可以让我的世界的声音变的和谐点的资源在1.minecraft\打开资源文件夹还有一种特殊的光影,就是体积云光影,你发的图就是体积云的光影而不是材质开光影需要一个叫GLSL光影渲染器的mod法线贴图材质是可以造成视差的材质,装上这个mod后会在.minecraft里生成一个叫shaderpacks的文件夹,就是同时用材质 天空贴图 声音资源等等资源包资源包放在,光影包就放在.minecraft\shaderpacks,然后在选项里面生成一个新的按钮点击光影按钮就可以打开选择光影的界面了要光影mod光影包,著名显卡杀手的材质R3D法线贴图整合材质
采纳率:64%
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。OpenGL/GLSL数据传递小记(3.x)—Shader技术-ZwqXin
OpenGL/GLSL数据传递小记(3.x)
OpenGL/GLSL规范在不断演进着,我们渐渐走进可编程管道的时代的同时,崭新的功能接口也让我们有点缭乱的感觉。本文再次从OpenGL和GLSL之间数据的传递这一点,记录和介绍基于OpenGL3.x的新方式,也会适时介绍Unform Buffer Objecct(UBO)这一重要特性。&&.com本文可视为大致一年半前的本博客的[]一文的延续。对这方面不熟悉的话请先浏览一下该文中介绍的基本概念。在该文中,我把这些传递分为attribute变量、uniform变量、varying变量和Fragment Shader输出,这四部分(主要讲述前两部分)。而本文再次按此四部分,谈谈在GL3.x(NVidia 8Series以后显卡所支持的OpenGL版本)中的数据传递方式的变化。本文来源于 ZwqXin (), 转载请注明&&&&&&原文地址:1. attribute变量在前文中提及到GLSL中每一个attribute变量都有一个&位置&值(Location),在ShaderProgram链接(link)前,可以Bind之,链接之后,可以Get之。通过这两种方式都可以建立attribute变量与顶点属性的联系。如今引入第三种方式&&直接在GLSL代码中指定这些位置值:
#version&330&&
layout(location&=&0)&in&vec3&attrib_&&
layout(location&=&1)&in&vec2&attrib_&&
layout(location&=&2)&in&vec3&attrib_&&
layout(location&=&3)&in&int&&attrib_&&在上面的Vertex Program代码中,第一行(#version&330),表明我们现在使用的GLSL版本是GLSL3.3,以区别于以前的版本并允许我们使用基于GLSL3.3的功能。在过去,OpenGL的版本和GLSL版本是不统一的(前文中的GL2.2所对应的是GLSL1.2,而后来的对应关系是GL3.0-GLSL1.3,GL3.1-GLSL1.4,GL3.2-GLSL1.5),直到2010年OpenGL3.3/4.0规范的提出,khronos委员会决定让两者版本统一,所以就有了现在本博客所使用的OpenGL3.3-GLSL3.3的对应关系(注,ShaderModel4.0的显卡可达到的最高版本)。接下来的几行声明了4个attribute变量。在GL2.x中一个attribute变量通常是&attribute vec3 attrib_&这样来表示,在GL3.x中,废弃了attribute关键字(以及varying关键字),属性变量统一用in/out作为前置关键字,对每一个Shader stage来说,in表示该属性是作为输入的属性,out表示该属性是用于输出的属性。这里,attribute变量作为Vertex Shader的顶点输入属性,所以都用in标记。另外,这里使用了layout关键字(通常是layout(layoutAttrib1=XXX, layoutAttrib2=XXX, ...)这样的形式)。这个关键字用于一个具体变量前,用于显式标明该变量的一些布局属性,这里就是显式设定了该attribute变量的位置值(location),其作用跟ShaderProgram(着色程序)链接前调用glBindAttribLocation来设定atribute变量的位置值是等效的。为什么采用这种方式更好呢?其一当然是编码量减少了,二来也避免了去Get某个attribute的location带来的开销,三来,最重要的是,它重定义了OpenGL和GLSL之间attribute变量属性的依赖。过去我们的OpenGL端必须首先要知道GLSL端某个attribute的名字,才能设置/获得其位置值,如今两者只需要location对应起来就可以完成绘制时顶点属性流的传递了。不再需要在ShaderProgram的compile和link之间插入代码也更方便于其模块化。2.uniform变量对于uniform变量的声明方式,跟GL2.x的一致,使用uniform关键字就可以了。
#version&330&&
uniform&sampler2D&&&basetex1;&&
uniform&float&fAlphaRestrictV&&
uniform&mat4&matM&&
uniform&mat4&matV&&
uniform&mat4&matP&&每一个uniform变量也都有其一个&位置值&(Location),在OpenGL中,我们可以通过glGetUniformLocation来获得。那么我们可以不可以像attribute变量那样,在Shader代码中显式指定这个Location呢?(其好处也是跟上述差不多的,但就是如果uniform变量太多的话这样做也麻烦,因为得在代码中一个一个指定不重复的location。)嘛,attribute变量location的显式指定,是经由GL扩展GL_ARB_explicit_attrib_location实现的,而事实上,现在也有GL_ARB_explicit_uniform_location这样一个GL扩展,能实现这样的功能,只不过它是OpenGL4.3标准的一部分,隶属于GLSL4.3,所以即使GL3.x支持这个扩展,我们还是暂时不要用的好。那我们就像往常一样,在glUseProgram启用了某个ShaderProgram之后,一个一个地给每个unifom变量关联数据咯(通过其location)&&等等,这是在运行期间设置数据值吧,那如果我这个关联数据并不是每帧都变化的,甚至它是一个固定值,这样做岂不太无聊太浪费了?事实上我们还是可以在glUseProgram之外绑定数据的&&乃至直接在初始化时。这得益于glProgramUniform系列函数的引入,它比起往常的glUniform要多一个参数用来接收一个ShaderProgram的ID。在建立ShaderProgram后,我们也不需要glUseProgram来预先绑定它就可以直接取得某个uniform变量的location值并用glProgramUniform系列函数关联数据,而且这个数据在其后运行期间的每次glUseProgram后都不会失效。从理论上将,这族函数完全可以替代glUniform系列函数(是它们功能的一个超集),但是就不知道会不会有性能上的损失了(这个暂时目前找不到说法),所以我暂时建议是只对那些非动态变化的uniform变量使用了。再来看看uniform变量的问题。通常一个稍微复杂点点、更多控制参数的Shader,都会有大量的Uniform变量需要设置,所以导致了我们很多时候在glUseProgram之后要调用一长串的glUniform函数来传递该Pass的数据。有没有方法尽量把这些操作合并呢?另外,我们知道一个Shader的可用Uniform数据大小是有一个上限值的(例如我目前显卡的一个vertex shader的GL_MAX_VERTEX_UNIFORM_COMPONENTS值是4096,意味着我在一个VertexShader里使用的active uniforms,大概就是最多4096个float/int值了,或者说最多1024个vec4、最多256个mat16),那么有没办法提高这个上限呢?在[]这篇文章中,因为担心uniform数量不足以支撑传入的众多个骨骼矩阵,所以优先选择TBO(Texture Buffer Object)作为传入数据的媒介,把数据装入一个一维纹理的Buffer中以提供给Shader。那么除了使用纹理数据外,还有没有更直接的方式呢?&Uniform Buffer Object(UBO)UBO,顾名思义,就是一个装载Uniform变量数据的Buffer Object。就概念而言,它跟VBO([] )之类Buffer Object差不多,反正就是显存中一块用于储存特定数据的区域了。在OpenGL端,它的创建、更新、销毁的方式都与其他Buffer Object没什么区别,我们只不过把一个或多个uniform数据交给它,以替代glUniform的方式传递数据而已。这里必须明确一点,这些数据是给到这个UBO,存储于这个UBO上,而不再是交给ShaderProgram,所以它们不会占用这个ShaderProgram自身的uniform存储空间,所以UBO是一种全新的传递数据的方式,从路径到目的地,都跟传统uniform变量的方式不一样。自然,对于这样的数据,在Shader中不能再使用上面代码中的方式来指涉了。随着UBO的引入,GLSL也引入了uniform block这种指涉工具。
#version&330&&
layout(std140)&uniform&matVP&&
&&&mat4&matP&&
&&&mat4&matV&&
};&&uniform block是Interface block的一种,(layout意义容后再述)在unifom关键字后直接跟随一个block name和大括号,里面是一个或多个uniform变量。一个uniform block可以指涉一个UBO的数据&&我们要把block里的uniform变量与OpenGL里的数据建立关联。 因为这些uniform变量不是存储在Shader的&uniform区域&里的,所以也就没有那一套&位置值&(location),那么我们通过什么建立关联呢?对于每一个uniform block,都有一个&索引值&(index),这个索引值我们可以在OpenGL中获得,并把它与一个具体的UBO关联起来。这样block内的数据声明就会与UBO中的实质数据联系起来了:
GLint&nMatVPBlockIndex&=&glGetUniformBlockIndex(nProgramHandler,&&matVP&);&&
if&(GL_INVALID_INDEX&!=&nMatVPBlockIndex)&&
&&&&GLint&nBlockDataSize&=&0;&&
&&&&glGetActiveUniformBlockiv(nProgramHandler,&nMatVPBlockIndex,&GL_UNIFORM_BLOCK_DATA_SIZE,&&nBlockDataSize);&&
&&&&glGenBuffers(1,&&m_nUBO);&&
&&&&glBindBuffer(GL_UNIFORM_BUFFER,&m_nUBO);&&
&&&&glBufferData(GL_UNIFORM_BUFFER,&nBlockDataSize,&NULL,&GL_DYNAMIC_DRAW);&&
&&&&glBindBufferRange(GL_UNIFORM_BUFFER,&0,&m_nUBO,&0,&nBlockDataSize);&&
&&&&glUniformBlockBinding(nProgramHandler,&nMatVPBlockIndex,&0);&&
&&&&glBindBuffer(GL_UNIFORM_BUFFER,&NULL);&&
}&&一般我们可以使用glGetUniformBlockIndex来获取这个Index,但扩展GL_ARB_program_interface_query引入了比较统一的获取ShaderProgram内资源的相关属性的API(详见此扩展的spec),所以也可以以)相关联:把它们都关联到同一个uniform buffer binding-point。其中前者通过glUniformBlockBinding来完成,其中第三个参数是GL_MAX_UNIFORM_BUFFER_BINDINGS的个数为36,这表示同一时间能映射的UBO-uniform block关系最多只有36对(间接也限制了一个ShaderProgram中uniform block的个数),哪怕你有大量的UBO,为了以上机制的实行,也只能接受这个限制。我们就是通过glUniformBlockBinding来&通知&ShaderProgram某个uniform block的数据信息存储在哪个binding-point上。如果把glUniformBlockBinding当成glUniform族函数,这个操作会更亲切一点:只不过如今对于目标block使用的是Index而不是Location(事实上它的行为更类似上面提到的glProgramUniform族函数,因为不需要事先glUseProgram启用某个ShaderProgram而是作为首参罢)。除了UBO,前面某篇博文[]中提到的Transform Feedback Buffer也是使用binding-point(参见文中代码段)的&好手&。因为Shader同样需要快速找出需要feedback的那个Buffer的所在地,尤其是通过GL_SEPARATE_ATTRIBS的方式为每一个输出数据独立指定buffer时,就需要用到多个transform-feedback binding-point来储存各个buffer的信息了。其限制个数其实就是GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS了(本显卡此数字为4)。这里引出一个问题:我们能不能像TransformFeedback那样,为一个UBO对象非配数个binding-point呢?可以的。这样做的目的也很明确&&单个UBO多个uniform-block。准确地说,是每个uniform block对应该UBO存储区域中不同的分区域(sub-region)&&
GLint&nMatVPBlockIndex&=&glGetUniformBlockIndex(nProgramHandler,&&matVP&);&&
GLint&nCloudScaleIndex&=&glGetUniformBlockIndex(nProgramHandler,&&Scale&);&&
if&(GL_INVALID_INDEX&!=&nMatVPBlockIndex&&&&GL_INVALID_INDEX&!=&nCloudScaleIndex)&&
&&&&int&nUniformBufferAlignSize&=&0;&&&
&&&&glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,&&nUniformBufferAlignSize);&&&
&&&&GLint&nBlockDataSize1&=&0,&nBlockDataSize2&=&0;&&
&&&&glGetActiveUniformBlockiv(nProgramHandler,&nMatVPBlockIndex,&GL_UNIFORM_BLOCK_DATA_SIZE,&&nBlockDataSize1);&&
&&&&glGetActiveUniformBlockiv(nProgramHandler,&nCloudScaleIndex,&GL_UNIFORM_BLOCK_DATA_SIZE,&&nBlockDataSize2);&&
&&&&glGenBuffers(1,&&m_nUBO);&&
&&&&glBindBuffer(GL_UNIFORM_BUFFER,&m_nUBO);&&
&&&&glBufferData(GL_UNIFORM_BUFFER,&nUniformBufferAlignSize&+&nBlockDataSize2,&NULL,&GL_DYNAMIC_DRAW);&&
&&&&glBindBufferRange(GL_UNIFORM_BUFFER,&0,&m_nUBO,&0,&nBlockDataSize1);&&
&&&&glUniformBlockBinding(nProgramHandler,&nMatVPBlockIndex,&0);&&
&&&&glBindBufferRange(GL_UNIFORM_BUFFER,&1,&m_nUBO,&nUniformBufferAlignSize,&nBlockDataSize2);&&
&&&&glUniformBlockBinding(nProgramHandler,&nCloudScaleIndex,&1);&&
}&&上面代码段中,我们把两个uniform-block关联到同一个UBO的两个区域:[0 ~ nBlockDataSize1]、[nUniformBufferAlignSize ~ nUniformBufferAlignSize+nBlockDataSize2]。为什么第二个block不是映射到[nBlockDataSize1 ~&nBlockDataSize1+nBlockDataSize2]呢?这里有个比较重要的概念:数据对齐。对于uniform-block,可以通过GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT找出这个对齐值(本显卡上此数值是256字节,所以每个uniform block都是256字节对齐,相邻uniform block的间隔必须满足256字节的整数倍,否则会发现数据会对不上)。记住了,block与block的数据不是紧紧pack在一起的。很容易想象,跟CPU上存储结构体一样,这是为了数据存取效率考虑,至于为什么是这个值,就要更深入研究了。麻烦可不止这一个&&单个uniform-block里面的数据,也有字节对齐的机制&&这给uniorm变量的数据更新带来更大的麻烦。先来大致了解一下的uniform block前面的layout内容。一般uniform block按数据组织类型可分为三种(目前):packed、shared、std140,我们可以在它们前面用layout去指定该block属于哪种类型(也可以全局设置,也就是把layout单独作为一语句,此时它影响随后的各个没前接layout的uniform block)。UBO的一个最显眼的好处就是实现数据共享。譬如我上面的matPV这个uniform block就是最好的例子:通常渲染场景时,只会有一个视图矩阵和一个投影矩阵([]
[] ),而且它们相对每一帧都是固定数据。而我们可能场景里物件用到的Shader不一样,但它们都得通过这两个矩阵计算最终的顶点输出啊?以前的话,我得每个Shader都传一次这些相同的矩阵数据,不仅时间上glUniform族函数会比较多而且空间上也分别占每个ShaderProgram本身的同等的存储资源。如今把它们统一在一个UBO中,每帧更新就只要更新UBO一次就可以了,而且也只占一份的资源空间(在显存上)。为什么突然插播以上&广告&呢?因为这对数据组织形式影响甚大。为了实现数据共享,必须保证各个shader里的指涉该UBO的unifom block&一模一样&。但我们也知道([] ),GLSL编译器会检查并自动删掉那些非active(在shader中没有实质用途)的uniform变量。那么,假如我们的多个Shader里都有相同的uniform block,而里面某个变量x被ShaderA用到而没背ShaderB用到,那么前者就会把它默默删掉,这样数据结构不统一,自然映射到同一个UBO也无法预计得到各个子数据的具体位置(必须得针对每个Shader的uniform block内每个变量查询它的Offset)&&block内的这种&检查&机制由packed这种layout掌控,为了要关闭这种机制,就需要选择其他三种layout。而shared(顺带一提,这个是默认layout)与std140不同之处在于,它虽然不会&删掉&block内的non-active变量,而且保证这些uniform block内的数据在存储分布上的一致性(所以各个shader能共享同一个block结构),但它不会去固定统一存储分布,所以还是有必要去查询各个变量的offset(因为可能在显卡A上这个offset是16在显卡B上就变32了)。至于std140等,其实就是排除这些因素而有着严格限制的一个数据组织结构&无优化&的版本,所以一般的场合下我们应该首选这类std(OpenGL-Standard)的layout。顺带说一下因为最初UBO/uniform block是跟随OpenGL3.1/GLSL1.4引入的所以有此std140之名(其实现存的类似layout还有个std430,但它是专门留给OpenGL/GLSL4.3的storage buffer block产生更小的offset而用的,按此不表)。说了那么多,既然一般应用首选std140,那么它那个固定的offset是多少呢?根据我的不严格查验(没验证多个显卡),其值为16字节,也就是说数据按16字节对齐。而数据中还再分为vector、数组、矩阵这些,也是按类似规则限制(不一一举出,查spec去吧)。举例一下吧:
layout(std140)&uniform&matVP&&
&&&float&elapsedT&&
&&&mat4&matP&&
&&&mat4&matV&&
layout(std140) uniform Scale
& uniform float cloudS
};要更新这两个block对应的那个UBO,应该这样:
&&&&glBindBuffer(GL_UNIFORM_BUFFER,&m_nUBO);&&
&&&&glBufferSubData(GL_UNIFORM_BUFFER,&0,&sizeof(GLfloat),&&fElapsed);&&
&&&&glBufferSubData(GL_UNIFORM_BUFFER,&16,&sizeof(Matrix16),&m_mtProj.mt);&&
&&&&glBufferSubData(GL_UNIFORM_BUFFER,&16&+&sizeof(Matrix16),&sizeof(Matrix16),&m_mtView.mt);&&
&&&&glBufferSubData(GL_UNIFORM_BUFFER,&256,&sizeof(GLfloat),&&fCScale);&&
&&&&glBindBuffer(GL_UNIFORM_BUFFER,&NULL);&&
}&&其实UBO除了能够共享unifom变量数据外,上面的叙述还隐含有它的两个重要优点:一点是索引、切换binding-point的速度比较快,比起多个glUniform的调用传递数据也更快;另一点是对于显存中的uniform数据,可用的存储空间也大幅增加(而且对比TBO,UBO更适合需要线性存取的数据)&&这回应了介绍UBO前的。UBO的介绍暂到此为止,真的很费口水&&因为我觉得它本身就是包含不少要点的OpenGL功能&&其实要点还不止这些,也还是需要更进一层地了解才行。uniform数据应尽量使用UBO来存放,尤其是那些需要Shader共享的数据,当然了零碎细小的数据还是glUniform/glProgramUniform类函数会更方便点吧~3.varying变量&varying变量主要用于在Shader Stage间进行传递,注意的是在光栅化(Rasterization)的时候,这些变量也会跟着一起被光栅插值。那如果我们不想某个顶点属性被光栅化,该怎么办呢?在[]这篇文章提到的一个古老API,glShadeModel,它在固定管道渲染流水线上能起到控制图元属性是否被插值的功效(需要光栅化时传入参数GL_SMOOTH,不需要时传入GL_FLAT),那么当选择不插值时(GL_FLAT),流水线上发生了什么呢?假设现在流水线上,经过裁剪、归一化等,生成了一个屏幕上的三角图元(三个顶点上的颜色属性分别是c1、c2、c3),进入光栅化阶段。假如进行插值,三角图元里各像(假设共n个)素会根据其各自位置对三个顶点的颜色值进行线性插值,生成对应的n个颜色值(cList[n]);假如不插值,则该三角形里所有像素都会是同一个值(cConst),这个值可能等于c1、c2或c3其中一个。到底是哪一个呢?这取决于哪个顶点是provoking-vertex(在[] 中也提及过它)。你可以在OpenGL端通过glProvokingVertex函数改变这个设置(参数GL_FIRST_VERTEX_CONVENTION/GL_LAST_VERTEX_CONVENTION决定取图元绘制顺序的第一个顶点还是最后一个顶点作为provoking-vertex)。其实要让GLSL中某个作为顶点属性的varying变量不被光栅化,只要在它前面加一个flat关键字就可以了。这样它就像上述的那样,到达Fragmen Shader的图元上所有像素的该varying值都是相同的值(provoking vertex上的值):
flat&out&float&&&
flat&in&float&&&同样在[]中也提到这样一个问题:一个ShaderProgram中不能有两个同为输入的同名varing变量,也不能有两个同为输出的同名varing变量存在。所以即使表示的是同一个变量,也得使其名字不一样:
out&vec2&varying_vg_&&&&
in&&vec2&varying_vg_texcoord[];&&&&
out&vec2&varying_gf_&&&&
in&vec2&varying_gf_&&&&这样的话,在有些场合需要实现不同shader的组合&&譬如实现一个可加入也可不加入的Geometry Shader,就难办了(何况当代流水线上的Shader可不止这三个呢)。为解决这个麻烦,也为了把变量声明组织得更&好看&一些,我们再次用到interface block。上面的uniform block是其中一种,但它还包括in block和out block这两种可用于varing变量的:
out&Varying&&
&&&& vec2&&&
}VaryingO&&
in&Varying&&
&&&& vec2&&&
}VaryingIn[];&&
out&Varying&&
&&&&vec2&&&
}VaryingO&&
in&Varying&&
&&&&vec2&&&&&&
}VaryingIn;&&注意这里使用了block insatnce name(紧随大括号后的那个名字),这个名字对各Shader Stage来说都是独特的,所以改成上面这样的话,block之间也不会发生名字冲突,block内的varying变量也就可以用同一个名字了。使用时需要按&blockInstanceName.varyingVariable&的类似结构体内变量的样式来表示:
void&main(void)&&
&&&for(int&i&=&0;&i&&&gl_in.length();&++i)&&
&&&&&&&&gl_Position&=&gl_in[i].gl_P&&
&&&&&&&&VaryingOut.texcoord&=&VaryingIn[i].&&
&&&&EmitVertex();&&
&&&EndPrimitive();&&
}&&block自带组织多个变量声明的功效:
out&Varying&&
&&&&vec3&&&
&&&&int&&&&
&&&&vec3&&&
}VaryingO&&另外,对于Transform Feedback([] ),指定输出Varing属性时,也要按上述的结构体内变量表示法:
const&GLchar&*varyingOutCloudFeed[]&=&{&Varying.position&,&&Varying.cloudcount&,&&Varying.dimension&};&&
glTransformFeedbackVaryings(m_CloudFeedShader.GetProgramHandler(),&3,&varyingOutCloudFeed,&GL_SEPARATE_ATTRIBS);&&
m_CloudFeedShader.Link();&&4.fragmentShader输出最后,再简单谈一下fragmentShader的输出。一般来说,输出的是颜色值,输出目标是Frame Buffer。这又包括常规的输出到屏幕Buffer、输出到FBO([] ),另外还可以通过MRT(Multi Render Target)输出到两个以上的FBO中。但是,这些对于Fragment Shader来说并没太多不一样:通过ShaderProgram链接前的glBindFragDataLocation指定输出到第几个Buffer(默认是0)。类似于,我们也可以直接通过layout来指定这个location值:
layout(location&=&0)&out&vec4&fragC&&
layout(location&=&0)&out&vec4&fragColor0;&&
layout(location&=&1)&out&vec4&fragColor1;&&
...&&然后只要在FragmentShader中把结果对应地赋给这些输出型变量就可以了。但是,这些layout里的关键字其实还有个index&&只是默认为0而已:
layout(location&=&0,&index&=&0)&out&vec4&fragC&&
layout(location&=&0,&index&=&1)&out&vec4&src1C&&它们同样是输出到第0个缓冲区,但是其中有一个的index为1&&这个src1Color是所谓的Second Output。它同样储存在一块缓冲区域中,但我们在OpenGL中怎么获得这个区域的颜色值呢?答案就是由GL_ARB_blend_func_extended扩展引入的,新的混合参数(GL_SRC1_COLOR/GL_SRC1_ALPHA等等这类新旧的enum)。它们作为混合因子而存在&&这里输出的src1Color,就只能作为各个对应像素混合因子来用。简单举例:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,&GL_SRC1_COLOR);&&该代码启用混合,当前绘制的内容(混合源src,即fragColor)的混合因子是自己的alpha值,而背景(混合目标dst,即绘制前此FrameBuffer的内容)处对应的被覆盖像素的混合因子则是该对应像素输出的src1Color值,其中RGBA分量分别用于混合RGBA四个通道:finalColor = sourceColor * sourceAlpha + destinationColor * src1Color&好了,本文于此结束。如有批误或疏忽提醒,请大牛们不腻赐教或指出给,谢谢。本文来源于 ZwqXin (), 转载请注明&&&&&&原文地址:
&&( 12:35:8)&&( 15:20:34)&&( 15:55:31)&&( 10:57:23)&&( 15:5:43)&&( 15:30:17)&&( 14:46:59)&&( 15:43:51)&&( 14:50:43)&&( 17:11:7)
博主文章写的很用心,从里面学到了不少的东西,部分内容我会转载到我的Blog
&.helloworld
太感謝了,聽君一文,勝過苦讀一年
&.Dragonfly
gluniformblockbinding() 我看有的地方说(http://book.2cto.com/28.html
) 要在GlLinkProgram之前调用.可是没链接没法GlGetUniformBlockIndex呀? 求教 先谢谢了o(∩_∩)o zwqxin 于
17:08:40 回复看看glProgram*开头的一簇API
寫得真好,受教了
Powered By

我要回帖

更多关于 绝地求生要多少显存 的文章

 

随机推荐