混合、反走样、雾效、多边形偏移

来源:互联网 发布:变年轻的软件 编辑:程序博客网 时间:2024/05/16 15:36
混合:介绍如何指定混合函数,它通过将源颜色和目标颜色混合,使场景的某些部分为半透明;
反走样:反走样通过修改颜色来消除点、线、多边形边缘的棱角和锯齿;多重采用是一种强大的反走样技术,适用于所有的图元;
雾:描述如何根据物体到视点的距离来计算物体的颜色值,以创建立体感效果,使远方的物体看起来已经融入到场景中;
点参数:讨论一种高效的技术,用于根据距离视点的距离渲染大小和颜色不同的点图元。在模拟粒子系统方面很有用。
多边形偏移:当线框物体和填充物体重合时,看起来可能很丑陋;使多边形偏移,改变其深度值,可以使带轮廓的物体更美观。
 
混合
    混合功能启用时,alpha值用于在在处理的片元的颜色值与存储在帧缓存中的像素颜色值合并。将场景光栅化并转换为片元后执行混合操作,最后将像素写入到帧缓存中。
输入片元颜色值(Rs, Gs, Bs, As), 帧缓存中的颜色(Rd, Gd, Bd, Ad), 源因子(Sr, Sg, Sb, Sa),目标因子(Dr, Dg, Db, Da);
则最终的颜色为(Rs*Sr+Rd*Dr, Gs*Sg+Gd*Dg, Bs*Sb+Bd*Db, As*Sa+Ad*Da),并截取到[0,1]。
选择源因子和目标因子的方式有两种:
1. glBlendFunc(GLenum srcfactor, GLenum destfactor);指定混合因子的计算方法
2. glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcalpha, GLenum destalpha);指定混合因子
常量      RGB混合因子     alpha混合因子
GL_ZERO     (0, 0, 0)      0
GL_ONE      (1, 1, 1)      1
GL_SRC_COLOR     (Rs, Gs,  Bs)     As
GL_ONE_MINUS_SRC_COLOR   (1,1,1)-(Rs, Gs, Bs)    1-As
GL_DST_COLOR     (Rd, Gd, Bd)     Ad
GL_ONE_MINUS_DST_COLOR   (1,1,1)-(Rd, Gd, Bd)    1-Ad
GL_SRC_ALPHA     (As, As, As)     As
GL_ONE_MINUS_SRC_ALPHA   (1,1,1)-(As, As, As)    1-As
GL_DST_ALPHA     (Ad, Ad, Ad)     Ad
GL_ONE_MINUS_DST_ALPHA   (1,1,1)-(Ad, Ad, Ad)    1-Ad
GL_CONSTANT_COLOR    (Rc, Gc, Bc)     Ac
GL_ONE_MINUS_CONSTANT_COLOR  (1,1,1)-(Rc, Gc, Bc)    1-Ac
GL_CONSTANT_ALPHA    (Ac, Ac, Ac)     Ac
GL_ONE_MINUS_CONSTANT_ALPHA  (1,1,1)-(Ac,Ac ,Ac)    1-Ac
GL_SRC_ALPHA_SATURATE   (f,f,f);f=min(As, 1-Ad)    1
使用GL*CONSTANT*为参数时,需指定一个常量
glBlendColor(GLclampf red, GLclampf green , GLclampf blue, GLclampf alpha)
启用混合
glEnable(GL_BLEND);
禁用
glEnable(GL_BLEND);
例程:blendeqn.cpp
使用混合方程合并像素
在混合时也可以指定其他运算方式:
glBlendEquation(GLenum mode);
Cs, Cd为源颜色和目标颜色, S, D为原混合因子和目标混合因子
GL_FUNC_ADD    Cs*S+Cd*D
GL_FUNC_SUBTRACT   Cs*S-Cd*D
GL_FUNC_REVERSE_SUBTRACT  Cd*D-Cs*S
GL_FUNC_MIN    min(Cs*S, Cd*D)
GL_FUNC_MAX    max(Cs*S, Cd*D)

使用深度缓存的三维混合:
特点:透明物体在前时,后面的物体都要绘制,透明物体在不透明物体后时不需要绘制。所以要对深度缓存进行控制。
方法:首先向深度缓存设置为正常,绘制所有不透明物体,然后将深度缓存设置为只读,绘制半透明物体时,将其与深度缓存比较,如果他们位于不透明物体后面,将不绘制,如果这些透明物体更近,则绘制并混合在一起,因为深度缓存不变,所以不会消除后面的不透明物体。
glDepthMask();
GL_FALSE;将深度缓存设置为只读。
GL_TRUE;设置为正常。
例程:alpha3D.cpp
 
反走样
Opengl根据片元覆盖了像素方块中的多少面积来计算覆盖比例。在RGBA模式下,Opengl将片元覆盖比例与alpha值相乘,并将乘积作为alpha值来将片元与帧缓存中的对应像素进行混合。在颜色索引模式下,Opengl根据片元的覆盖比例来设置颜色索引的后四位(没有覆盖时为0000,完全覆盖时为1111)。
glHint(GLenum target, GLenum hint);
提供在图像质量和速度间进行选择的建议,但opengl不一定会采纳。
target
GL_POINT_SMOOTH_HINT   
GL_LINE_SMOOTH_HINT    反走样操作中,直线、点或多边形的采样质量
GL_POLYGON_SMOOTH_HINT
GL_FOG_HINT     对每个像素(GL_NICEST)还是每个原点(GL_FASTEST)执行雾效计算
GL_PERSPECTIVE_CORRECTION_HINT  颜色和纹理坐标插值的质量:在屏幕空间中进行线性插值,或以透视修正的方式进行插值。
GL_GENERATE_MIPMAP_HINT   自动生成的mipmap的质量和性能
GL_TEXTURE_COMPRESSION_HINT  纹理图像的压缩质量和性能

