【寒江雪】纹理混合的实现
来源:互联网 发布:淘宝店铺入口 编辑:程序博客网 时间: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
- 【寒江雪】纹理混合的实现
- 多重纹理的混合
- 游戏的纹理混合
- 纹理混合
- 发两张室外场景纹理混合的截图
- OGRESE 混合纹理的源码 外加注释
- 基于高度的纹理混合shader
- 在OpenGL中实现多纹理混合(Multi-texture Blending)
- Android中使用OpenGL ES实现纹理贴图以及实现多重纹理混合
- 纹理混合和模板
- 混合纹理小结
- 多层纹理混合
- D3D纹理混合方式
- D3D纹理混合
- 纹理映射和混合
- D3D混合纹理
- opengl 纹理混合 glBlendFunc
- 地形混合纹理生成
- 关于wifiManager.getConnectionInfo()与wifiManager.getScanResults()的使用问题
- android 4.0 如何实现在没有activity情况下开机自启动服务,非常急。。。
- 以下ASP代码如何实现用page分页
- 获取有关Json复杂数据,获取不了第二层对象
- CGAL 4.9 - Triangulated Surface Mesh Deformation
- 【寒江雪】纹理混合的实现
- Android Studio 导入第三方开源库PullToRefresh的问题
- 小白想用C语言写一个背单词的程序
- ISO swift语言 图片抖动
- asp 证书加密
- handler.post()线程问题
- 有谁用过android的 HeaderGridView吗? 为什么我添加的HeaderView总是歪的?
- ios描述文件安装的问题
- android开发一般都用什么数据库