【寒江雪】纹理混合的实现

来源:互联网 发布:淘宝店铺入口 编辑:程序博客网 时间:2024/04/30 05:49

Alpha混合技术

  Alpha通道是计算机中存储一张图片的透明和半透明信息的通道。它是一个8位的灰度通道,用256级灰度来记录图像中的透明度信息,定义透明,不透明和半透明区域,其中黑色表示全透明,白色表示不透明,灰表示半透明.
  混合的英文术语为Blending,是计算机图形学中常用的一种技术,即混合像素。我们通常用已经光栅化的像素光栅化同一位置的像素,或者说是在某图元上混合图元。
  关于混合方面的基本知识与Direct3D9是一样的,还是附上我的笔记


http://blog.csdn.net/lkysyzxz/article/details/53855999


Direct3D11中的实现纹理混合

创建ID3D11BlendState

  在Direct3D11中,混合状态默认是关闭的.要打开混合状态,需要把描述混合状态的信息设置到上下文中.混合状态的信息由ID3D11BlendState接口保存.
  创建ID3D11BlendState首先需要描述状态信息,然后通过设备接口的CreateBlendState来描述.
  我们把状态信息写在一个叫做D3D11_BLEND_DESC的结构体里面.该结构体的组成成分如下:

typedef struct D3D11_BLEND_DESC {  BOOL                           AlphaToCoverageEnable;  BOOL                           IndependentBlendEnable;  D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[8];} D3D11_BLEND_DESC;
  • BOOL AlphaToCoverageEnable:当把一个像素设置到目标渲染视图的时候,该参数定义了是否需要多重采样
  • BOOL IndependentBlendEnable:该参数表明是否使用多个目标渲染视图.设为false表示只针对RenderTarget[0]设置绘制混合状态
  • D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[8]:表示对多个目标渲染视图混合状态的描述.

      对于D3D11_RENDER_TARGET_BLEND_DESC结构体,它的组成成分如下:
typedef struct D3D11_RENDER_TARGET_BLEND_DESC {  BOOL           BlendEnable;  D3D11_BLEND    SrcBlend;  D3D11_BLEND    DestBlend;  D3D11_BLEND_OP BlendOp;  D3D11_BLEND    SrcBlendAlpha;  D3D11_BLEND    DestBlendAlpha;  D3D11_BLEND_OP BlendOpAlpha;  UINT8          RenderTargetWriteMask;} D3D11_RENDER_TARGET_BLEND_DESC;
  • BOOL BlendEnable:表示是否需要开启混合状态。当然要开啦,所以设为true
  • D3D11_BLEND SrcBlend:混合选项。该参数表明该如何使用像素着色器输出的RGB值作为源混合颜色,也就是RGBsrc
  • D3D11_BLEND DestBlend:混合选项。该参数表明该如何使用当前目标渲染视图中的像素作为目的混合颜色,也就是RGBsrc
  • D3D11_BLEND_OP BlendOp:该参数定义了如何把上边两个参数结合起来
  • D3D11_BLEND SrcBlendAlpha:该参数表明了该如何使用像素着色器输出的Alpha值作为源Alpha
  • D3D11_BLEND DestBlendAlpha:该参数表明了该如何使用目标渲染视图中的像素作为目的Alpha
  • D3D11_BLEND_OP DestBlendAlpha:该参数表明了该如何结合上边两个Alpha数据
    UINT8 RenderTargetWriteMask:写入掩码.设为D3D11_COLOR_WRITE_ENABLE_ALL即可.

      D3D11_BLEND的结构:
typedef enum D3D11_BLEND {  D3D11_BLEND_ZERO              = 1,  D3D11_BLEND_ONE               = 2,  D3D11_BLEND_SRC_COLOR         = 3,  D3D11_BLEND_INV_SRC_COLOR     = 4,  D3D11_BLEND_SRC_ALPHA         = 5,  D3D11_BLEND_INV_SRC_ALPHA     = 6,  D3D11_BLEND_DEST_ALPHA        = 7,  D3D11_BLEND_INV_DEST_ALPHA    = 8,  D3D11_BLEND_DEST_COLOR        = 9,  D3D11_BLEND_INV_DEST_COLOR    = 10,  D3D11_BLEND_SRC_ALPHA_SAT     = 11,  D3D11_BLEND_BLEND_FACTOR      = 14,  D3D11_BLEND_INV_BLEND_FACTOR  = 15,  D3D11_BLEND_SRC1_COLOR        = 16,  D3D11_BLEND_INV_SRC1_COLOR    = 17,  D3D11_BLEND_SRC1_ALPHA        = 18,  D3D11_BLEND_INV_SRC1_ALPHA    = 19} D3D11_BLEND;


  D3D11_BLEND_OP的结构:

