alpha通道与混合技术
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通道与混合技术的更多相关文章
- 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记8——载入三维模型&Alpha混合技术&深度测试与Z缓存
第17章 三维游戏模型的载入 主要是如何从3ds max中导出.X文件,以及如何从X文件加载三维模型到DirextX游戏程序里.因为复杂的3D物体,要用代码去实现,那太反人类了,所以我们需要一些建模软 ...
- 什么是Alpha通道?
图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么? Alpha通道是计算机图形学中的术语,指的是特别的 ...
- Alpha通道
Alpha通道是计算机图形学中的术语,指的是特别的通道,意思是“非彩色”通道,主要是用来保存选区和编辑选区.真正让图片变透明的不是Alpha 实际是Alpha所代表的数值和其他数值做了一次运算 为 ...
- PorterDuffXfermode 图像混合技术在漫画APP中的应用
此文已由作者游葳授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 写在开头 随着应用开发的深入,视觉同学在完成了页面的基本设计后,再也按耐不住心中的寂寞,开始对各种细节不满意, ...
- OpenGL核心技术之混合技术
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者.国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...
- 如何基于纯GDI实现alpha通道的矢量和文字绘制
今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...
- ImagXpress中如何修改Alpha通道方法汇总
ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...
- 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
- 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
随机推荐
- 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 ...
- Flex scroller皮肤的使用
Flex4 scroller 自定义皮肤 十月 15, 2010 Posted by admin flex4里引入了sparkSkin, spark包里的可视控件可以通过指定skinClass的值来修 ...
- 创建gitlab ssh 密钥
SSH代表用于管理网络,操作系统和配置的Secure Shell或Secure Socket Shell,并且每次都不需要使用用户名和密码即可验证GitLab服务器. 您可以设置SSH密钥以提供计算机 ...
- Luffy之虚拟环境.项目搭建,目录日志等配置信息
1. 项目开发前 1.1 虚拟环境virtualenv 如果在一台电脑上, 想开发多个不同的项目, 需要用到同一个包的不同版本, 如果使用上面的命令, 在同一个目录下安装或者更新, 新版本会覆盖以前的 ...
- Appium移动自动化测试(一)----Appium的安装
前言: 我的环境为win10 64,安装过程请根据自己的电脑环境而定. 一.Appium安装 1.Appium官方网站:http://appium.io/下载windows版本的Appium; Eas ...
- js操作字符串的常用方法
使用 substring()或者slice() 函数:split() 功能:使用一个指定的分隔符把一个字符串分割存储到数组 例子: str=”jpg|bmp|gif|ico|png”; arr=the ...
- Oracle11g温习-第十一章:管理undo
2013年4月27日 星期六 10:40 1.undo tablespace 功能 undo tablespace 功能:用来存放从datafiles 读出的数据块旧的镜像 [ ...
- 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 ...
- [luogu P3382] 三分法
[luogu P3382] 三分法 题目描述 如题,给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减.试求出x的值. 输入输出格式 输入格式: 第一行一次 ...
- Nginx基本
静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片)通过HTTP协议展现给客户端.配置: server { listen ; # 端口号 locati ...