点和直线的反走样
方法:1. 使用GL_POINT_SMOOTH, GL_LINE_SMOOTH调用glEnable();
2. 使用glHint();提出质量建议
3. 使用多重采用
1. RGBA模式下的反走样
在RGBA模式时需要启用混合功能,最常用的混合因子是GL_SRC_ALPHA(源)和GL_ONE_MINUS_SRC_ALPHA(目标)。也可以将目标因子设置为GL_ONE, 使直线的相交处更亮。
在三维时需要按照循序进行绘制。
2. 颜色索引模式下的反走样
需要加载16个相邻的索引,其中第一个必须为16的倍数,它们对于与颜色从背景色渐变到物体的颜色。然后用第一个索引值对应的颜色作为清空颜色缓存,然后使用加载的颜色绘制点或直线。

多重采用对几何图元进行反走样处理
多重采用非常适合对多边形的变进行反走样处理。
多重采用基本原理:多重采样是一种使用更多的颜色、深度和样板信息对OPENGL图元进行反走样处理的技术。计算反走样覆盖比例时,不使用表示图元对像素覆盖比例的alpha值,而是使用存储在多重采样缓存中的样本。
使用步骤:
1. 打开一个支持多重采样的窗口。
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE);
2. 确定其是否支持多重采样。
查询状态变量GL_SAMPLE_BUFFERS时返回1;
查询GL_SAMPLES时返回子像素样本数返回值大于1;则可以使用多重采样。
3. 打开多重采样。
glEnable(GL_MULTISAMPLE);
 
glEnable(GL_FOG);启用雾效
glHint提供了处理效果建议GL_FOG_HINT
glFog*设置各个参数
GL_FOG_MODE
GL_FOG_COLRO
GL_FOG_DENSITY
GL_FOG_START
GL_FOT_END
雾方程式
雾是根据雾混合因子将雾颜色与片源颜色进行混合得到了,这个因子f是根据以下3个方程计算得到的:
f = e^(density*z)*(GL_EXP);
f = e^-((endsity*z)^2)*(GL_EXP2);
f = (end - z) / (end - start)*(GL_LINEAR)
最终的雾是:
C = f*Ci + (1-f)*Cf;
雾坐标
可以调用glFog(GL_FOG_COORD_SRC, GL_FOG_COORD)显示的指定每一个顶点的z值
glFogCoord*()指定坐标
点参数
模拟点物体的远近,根据远近对物体的大小进行修改。
可以使用glPointSize();指定点的大小
glEnable(GL_POINT_SMOOTH)启动点的平滑处理
点参数根据点和观察点的距离,对点的大小和亮度进行衰减。可以使用glPointParameterf*();指定衰减方程式的系数和点alpha成分
void glPointParameterf(GLenum pname, GLfloat param)
void glPointParameterfv(GLenum pname, GLfloat* param)
如果pname为GL_POINT_DISTANCE_ATTENUATION,param为包含了(常数、线性、二次衰减系数)的数组。d为点与观察点的距离
derivedSize = clamp(size*sqrt(1/(a+b*d+c*d^2)))
如果pname为GL_POINT_SIZE_MIN,GL_POINT_SIZE_MAX,param是一个限制对上一步经过计算得到的点大小进行截取。
如果启用的多重采用pname是GL_FADE_THRESHOLD_SIZE,param是制定了点大小的不同的底限。如果derivedSize < threshold,就用fade因子对点的alpha值进行调整,衰减它的亮度
fade = (derivedSize/threshold)^2
 
多边形偏移
当着重显示实心物体边缘是,可以用GL_FILL绘制这个物体,在用GL_LINE重新绘制这个物体,但是由于直线和填充的方式绘制opengl所产生的深度值并不完全相同,因此其可能受重叠的多边形影响,显示效果忽浓忽淡。
多边形偏移将着重显示的多边形边缘与多边形分离。
三种方法启用多边形偏移分别用于不同的多边形光栅化模式:
GL_FILL,GL_LINE,GL_POINT,再想glEnable传递适当参数:GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, GL_POLYGON_OFFSET_POINT,再用glPolygonMode()设置光栅化模式;
glPolygonOffset(GLfloat factor, GLfloat units)
设置计算偏移值参数:o = m*factor+r*units,m是多边形的最大深度斜率, r是保证能够产生可解析区别的窗口坐标深度值的最小值,是一个特殊的实现常数。
深度斜率m是当穿越一个多边形z值的变化除以x或y值的变化所得的值。
m = max{|det(V)/det(s)|, |det(v)/det(t)|}
对于深度斜率接近0的多边形,可以指定一个很小的偏移量,factor = 0.0, units = 1.0.
对于角度大的多边形可以指定一个较小的factor如(0.75, 1.0)就可以产生很好的效果。