紋理階段混合操作
紋理映射本質上就是從紋理中獲取顏色值,然后應用到物體的表面,多層紋理映射本質上就是混合多層紋理的顏色,然后應用到物體表面。為了處理上的方便,Direct3D將顏色的RGB通道和alpha通道分別進行處理,具體的操作方法通過紋理階段狀態進行設置。
設置紋理顏色混合操作的代碼大致如下:
// i表示紋理階段序號
pd3dDevice->SetTextureStageState(i, D3DTSS_COLORARG1, arg1);
pd3dDevice->SetTextureStageState(i, D3DTSS_COLORARG2,
arg2);
pd3dDevice->SetTextureStageState(i, D3DTSS_COLOROP,
op);
一般的,用D3DTSS_COLORARG1指定當前紋理層的顏色,用D3DTSS_COLORARG2指定已經過顏色混合處理后的前面所有紋理層的顏色,用D3DTSS_COLOROP指定混合方式。Direct3D使用下面的方式進行紋理混合:
Colorstage =
D3DTSS_COLOROP(D3DTSS_COLORARG1, D3DTSS_COLORARG2)
渲染狀態D3DTSS_COLOROP用來指定紋理RGB通道混合方式,它們是屬于枚舉類型D3DTEXTUREOP的常量,D3DTEXTUREOP定義如下:
Defines per-stage texture-blending operations.
typedef enum D3DTEXTUREOP
{
D3DTOP_DISABLE = 1,
D3DTOP_SELECTARG1 = 2,
D3DTOP_SELECTARG2 = 3,
D3DTOP_MODULATE = 4,
D3DTOP_MODULATE2X = 5,
D3DTOP_MODULATE4X = 6,
D3DTOP_ADD = 7,
D3DTOP_ADDSIGNED = 8,
D3DTOP_ADDSIGNED2X = 9,
D3DTOP_SUBTRACT = 10,
D3DTOP_ADDSMOOTH = 11,
D3DTOP_BLENDDIFFUSEALPHA = 12,
D3DTOP_BLENDTEXTUREALPHA = 13,
D3DTOP_BLENDFACTORALPHA = 14,
D3DTOP_BLENDTEXTUREALPHAPM = 15,
D3DTOP_BLENDCURRENTALPHA = 16,
D3DTOP_PREMODULATE = 17,
D3DTOP_MODULATEALPHA_ADDCOLOR = 18,
D3DTOP_MODULATECOLOR_ADDALPHA = 19,
D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20,
D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21,
D3DTOP_BUMPENVMAP = 22,
D3DTOP_BUMPENVMAPLUMINANCE = 23,
D3DTOP_DOTPRODUCT3 = 24,
D3DTOP_MULTIPLYADD = 25,
D3DTOP_LERP = 26,
D3DTOP_FORCE_DWORD = 0x7fffffff,
} D3DTEXTUREOP, *LPD3DTEXTUREOP;
Constants
- D3DTOP_DISABLE
- Disables output from this texture stage and all
stages with a higher index. To disable texture mapping, set this as the
color operation for the first texture stage (stage 0). Alpha operations
cannot be disabled when color operations are enabled. Setting the alpha
operation to D3DTOP_DISABLE when color blending is enabled causes undefined
behavior.
- D3DTOP_SELECTARG1
- Use this texture stage's first color or alpha
argument, unmodified, as the output. This operation affects the color
argument when used with the D3DTSS_COLOROP texture-stage state, and the
alpha argument when used with D3DTSS_ALPHAOP.
SRGBA = Arg1
- D3DTOP_SELECTARG2
- Use this texture stage's second color or alpha
argument, unmodified, as the output. This operation affects the color
argument when used with the D3DTSS_COLOROP texture stage state, and the
alpha argument when used with D3DTSS_ALPHAOP.
SRGBA = Arg2
- D3DTOP_MODULATE
- Multiply the components of the arguments.
SRGBA = Arg1 x Arg2
- D3DTOP_MODULATE2X
- Multiply the components of the arguments, and
shift the products to the left 1 bit (effectively multiplying them by 2) for
brightening.
SRGBA = (Arg1 x Arg2) << 1
- D3DTOP_MODULATE4X
- Multiply the components of the arguments, and
shift the products to the left 2 bits (effectively multiplying them by 4)
for brightening.
SRGBA = (Arg1 x Arg2) << 2
- D3DTOP_ADD
- Add the components of the arguments.
SRGBA = Arg1 + Arg2
- D3DTOP_ADDSIGNED
- Add the components of the arguments with a - 0.5
bias, making the effective range of values from - 0.5 through 0.5.
SRGBA = Arg1 + Arg2 - 0.5
- D3DTOP_ADDSIGNED2X
- Add the components of the arguments with a - 0.5
bias, and shift the products to the left 1 bit.
SRGBA = (Arg1 + Arg2 - 0.5) << 1
- D3DTOP_SUBTRACT
- Subtract the components of the second argument
from those of the first argument.
SRGBA = Arg1 - Arg2
- D3DTOP_ADDSMOOTH
- Add the first and second arguments; then subtract
their product from the sum.
SRGBA = Arg1 + Arg2 - Arg1 x Arg2 = Arg1
+ Arg2 x (1 - Arg1)
D3DTA
Texture argument constants are used as values for the
following members of the D3DTEXTURESTAGESTATETYPE enumerated type:
- D3DTSS_ALPHAARG0
- D3DTSS_ALPHAARG1
- D3DTSS_ALPHAARG2
- D3DTSS_COLORARG0
- D3DTSS_COLORARG1
- D3DTSS_COLORARG2
- D3DTSS_RESULTARG
Set and retrieve texture arguments by calling the
IDirect3DDevice9::SetTextureStageState and
IDirect3DDevice9::GetTextureStageState methods.
Argument flags
You can combine an argument flag with a modifier, but
two argument flags cannot be combined.
#define |
Description |
D3DTA_CONSTANT |
Select a constant from
a texture stage. The default value is 0xffffffff. |
D3DTA_CURRENT |
The texture argument is
the result of the previous blending stage. In the first texture stage
(stage 0), this argument is equivalent to D3DTA_DIFFUSE. If the previous
blending stage uses a bump-map texture (the D3DTOP_BUMPENVMAP
operation), the system chooses the texture from the stage before the
bump-map texture. If s represents the current texture stage and s - 1
contains a bump-map texture, this argument becomes the result output by
texture stage s - 2. Permissions are read/write. |
D3DTA_DIFFUSE |
The texture argument is
the diffuse color interpolated from vertex components during Gouraud
shading. If the vertex does not contain a diffuse color, the default
color is 0xffffffff. Permissions are read-only. |
D3DTA_SELECTMASK |
Mask value for all
arguments; not used when setting texture arguments. |
D3DTA_SPECULAR |
The texture argument is
the specular color interpolated from vertex components during Gouraud
shading. If the vertex does not contain a specular color, the default
color is 0xffffffff. Permissions are read-only. |
D3DTA_TEMP |
The texture argument is
a temporary register color for read or write. D3DTA_TEMP is supported if
the D3DPMISCCAPS_TSSARGTEMP device capability is present. The default
value for the register is (0.0, 0.0, 0.0, 0.0). Permissions are
read/write. |
D3DTA_TEXTURE |
The texture argument is
the texture color for this texture stage. Permissions are read-only. |
D3DTA_TFACTOR |
The texture argument is
the texture factor set in a previous call to the
IDirect3DDevice9::SetRenderState with the D3DRS_TEXTUREFACTOR
render-state value. Permissions are read-only. |
Modifier flags
An argument flag may be combined with one of the
following modifier flags.
#define |
Description |
D3DTA_ALPHAREPLICATE |
Replicate the alpha
information to all color channels before the operation completes. This
is a read modifier. |
D3DTA_COMPLEMENT |
Take the complement of
the argument x, (1.0 - x). This is a read modifier. |
黑暗映射
在Direct3D的坐標變換和光照流水線中,光照效果是基于所謂的"逐頂點(per-vertex)"方式計算的,也就是說,參與實際數計算的是三角形的每個頂點,而不是針對每個像素進行。有時這會造成一些較為明顯的視覺錯誤,例如,有一個很大的三角形,其表面近處有一個光源,當光源靠近該三角形的一個頂點時,就會看到這個三角形的受光效果;當光源向三角形的重心靠近時,三角形的受光效果便會逐漸消失。最壞的情況是,當光源位于三角形的中央時,整個三角形只受非常少的光照,而在三角形的中央會有一個亮點。由此可見,如果頂點未受光照,則無法計算出正確的三角形面的顏色。為了解決這個問題,可以采用基于像素的光照計算,但是基于像素的光照計算其計算量比較大,通常采用紋理貼圖的方式模擬基于逐像素光照效果,其中紋理貼圖的內容正式所期望的類型光源照射在一張漆黑表面上的結果。
通過紋理映射來模擬逐像素光照效果,通常是將第一層紋理設置為物體原來的表面紋理,將第二層紋理設置為光照紋理,然后將兩張紋理的顏色相乘,所以有時將兩張紋理的顏色相乘稱為光照映射(light
mapping)。由于這種技術經常被用于使一張紋理變暗,有時也稱為黑暗映射(dark mapping)。示例代碼如下:
pd3dDevice->SetTexture(0,
g_base_texture);
pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pd3dDevice->SetTexture(1, g_dark_texture);
pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
物體紋理
|
光照紋理
|
黑暗映射的效果:

這種類型的多層紋理之所以稱為"黑暗映射",是因為最終結果中未受到"光照"的紋理元素比原圖中的紋理元素更暗。
黑暗映射通常有三種調制操作:D3DTOP_MODULATE,D3DTOP_MODULATE2X,D3DTOP_MODULATE4X。
當應用程序選擇了一張紋理作為當前紋理,也就是指示Direct3D將該紋理應用于此后所有將要渲染的圖元,直到再次改變當前紋理為止。如果一個三維場景中的每個圖元都有各自不同的紋理,則必須在渲染每個圖元之前先設置相應的紋理。