高级纹理映射技术(2)

高级纹理映射技术(2)

纹理阶段混合操作

纹理映射本质上就是从纹理中获取颜色值,然后应用到物体的表面,多层纹理映射本质上就是混合多层纹理的颜色,然后应用到物体表面。为了处理上的方便,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);

高级纹理映射技术(2)_第1张图片

物体纹理

高级纹理映射技术(2)_第2张图片

光照纹理

 

黑暗映射的效果:

高级纹理映射技术(2)_第3张图片

这种类型的多层纹理之所以称为"黑暗映射",是因为最终结果中未受到"光照"的纹理元素比原图中的纹理元素更暗。

黑暗映射通常有三种调制操作:D3DTOP_MODULATE,D3DTOP_MODULATE2X,D3DTOP_MODULATE4X。

当应用程序选择了一张纹理作为当前纹理,也就是指示Direct3D将该纹理应用于此后所有将要渲染的图元,直到再次改变当前纹理为止。如果一个三维场景中的每个图元都有各自不同的纹理,则必须在渲染每个图元之前先设置相应的纹理。


你可能感兴趣的:(高级纹理映射技术(2))