Alpha其作用是要实现一种半透明效果。

假设一种不透明的东西颜色是A,另一种透明的东西颜色是B,那么透过B去看A,看上去的颜色C就是B与A的混合颜色。设置B的透明度为alpha(取值为0-1,0为完全透明,1为不透明)

R(C)=alpha*R(B)+(1-alpha)*R(A)

G(C)=alpha*G(B)+(1-alpha)*G(A)

B(C)=alpha*B(B)+(1-alpha)*B(A)

融合因子

首先,Direct3D中依然是用Alpha通道来实现多个像素颜色值的融合。每个像素都包含四个分量:Alpha分量、红色分量、绿色分量和蓝色分量(即ARGB四分量)。其中,Alpha分量用于指定像素的透明度,在0~255之间取值,0表示完全透明,255表示完全不透明。另外,根据使用的不同的颜色宏的区别,还可能是在0.0~1.0之间取值。

在Direct3D中,融合这一领域有一个权威,那便是Alpha融合公式。Alpha融合公式如下:

其中RGB_src 和RGB_dst分别表示源像素和目标像素的颜色值,为包含四个颜色分量的颜色值。

K_src 和K_dst分别表示源融合因子和目标融合因子。他们指定了源像素和目标像素的颜色值在融合过程中所占的比例,在[0,1]之间取值。通过原融合因子和目标融合因子,我们能够以多种方式来修改源像素和目标像素的颜色值,从而获得我们满意的最终的融合后的颜色值。稍后会讲解融合因子的具体取法,这里我们先把这个融合公式解析完。

在融合公式中,OP表示源和目标的融合运算方式,由D3DBLENDOP枚举体来指定,需要注意的是它的默认值是源计算结果和目标计算结果相加。

上面我们刚提到过,融合运算方式由D3DBLENDOP枚举体来指定。

我们指的是SetRenderState中的第二个参数在D3DBLENDOP枚举体中取值,而第一个参数,取D3DRS_BLENDOP。

这一节就来看一下这个D3DBLENDOP枚举体的定义:

typedef enum D3DBLENDOP {
D3DBLENDOP_ADD = 1,
D3DBLENDOP_SUBTRACT = 2,
D3DBLENDOP_REVSUBTRACT = 3,
D3DBLENDOP_MIN = 4,
D3DBLENDOP_MAX = 5,
D3DBLENDOP_FORCE_DWORD = 0x7fffffff
} D3DBLENDOP, *LPD3DBLENDOP; 我们用一个列表来进行讲解吧:

D3DBLENDOP操作符

精析

D3DBLENDOP_ADD

源像素计算结果与目标像素的计算结果相加,即【最终结果】=【源】+【目标】

D3DBLENDOP_SUBTRACT

源像素计算结果与目标像素的计算结果相减,即【最终结果】=【源】-【目标】

D3DBLENDOP_REVSUBTRACT

目标像素的计算结果减去源像素计算结果,即【最终结果】=【目标】-【源】

D3DBLENDOP_MIN

在源像素计算结果和目标像素计算结果之间取小者。即【最终结果】= MIN(【目标】,【源】)

D3DBLENDOP_MAX

在源像素计算结果和目标像素计算结果之间取大者。即【最终结果】= MAX(【目标】,【源】)

 

源融合因子和目标融合因子可以在SetRenderState方法中第一个参数取D3DRS_SRCBLEND和D3DRS_DESTBLEND分别进行设置,而第二个参数都是在一个D3DBLEND枚举体中进行的取值,我们在MSDN中查到它的原型如下:

typedef enum D3DBLEND {
D3DBLEND_ZERO = 1,
D3DBLEND_ONE = 2,
D3DBLEND_SRCCOLOR = 3,
D3DBLEND_INVSRCCOLOR = 4,
D3DBLEND_SRCALPHA = 5,
D3DBLEND_INVSRCALPHA = 6,
D3DBLEND_DESTALPHA = 7,
D3DBLEND_INVDESTALPHA = 8,
D3DBLEND_DESTCOLOR = 9,
D3DBLEND_INVDESTCOLOR = 10,
D3DBLEND_SRCALPHASAT = 11,
D3DBLEND_BOTHSRCALPHA = 12,
D3DBLEND_BOTHINVSRCALPHA = 13,
D3DBLEND_BLENDFACTOR = 14,
D3DBLEND_INVBLENDFACTOR = 15,
D3DBLEND_SRCCOLOR2 = 16,
D3DBLEND_INVSRCCOLOR2 = 17,
D3DBLEND_FORCE_DWORD = 0x7fffffff
} D3DBLEND, *LPD3DBLEND;

依旧是通过一个表格来对其中常用的参数进行讲解,:

D3DBLEND融合类型

精析

D3DBLEND_ZERO

融合因子=(0,0,0,0)

D3DBLEND_ONE

融合因子=(1,1,1,1)

D3DBLEND_SRCCOLOR

融合因子=(R_src,G_src,B_src,A_src)

D3DBLEND_INVSRCCOLOR

融合因子=(1- R_src,1-G_src,1-B_src,1-A_src )

