zoukankan      html  css  js  c++  java
  • Alpha混合(一)Vertex Alpha

    Vertex alpha

    Alpha混合通常是为了实现透明效果,透明效果的程度通过alpha值来控制,对于一个8bit的alpha chanel,可以产生0-255级透明效果,0表示完全透明,255表示完全不透明,在D3D中alpha值的来源主要有三种

    • 顶点
    • 材质
    • 纹理

    今天介绍如何使用顶点的alpha值来实现透明效果,为了简化程序,我们使用顶点的alpha值来控制顶点的颜色,不涉及到纹理。关于如何使用material alpha及Texture alpha将在后续的篇章中介绍。

    定义顶点格式

    我们使用Lit顶点格式,也就是无需光照,顶点本身包含颜色值,所以顶点格式如下。

    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)

    定义顶点

    { 0.0f, 0.0f, -1.0f, 0x8000ff00 };

    这里只选取一个顶点作为示例。前三个值表示顶点的位置,最后一个值表示顶点的颜色,在D3D中,颜色用一个DWORD表示,其格式如下,最高位的一个byte表示alpha值,随后三个byte分别表示红绿蓝三原色。每个值的范围都是00-ff(十六进制),即十进制0-255。

    所以对于0x8000ff00这个值,80表示alpha值,00ff00表示颜色,显然是绿色。

    设置diffuse color的来源为顶点diffuse color

    在D3D中,Diffuse color(漫反射颜色)一共有三种来源:

    • D3DMCS_MATERIAL, 使用当前的material颜色
    • D3DMCS_COLOR1      使用顶点的diffuse(漫反射)颜色,这也是D3D的默认值。
    • D3DMCS_COLOR2      使用顶点的specular(镜面反射)颜色

    为了使用顶点的alpha值,我们需要将diffuse color的来源设置为D3DMCS_COLOR1。

    g_pd3dDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );

    启用alpha混合功能

    g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

    设置颜色

    下面需要设置一些列的纹理状态,虽然我们只使用顶点,而未使用纹理,但是设置颜色和alpha值都需要通过纹理状态函数来完成。这段代码的意义是先选择两个颜色来源,然后指定一个施加在这两个颜色上的操作,从代码可知,第一个颜色是顶点的颜色,第二个是纹理的颜色,颜色操作是D3DTOP_SELECTARG1,也就是直接选择第一个颜色(顶点颜色)。纹理颜色被丢弃,所以第二行可有可无。

    //Set the color to come completely from the vertex color
    g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); //Ignored g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);

    设置alpha值

    下面这段代码和上面设置颜色的代码道理相同,选择两个alpha值来源,然后指定一个施加在两个alpha值上的操作,这里同样只选择顶点的alpha值,因为我们就是想使用它!

    //Set the alpha to come completely from the vertex diffuse
    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1,  D3DTA_DIFFUSE);
    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2,  D3DTA_TEXTURE);   //Ignored
    g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,    D3DTOP_SELECTARG1);

    混合

    混合公式

    OutputPixel = SourcePixel SourceBlendFactor + DestPixel DestBlendFactor

    • OutputPixel—混合后的颜色

    • SourcePixel—源像素,即当前正在计算的像素的颜色

    • SourceBlendFactor—源颜色的百分比

    • DestPixel—目标像素,即已经绘制的像素颜色(在back buffer中)

    • DestBlendFactor—目标像素颜色的百分比

    表示分量乘积

    真正的混合操作由下面的代码完成,第一行指定源像素的混合因子,这里是D3DBLEND_SRCALPHA,也就是使用顶点的alpha值,源像素即当前正在计算的像素,第二行指定目标像素的混合因子,这里是D3DBLEND_INVSRCALPHA,也就是1减去顶点的alpha值。目标像素是指当前已经绘制在backbuffer中的像素,由于我们只绘制了一个物体,所以目标像素为空。第三行是混合操作,相加,这也是D3D的默认值。

    g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
    g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
    g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

    效果图

    下面是使用Vertex alpha和Vertex color混合的结果,根据alpha值的不同,可以产生不同级别的透明效果,这四幅图的alpha值依次是20, 80, C0和FF。

    Happy coding!!!

    ==

    作者:zdd
    出处:http://www.cnblogs.com/graphics/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    Java集合(容器)学习
    Java中最基本的集合接口:初识Collection
    Java中的Overload和Override有什么区别
    Java程序国际化学习代码一
    Java中的io流学习(了解四大基类和基本步骤)
    忘记电脑连过的WiFi的密码了,但又想知道,该怎么办?
    你真的理解了for循环吗?反正我是没有
    Java中的“==操作符”和equals方法有什么区别
    Java中final、finally、finalize有什么区别?
    Thread--线程工作万花筒
  • 原文地址:https://www.cnblogs.com/graphics/p/2643086.html
Copyright © 2011-2022 走看看