纹理颜色混合
这是我对纹理混合的理解,如果我的理解有误,请一定给我来信(
gao_xudong2004@163.com
),敬请赐教:
在
D3D
中,一个物体表面可以使用多个纹理,使用多个纹理时,某点最后的显示颜色可以由两个纹理的同一纹理坐标位置的两个颜色的混合值来决定,并且两纹理的操作结果可以作为下一次纹理颜色混合的来源颜色
(
我理解为,将操作结果保存在帧缓冲中,下一次操作可以调出这一次的操作结果作为颜色来源
)
。
1、
纹理颜色值与纹理颜色值的混合操作
g_pMyd3dDevice
->
SetTexture(
0
, g_pTextureWall0 );
//
将g_pTextureWall0 纹理与0号纹理阶段关联
g_pMyd3dDevice -> SetSamplerState ( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pMyd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TEXTURE ); // 指定第一来源色为当前纹理
g_pMyd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLOROP,D3DTOP_SELECTARG1 ); // 将第一来源色作为输出(我理解为将第一来源色送入帧缓冲中去)
g_pMyd3dDevice -> SetTexture( 1 , g_pTextureWall1 );); // 将g_pTextureWall1纹理与stage1关联
g_pMyd3dDevice -> SetSamplerState ( 1 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE ); // 指定第一来源色为1号纹理阶段中纹理
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLOROP, D3DTOP_MODULATE ); // 将第一来源色和第二来源色的乘积作为输出来更新帧缓冲
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT ); // 指定第二来源色为上一次的输出(我想也就是帧缓冲中的数据)
g_pMyd3dDevice -> SetSamplerState ( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
g_pMyd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TEXTURE ); // 指定第一来源色为当前纹理
g_pMyd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLOROP,D3DTOP_SELECTARG1 ); // 将第一来源色作为输出(我理解为将第一来源色送入帧缓冲中去)
g_pMyd3dDevice -> SetTexture( 1 , g_pTextureWall1 );); // 将g_pTextureWall1纹理与stage1关联
g_pMyd3dDevice -> SetSamplerState ( 1 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE ); // 指定第一来源色为1号纹理阶段中纹理
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLOROP, D3DTOP_MODULATE ); // 将第一来源色和第二来源色的乘积作为输出来更新帧缓冲
g_pMyd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT ); // 指定第二来源色为上一次的输出(我想也就是帧缓冲中的数据)
2、
纹理颜色值与指定颜色值的混合操作
DWORD dwFactor
=
0x000000ff
;
g_pd3dDevice -> SetRenderState( D3DRS_TEXTUREFACTOR, dwFactor ); // 设置一个颜色值
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TFACTOR ); // 将上面设置的颜色值作为第一来源色
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG2, D3DTA_TEXTURE ); // 将0号纹理阶段的纹理颜色值作为第二来源色
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_ADD); // 将第一来源色与第二来源色的和作为输出。
g_pd3dDevice -> SetRenderState( D3DRS_TEXTUREFACTOR, dwFactor ); // 设置一个颜色值
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG1, D3DTA_TFACTOR ); // 将上面设置的颜色值作为第一来源色
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLORARG2, D3DTA_TEXTURE ); // 将0号纹理阶段的纹理颜色值作为第二来源色
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_COLOROP, D3DTOP_ADD); // 将第一来源色与第二来源色的和作为输出。
第一来源色可以看作是一张所有像素颜色为
dwFactor值的纹理图片。
3
、累积乘法操作
g_pd3dDevice
->
SetTextureStageState(
1
,D3DTSS_COLOROP,D3DTOP_MULTIPLYADD);
//
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT );
其中
Arg1
是上一次纹理操作的结果
(
帧缓冲中的内容
)
,
Arg2
和
Arg3
是本层纹理里你设置的
ColorArg1
和
ColorArg2
,故以上代码实现的纹理颜色混合的操作结果为:SRGBA =
上一次纹理操作的结果
+
本层纹理的颜色值
*
上一次纹理操作的结果
alpha混合
使用alpha混合可以将图像与当前帧缓冲中的数据相混合,alpha混合的处理结果最后还是要送到前帧缓冲.
OutputPixel=SourcePixel*SourceBlendFactor+DestPixel*DestBlendFactor 也就是:
Color = TexelColor x SourceBlend + CurrentPixelColor x DestBlend
这个公式的意思是:源像素 * 源混合因子 + 目的像素 * 目的混合因子
其中目的像素 (DestPixel) 指的是帧缓冲中的数据,源像素 (SourcePixel) 指的是你将要向帧缓冲中贴的数据
可以理解为用两个混合因子分别指定源像素颜色的深度 (SourceBlendFactor) 、和目的像素颜色的深度 (DestBlendFactor) ,通过 D3DRS_SRCBLEND 、 D3DRS_DESTBLEND 渲染参数来设。 OutputPixel 就是最终看到的像素
即:
Color = TexelColor x SourceBlend + CurrentPixelColor x DestBlend
alpha 混合就是通过上述公式进行的
OutputPixel=SourcePixel*SourceBlendFactor+DestPixel*DestBlendFactor 也就是:
Color = TexelColor x SourceBlend + CurrentPixelColor x DestBlend
这个公式的意思是:源像素 * 源混合因子 + 目的像素 * 目的混合因子
其中目的像素 (DestPixel) 指的是帧缓冲中的数据,源像素 (SourcePixel) 指的是你将要向帧缓冲中贴的数据
可以理解为用两个混合因子分别指定源像素颜色的深度 (SourceBlendFactor) 、和目的像素颜色的深度 (DestBlendFactor) ,通过 D3DRS_SRCBLEND 、 D3DRS_DESTBLEND 渲染参数来设。 OutputPixel 就是最终看到的像素
即:
Color = TexelColor x SourceBlend + CurrentPixelColor x DestBlend
alpha 混合就是通过上述公式进行的
例一:
m_pd3dDevice
->
SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE);
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE);
是怎么计算的呢:
Color = TexelColor x ( 0 , 0 , 0 , 0 ) + CurrentPixelColor x ( 1 , 1 , 1 , 1 )
例二:
Color = TexelColor x ( 0 , 0 , 0 , 0 ) + CurrentPixelColor x ( 1 , 1 , 1 , 1 )
例二:
m_pd3dDevice
->
SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
Color = TexelColor x ( A , A , A , A ) + CurrentPixelColor x ( 1-A , 1-A , 1-A , 1-A )
至于这个 A 是什具体是个什么数呢?这就要用到 alpha 通道了。 alpha 通道里每个象素都有一个透明度值,值域为 0-1 。应该不难想通吧。
例三:
m_pd3dDevice
->
SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR);
m_pd3dDevice -> SetRenderState( D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR);
Color = TexelColor x (0,0,0,0) + CurrentPixelColor x (R,G,B,A)
这是源颜色与目的色相乘,
例四(从纹理中获得ALPHA参数):
g_pd3dDevice
->
SetTextureStageState(
0
, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
//
0阶段纹理是一张灰度图片
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLOROP, D3DTOP_MODULATE ); /// 运用MODULATE运算进行颜色混合
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT );
g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLOROP, D3DTOP_MODULATE ); /// 运用MODULATE运算进行颜色混合
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG1, D3DTA_TEXTURE );
g_pd3dDevice -> SetTextureStageState( 1 , D3DTSS_COLORARG2, D3DTA_CURRENT );
第1、2行将第0号阶段的纹理作为输出(将灰度图片放到帧缓冲中),第3、4、5将上一次的输出结果(ALPHA参数)与第1号阶段的纹理进行ALPHA混合。
如果我理解有误的地方还请高手赐教一下.