D3DBLEND_SRCALPHA

融合因子=(1- A_src , A_src , A_src , A_src )

D3DBLEND_INVSRCALPHA

融合因子=( 1- A_src , 1- A_src , 1- A_src , 1- A_src )

D3DBLEND_DESTALPHA

融合因子=( A_dst , A_dst, A_dst  , A_dst)

D3DBLEND_INVDESTALPHA

融合因子= (1- A_dst , 1- A_dst , 1- A_dst , 1- A_dst ).

D3DBLEND_DESTCOLOR

融合因子=( R_dst , G_dst, B_dst  , A_dst).

D3DBLEND_INVDESTCOLOR

融合因子= ( 1 - R_dst, 1 - G_dst, 1 - B_dst, 1 - A_dst).

D3DBLEND_SRCALPHASAT

融合因子= (f, f, f, 1),其中f = min(A_src,1 - A_dst)

在上表中, R_src  , G_src , B_src  , A_src 分别表示源(即source)像素的红、绿、蓝、透明四个分量值,而 R_dst  , G_dst, B_dst  , A_dst 表示目标(即destination)像素的红、绿、蓝、透明四个分量值。

大家需要什么类型的融合因子,在上表中进行查阅就行了。

Alpha的三处来源

我们在使用Alpha融合之前,还需要明确源像素和目标像素颜色值的Alpha分量来自何方。像素的Alpha值一般有三处来源,分别是顶点颜色的Alpha值、材质的Alpha值、纹理的Alpha值。我们通常在这三处来源中取一处就可以了。它们的优先级是这样的,纹理>材质>顶点颜色。

1.顶点Alpha分量

 

首先我们要知道,顶点Alpha分量只是备胎的备胎而已,它在没有使用光照和材质的情况下才有上场的机会。

如果在程序中直接指定每个顶点的颜色,那么可以直接给出每个顶点颜色的Alpha值,并且这些顶点的Alpha值是可以在程序运行过程中动态修改的。

我们可以通过IDirect3DDevice9::SetTextureStageState方法指定Alpha值的来源,把第三个参数指定为D3DTA_DIFFUSE,来指定Alpha值来自顶点颜色。

在MSDN中查到这个函数原型如下:

HRESULT SetTextureStageState(
[in] DWORD Stage,
[in]D3DTEXTURESTAGESTATETYPE Type,
[in] DWORD Value
);

■第一个参数,DWORD类型的Stage,指定当前设置的纹理层为第几层(有效值0~7)

■第二个参数,D3DTEXTURESTAGESTATETYPE类型的Type,填将要设置的纹理渲染状态,在枚举类型D3DTEXTURESTAGESTATETYPE中任意取值。

■第三个参数,DWORD类型的Value,表示所设置的状态值,它是根据第二个参数来决定具体取什么值的。

对于顶点Alpha分量,我们就这样来两句:

//计算漫反射颜色的alpha值
g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

2.材质的Alpha分量

 

之前部分我们讲的材质的Alpha分量,充其量也只是个备胎而已,在场景内的物体没有指定纹理的时候,才有用武之地。在这种情况下,顶点的Alpha值取决于材质属性中漫反射颜色的Alpha系数以及灯光颜色中的Alpha系数,通过材质和光照中的Alpha系数相互作用,计算得到。我们知道,顶点的光照计算过程是分别针对红、绿、蓝、Alpha这四个颜色分量分开独立计算的。而我们关注的顶点的Alpha值就决定于光照计算结果的Alpha分量,和其他的红、绿、蓝三个分量毫无瓜葛。

比如我们可以这样来设定某材质的Alpha分量值,这句代码中我们把这种材质的漫反射颜色值的Alpha分量设为了0.2(范围为0.0~1.0)

g_pMaterial].Diffuse.a= 0.2f;

3.纹理的Alpha分量

 

作为不可一世的“高富帅”——纹理,既然它在物体表面上使用了,就必须首先满足它的要求,那么,像素的Alpha值就是纹理Alpha混合之后的值了。

所以这时候混合后的像素就取决于纹理的Alpha混合方式。而纹理Alpha混合方式决定了纹理Alpha混合之后的Alpha值是取自材质,还是取自纹理,抑或是取自这两者的某种运算。

若是取自纹理,我们就这样写:

m_pd3dDevice->SetTextureStageState( 0,D3DTSS_ALPHAARG1, D3DTA_TEXTURE );// Alpha值是取自材质
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); //将纹理颜色混合的第一个参数的ALPHA值用于输出

我是旁白:可以使用DirectX SDK中提供的DirectX Texture Tool来为我们的素材纹理图片创建Alpha通道

Alpha融合使用三步曲

1. 三步曲之一:启用Alpha融合

在Direct3D中,混合默认是被关闭着的,要启用Alpha融合的话,我们就通过设置D3DRS_ALPHABLENDENABLE渲染状态为true,即写上这句代码:

m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

2. 三步曲之二:设置融合因子