typedef enum D3D11_BLEND_OP {  D3D11_BLEND_OP_ADD           = 1,  D3D11_BLEND_OP_SUBTRACT      = 2,  D3D11_BLEND_OP_REV_SUBTRACT  = 3,  D3D11_BLEND_OP_MIN           = 4,  D3D11_BLEND_OP_MAX           = 5} D3D11_BLEND_OP;

  其中的每个值的含义可以查阅MSDN了.

创建ID3D11RasterizerState

  ID3D11RasterizerState保存着光栅器的信息.
  与ID3D11BlendState一样,在创建之前需要先对其进行描述.通过填充D3D11_RASTERIZER_DESC结构体进行描述.该结构体的内部结构如下:

typedef struct D3D11_RASTERIZER_DESC {  D3D11_FILL_MODE FillMode;  D3D11_CULL_MODE CullMode;  BOOL            FrontCounterClockwise;  INT             DepthBias;  FLOAT           DepthBiasClamp;  FLOAT           SlopeScaledDepthBias;  BOOL            DepthClipEnable;  BOOL            ScissorEnable;  BOOL            MultisampleEnable;  BOOL            AntialiasedLineEnable;} D3D11_RASTERIZER_DESC;
  • D3D11_FILL_MODE FillMode:设置填充模式.只有D3D11_FILL_WIREFRAME和D3D11_FILL_SOLID两种,前者是线框模式,后者是实体模式.
  • D3D11_CULL_MODE CullMode:设置剔除模式.D3D11_CULL_MODE枚举类型有三种剔除模式.

    typedef enum D3D11_CULL_MODE {
    D3D11_CULL_NONE = 1,
    D3D11_CULL_FRONT = 2,
    D3D11_CULL_BACK = 3
    } D3D11_CULL_MODE;

    • D3D11_CULL_NONE:将绘制所有三角形
    • D3D11_CULL_BACK:背面三角形将不绘制
    • D3D11_CULL_FRONT:正面三角形将不绘制
  • BOOL FrontCounterClockwise:标识是否将三角形逆时针设为正面
  • INT DepthBias:深度偏移量。这个值为共面的面定义一个小的偏移量,让共面的物体能正常渲染出来。比如影子和墙面。
  • FLOAT DepthBiasClamp:该定义了深度偏移的最大值,也就是偏移不能超过该值。
  • FLOAT SlopeScaledDepthBias:描述的是偏移量计算公式中的标量斜率.可见这个参数与上边两个参数是一起使用的.
  • BOOL DepthClipEnable:是否要使用深度裁切
  • BOOL ScissorEnable:是否剔除所有在scissor rectangle外的像素
  • BOOL MultisampleEnable:是否使用多重采样
  • BOOL AntialiasedLineEnable:指明是否需要使用线性反走样。只有当在画线和禁用多重采样的情况下才起作用.更多详细信息可以参考MSDN

  下面是一个简单的填充示例:

//关闭背面消隐D3D11_RASTERIZER_DESC ncDesc;ZeroMemory(&ncDesc, sizeof(ncDesc));ncDesc.CullMode = D3D11_CULL_NONE;//剔除特定三角形,这里不剔除任何三角形ncDesc.FillMode = D3D11_FILL_SOLID;//填充模式,这里为利用三角形填充ncDesc.FrontCounterClockwise = false;//是否设置逆时针绕续的三角形为正面ncDesc.DepthClipEnable = true;//开启深度裁剪


  描述完成之后,就可以使用设备接口来创建ID3D11RasterizerState接口了。创建使用设备接口的CreateRasterizerState方法来创建.该方法的原型如下:

HRESULT CreateRasterizerState(  [in]            const D3D11_RASTERIZER_DESC *pRasterizerDesc,  [out, optional]       ID3D11RasterizerState **ppRasterizerState);
  • const D3D11_RASTERIZER_DESC *pRasterizerDesc:填的就是我们刚才描述的结构体的地址
  • ID3D11RasterizerState **ppRasterizerState:该参数为输出参数,我们调用这个方法就是为了初始化这个参数.

设置ID3D11BlendState和ID3D11RasterizerState

  先来说说ID3D11BlendState的设置.设置ID3D11BlendState是通过使用立即执行上下文的OMSetBlendState方法来完成的,该方法的原型定义如下:

void OMSetBlendState(  [in, optional]       ID3D11BlendState *pBlendState,  [in, optional] const FLOAT            BlendFactor[4],  [in]                 UINT             SampleMask);
  • 第一个参数正是我们刚创建好的BlendState
  • 第二个参数是需要程序员手动指定的混合因子,即刚介绍混合因子时,如果指定参数为D3D11_BLEND_BLEND_FACTOR或D3D11_BLEND_INV_BLEND_FACTOR,则使用第二个参数指定的颜色值为了混合因子;
  • 第三个参数是为采样点掩码。D3D11中的多重采样可以支持32个采样点,该参数用来决定”使用/丢弃”哪些采样点。该参数类型为UINT,32位,其中从最低位到最高位分别代表一个采样点。比如,如果第5位指定为0,则第5个采样点将被丢弃。当然,只有当开启至少5重采样时该设定才有效。如果当前设置为单个采样点,则只有最低位才对我们有用。默认情况下,该参数值为0xFFFFFFFF,即对所有采样点有效。

  接下来是设置ID3D11RasterizerState.设置ID3D11RasterizerState是通过立即执行上下文的RSSetState方法完成的。该方法负责设置渲染状态.

void RSSetState(  [in, optional] ID3D11RasterizerState *pRasterizerState);
  • 唯一一个参数,就填刚才创建好的ID3D11RasterizerState接口即可.

  将ID3D11BlendState和ID3D11RasterizerState创建好之后,只需要在使用的时候通过上下文设置一下就行了.
  设置示例如下:

float BlendFactor[] = { 0,0,0,0 };        d3dSys->D3DDeviceContext()->OMSetBlendState(m_pBlendState, BlendFactor, 0xffffffff);        d3dSys->D3DDeviceContext()->RSSetState(m_pRasterizerState);

  有的时候我们还需要恢复设置,恢复的代码如下:

d3dSys->D3DDeviceContext()->OMSetBlendState(0, 0, 0xffffffff);d3dSys->D3DDeviceContext()->RSSetState(0);



Copyright© by 寒江雪
Date:2017.1.2

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为手机拨打电话时黑屏怎么办 小米6x拨电话黑屏怎么办 魅族手机打电话黑屏怎么办 三星手机拨打电话时黑屏怎么办 华为畅享5打电话黑屏怎么办 小米note通话声音小怎么办 金立m5黑屏开不了机怎么办 金立手机光感器坏了怎么办 红掌根部烂了怎么办 魅族相册闪退怎么办 魅族手机闪退怎么办 苹果6手机主页面打不开怎么办 手机中病毒闪退怎么办 酷派手机开机黑屏怎么办啊 酷派手机黑屏打不开怎么办 酷派手机不开机怎么办 乐视手机开不了机怎么办 vivo手机拨号键盘不见了怎么办 华为手机拨号键盘不见了怎么办 金立手机拨号键盘不见了怎么办 酷派手机home键失灵怎么办 r11屏碎一半黑屏怎么办 金立手机黑屏打不开怎么办 小米8se自动跳出广告怎么办 小米手机总跳出广告怎么办 小米手机总是出现广告怎么办 红米1s开机黑屏怎么办 红米手机打电话黑屏怎么办 小米4c打游戏卡怎么办 电脑总出现拨号连接怎么办 win10电脑没有拨号连接怎么办 红米手机黑屏了怎么办 小米4s黑屏了怎么办 鼠标的左键失灵怎么办 小米5左键失灵怎么办 小米4左键失灵怎么办 小米5s左键失灵怎么办 单击鼠标左键就会自动删除?怎么办 华为五s开不开机怎么办 荣耀8关不了机怎么办 三星s7左键失灵怎么办