启用了Alpha融合,第二步便是设置源融合因子和目标融合因子。前面我们已经详细讲解过源融合因子和目标融合因子的取值。源融合因子和目标融合因子分别可以在SetRenderState方法中第一个参数取D3DRS_SRCBLEND和D3DRS_DESTBLEND分别进行设置,第二个参数都是在一个D3DBLEND枚举体中进行的取值。

比如这样写,就是源融合因子=( A_src , A_src , A_src , A_src),目标融合因子=(1- A_src , 1-A_src , 1-A_src , 1-A_src ),这是我们最常用的Alpha混合因子取法:

//设置融合因子
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

3. 三步曲之三:设置Alpha融合运算方式

因为Direct3D中有默认的融合运算方式D3DBLENDOP_ADD,即源像素计算结果与目标像素的计算结果相加。所以这一步其实可以省略,但是如果不想用这种融合运算方式,我们可以加上这一步,用SetRenderState方法来改成我们需要的运算方式,比如如下的代码,便将融合运算方式改成了D3DBLENDOP_SUBTRACT,即源像素计算结果与目标像素的计算结果相减:

g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);

4. 以代码为载体理解

依旧是把这三步曲整合一下,在Direct3D中运用Alpha混合技术,其实最少只用写3句代码,第三步通常可以省略,即如下的代码:

        // 三步曲之一,开启Alpha融合
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
//三步曲之二,设置融合因子
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
//三步曲之三,设置融合运算方式
g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); //这句设置运算方式为D3DBLENDOP_ADD的代码Direct3D默认为我们写了,所以注释掉这句也没大碍

alpha通道与混合技术的更多相关文章

  1. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记8——载入三维模型&Alpha混合技术&深度测试与Z缓存

    第17章 三维游戏模型的载入 主要是如何从3ds max中导出.X文件,以及如何从X文件加载三维模型到DirextX游戏程序里.因为复杂的3D物体,要用代码去实现,那太反人类了,所以我们需要一些建模软 ...

  2. 什么是Alpha通道?

    图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么?  Alpha通道是计算机图形学中的术语,指的是特别的 ...

  3. Alpha通道

     Alpha通道是计算机图形学中的术语,指的是特别的通道,意思是“非彩色”通道,主要是用来保存选区和编辑选区.真正让图片变透明的不是Alpha 实际是Alpha所代表的数值和其他数值做了一次运算  为 ...

  4. PorterDuffXfermode 图像混合技术在漫画APP中的应用

    此文已由作者游葳授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 写在开头 随着应用开发的深入,视觉同学在完成了页面的基本设计后,再也按耐不住心中的寂寞,开始对各种细节不满意, ...

  5. OpenGL核心技术之混合技术

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者.国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  6. 如何基于纯GDI实现alpha通道的矢量和文字绘制

    今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...

  7. ImagXpress中如何修改Alpha通道方法汇总

    ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...

  8. 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

  9. 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

随机推荐

  1. android------eclipse运行错误提示 Failed to load D:\Android\sdk\build-tools\26.0.0-preview\lib\dx.jar

    更新了SDK后,在ecplise上运行项目时出现了一个问题. 一运行就提示这个错误:Your project contains error(s), please fix them before run ...

  2. Flex scroller皮肤的使用

    Flex4 scroller 自定义皮肤 十月 15, 2010 Posted by admin flex4里引入了sparkSkin, spark包里的可视控件可以通过指定skinClass的值来修 ...

  3. 创建gitlab ssh 密钥

    SSH代表用于管理网络,操作系统和配置的Secure Shell或Secure Socket Shell,并且每次都不需要使用用户名和密码即可验证GitLab服务器. 您可以设置SSH密钥以提供计算机 ...

  4. Luffy之虚拟环境.项目搭建,目录日志等配置信息

    1. 项目开发前 1.1 虚拟环境virtualenv 如果在一台电脑上, 想开发多个不同的项目, 需要用到同一个包的不同版本, 如果使用上面的命令, 在同一个目录下安装或者更新, 新版本会覆盖以前的 ...

  5. Appium移动自动化测试(一)----Appium的安装

    前言: 我的环境为win10 64,安装过程请根据自己的电脑环境而定. 一.Appium安装 1.Appium官方网站:http://appium.io/下载windows版本的Appium; Eas ...

  6. js操作字符串的常用方法

    使用 substring()或者slice() 函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str=”jpg|bmp|gif|ico|png”; arr=the ...

  7. Oracle11g温习-第十一章:管理undo

    2013年4月27日 星期六 10:40 1.undo tablespace 功能 undo tablespace 功能:用来存放从datafiles 读出的数据块旧的镜像 [             ...

  8. Oracle 11.2.0.4.0 Dataguard部署和日常维护(6)-Active Dataguard篇

    1. 检查主备库的状态 on primary column DATABASE_ROLE format a20 column OPEN_MODE format a15 column PROTECTION ...

  9. [luogu P3382] 三分法

    [luogu P3382] 三分法 题目描述 如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减.试求出x的值. 输入输出格式 输入格式: 第一行一次 ...

  10. Nginx基本

    静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片)通过HTTP协议展现给客户端.配置: server { listen ; # 端口号 locati ...