D3D9学习笔记(七) TEXTURE 纹理

texture永远是图形学最精华细节最多的地方,所以我也花了最多的时间阅读和写这个章节。

 

d3dDevice->SetTexture(n,tex)设置当前在n通道的texture,n的数量硬件在0-7.多个通道的texture可以进行blending

 

一个pixel在光照计算后得到一个颜色值c1,它纹理采样有一个颜色值c2,最终这个pixel的颜色值为
Color = c1 x DestBlend+c2 x SourceBlend 
可以通过
IDirect3DDevice9::SetRenderState(D3DRS_BLENDXXX)来控制这个混合策略
默认是
SourceBlend = D3DBLEND_SRCALPHA 
DestBlend = D3DBLEND_INVSRCALPHA
也就是贴图的颜色权重就是alpha值。
可以通过这个设定,设置贴图的透明度,SourceBlend = D3DBLEND_ZERO 
DestBlend = D3DBLEND_ONE就会变成贴图完全消失
 
 
 

 

7.1 address mode

纹理坐标通常在0-1之间,当处理那些不在这个范围内的纹理坐标时的策略就是address mode

IDirect3DDevice9::SetSamplerState(D3DSAMP_ADDRESSU/D3DSAMP_ADDRESSV/D3DSAMP_ADDRESSW,)

D3DTADDRESS_WRAP          重复纹理u=2与u=1相同
D3DTADDRESS_MIRROR        于上类似,但是01正向 12镜像23正向...
D3DTADDRESS_CLAMP        小于0设为0 大于1设为1
D3DTADDRESS_BORDER        超范围的设为设定的border color
(设定这个值通过IDirect3DDevice9::SetSamplerState(D3DSAMP_BORDERCOLOR))
D3DTADDRESS_MIRRORONCE    只镜像一次然后 clamp
 
虽然允许使用任意数值的纹理坐标,但是往往这个值也是被硬件限制的,D3DCAPS9中的MaxTextureRepeat代表纹理坐标的范围在-MaxTextureRepeat到MaxTextureRepeat之间。The interpretation of MaxTextureRepeat is also affected by the D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE capability bit. When this bit is set, the value in the MaxTextureRepeat member is used precisely as described. However, when D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE is not set, texture repeating limitations depend on the size of the texture indexed by the texture coordinates. In this case, MaxTextureRepeat must be scaled by the current texture size at the largest level of detail to compute the valid texture coordinate range. For example, given a texture dimension of 32 and MaxTextureRepeat of 512, the actual valid texture coordinate range is 512/32 = 16, so the texture coordinates for this device must be within the range of -16.0 to +16.0.

7.2 texture filtering

filtering是使用具体的0-1内的纹理坐标获取纹理上颜色值的策略。

IDirect3DDevice9::SetSamplerState(0-7),场合参数,filter参数)

场合参数

D3DSAMP_MAGFILTER,一个纹理点(texel)需要被映射到很多pixel的时候放大
D3DSAMP_MINFILTER,一个pixel采样到很多纹理点的时候,放小

D3DSAMP_MIPFILTER mipmap的时候

filter参数

为什么要设置filter,因为D3D采样纹理(直接采样过程)是把0-1的纹理坐标映射到-0.5~n-0.5范围内的纹理像素点(n是texel的像素数)如下图0,0点和1/3,1/3点的映射像素(左图是pixel表面,右图是纹理图像)分别为(-0.5,-0.5)和(0.5,0.5)(注意0,0位于第一个像素格子的中心)纹理坐标uv对应的texel坐标为(uv)*n-0.5

                  

 

这样采样出来看上去就像贴图在pixel表面上比你预计的想左上位移了0.5个tixel一样

 

为了解决颜色的错乱(纹理采样的走样),就有了很多种filter策略,这个策略主要在于根据uv得到的texel坐标xy,怎样根据xy找到合适的颜色值

filter参数有:

D3DTEXF_POINT:这叫默认的,也是最差的,基本现在都不用的,叫最近点策略,就是采到一个像素点位置(texel)坐标xy时,如果坐标值xy不是整数,那么就转换成离这个浮点数最近的整数,因为整数的texel意味着不需要潜在的平均多个texel的颜色值等,直接取颜色,最快,但是效果可能差别很大。

如最上面的采样结果就会变成这样 右下的贴图损失了(纹理坐标1,1转化的texel坐标3.5
3.5,转为整数4,4 4,4在贴图处是空白色的)

LINEAR:线性差值(其实可以看做二维的模糊),一种效果较好的流行的方式,它对于xy会找到离xy最近的上下左右四个整数值的颜色进行加权平均,颜色基本上最贴近贴图,如上例会变为

D3DTEXF_ANISOTROPIC:texel映射到曲面物体表面发生的变形叫做anisotropy(各向异性),一个屏幕像素反映射到纹理texel区域的长宽比称为延展度,它反映了anisotropy的程度。

联合LINEAR或mipmap的方式使用D3DTEXF_ANISOTROPIC可以提高各向异性时的贴图质量,还可以通过IDirect3DDevice9::SetSamplerState(D3DSAMP_MAXANISOTROPY)设置各向异性的degree

 

下面左右分别是使用高低不同质量的贴图,从上到下依次使用线性合并各向异性、线性、最近点的filter模式。可以看到最右下角在低质量贴图时用最近点采样纹理颜色错位严重,而线性是通常可以接受的方式。

     

 

  

7.2.1

MIPMAP

 

1.在CreateTexture的第三个参数指定mipmap的level数量,如果设为0,将自动的产生一直降到1*1的所有mip。将usage设为D3DUSAGE_AUTOGENMIPMAP将自动产生mipmap

map

2.设置mipmap的filter以启用mipmap

如SetSamplerState(0,D3DSAMP_MIPFILTER, D3DTEXF_POINT);

 

使用IDirect3DBaseTexture9::SetAutoGenFilterType Method可以设置在自动产生mipmap的时候的filter(怎么由大的贴图生成小的贴图,这个参数同texture
filtering的type一样)

使用IDirect3DTexture9::GetSurfaceLevel能够拿到具体某个level的mipmap的surface,

使用IDirect3DBaseTexture9::GetLevelCount可以拿到level的数量

  左右两张图分别是开启了mipmap和不开的情况,右图中在图像变小后纹理更加清晰,而左图则使用了低LOD的模式。

 

7.3 texture warpping

理解纹理的warpping(卷曲)就要先看下面一个问题,想把贴图贴给这个立方体然后贴成最下图的样子

 

如果按照正常的贴图方法,在贴从(0.857)到(0.175)这部分会很难实现,因为对于图中箭头所指的这个面,u坐标从(0.857)到(0.175)进行差值,在贴图上,将跨越4个颜色,而不是结果图中那样的情况。

 

问题的原因在于正常的纹理坐标差值都是基于两个浮点数之间的线性差值,通过设定texture warpping可以解决,当设置了u方向上的warpping后,可以想象将贴图弯曲成一个圆柱了,从(0.857)到(0.175)差值将选择最近的方向,而不是像原来一样跨越四个颜色。

 

设置的函数:

d3dDevice->SetRenderState(D3DRS_WRAP0, D3DWRAPCOORD_0);设置贴图0在u方向warping。
 
D3D在renderstage设置的warpping和7.1采样模式时设置的warpping 是两个不同的概念,要区分

 

 

7.4纹理坐标产生

from fvf 是直接从输入的vb中产生,from D3d是自动的产生方式

SetTextureStageStateD3DTSS_TEXTURETRANSFORMFLAGS:

D3DTTFF_DISABLE    不对纹理进行坐标变换
D3DTTFF_COUNT1     
D3DTTFF_COUNT2     
D3DTTFF_COUNT3    
D3DTTFF_COUNT4    

The rasterizer should expect (1-4)D texture coordinates. This value is used by fixed function vertex processing; it should be set to 0 when using a programmable vertex shader.

 
D3DTTFF_PROJECTED    每个元素会除以最后一个元素.这个通常联合使用D3DTSS_TCI_CAMERASPACEPOSITION,因为在摄像机空间下的纹理坐标再除以最后一个,得到的纹理坐标就是其剪裁坐标系下的顶点坐标了,这就是投射纹理,即总在视角方向的纹理。在设置这个标记时对于纹理的矩阵设置将不会生效,此时算出来的已经是最终纹理坐标位置了
 

7.4.1自动纹理产生

设置自动纹理产生的方式
IDirect3DDevice9:: SetTextureStageState(D3DTSS_TEXCOORDINDEX)
参数:
D3DTSS_TCI_CAMERASPACENORMAL 使用顶点的法向
D3DTSS_TCI_CAMERASPACEPOSITION 使用摄像机空间的顶点位置D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR 使用摄像机空间的reflection vector,这个常用于cubic env mapping
D3DTSS_TCI_PASSTHRU 使用VB中的.
这里有一个问题要注意,vb中可以指定顶点的纹理坐标,如D3DFVF_TEX1,在不指定坐标的产生方式时,这只是第0 stage的坐标的产生方式,对于1stage,如果没有指定D3DFVF_TEX1默认是没有纹理坐标的(或者都是00),但此时可用D3DTSS_TCI_PASSTHRU标志告诉stage1也用VB中的D3DFVF_TEX1

7.4.2纹理坐标的变换

IDirect3DDevice9::SetTransform时第一个参数传入D3DTS_TEXTURE0 through D3DTS_TEXTURE7。

还要用D3DTSS_TEXTURETRANSFORMFLAGS的非D3DTTFF_DISABLE打开开关

 

7.5 texture blending

首先要查询硬件的IDirect3DDevice9::GetDeviceCaps.是否支持纹理混合

texture可以进行多次混合,每一次混合称为一个stage,stage为0,开始,最多到7,具体支持的数量还要查询硬件。

 

d3dDevice->SetTexture(0, pTexture1);

d3dDevice->SetTexture(1, pTexture2);

设置stage0 和1的两张贴图,在每个stage进行一次混合然后传入下个stage,下面参数可以控制每个stage的混合方式

IDirect3DDevice9::SetTextureStageState(n,D3DTSS_COLOROP/D3DTSS_ALPHAOP..)在第n
stage对纹理的哪个颜色通道执行那种混合操作(modulate add。。)

这里的各种参数

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,

 

IDirect3DDevice9::SetTextureStageState(n,D3DTSS_COLORARG1,
component

设定这个纹理混合时的每个混合参数来自什么地方,参数有


D3DTA_CONSTANT


一个常量颜色


D3DTA_CURRENT


当前这个纹理通道已经混合后的结果(如果是第一次混合,那么等于DIFFUSE)


D3DTA_DIFFUSE


差值出的当前漫反射颜色


D3DTA_SPECULAR


差值出的当前高光颜色


D3DTA_TEMP


The texture argument is a temporary register color for read or write. D3DTA_TEMP is supported if theD3DPMISCCAPS_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


当前这个纹理通道的纹理


D3DTA_TFACTOR


The texture argument is the texture factor set in a previous call to theSetRenderState
with theD3DRS_TEXTUREFACTOR render-state value. Permissions are read-only

 

7.6 MultiPass Texture Blend

某些硬件可能不支持很多个stage的texture blending,这时还可以通过多个pass的渲染来实现,其实就是把一张贴图渲染一遍,不清缓存,再渲染一遍用另外一张贴图...

 

光照贴图

使用贴图可以高效的实现复杂的光照计算,即将顶点的光照计算结果存在贴图中,然后使用贴图的blend或 multipass。

其他

 

IDirect3DDevice9::SetCurrentTexturePalette设置纹理的色板

时间: 2024-10-29 17:40:37

D3D9学习笔记(七) TEXTURE 纹理的相关文章

D3D9学习笔记(五) Resource

Usage 这是强制的属性,使用时要明确确定,下面是每种reource的用途列表 Format <d3d9types.h> 存储访问顺序 D3DFORMAT_ARGB:内存中存储顺序是B到A                             D3DFMT_A8L8代表16位整数,高8位是A 存在未定义通道的格式都被默认为1 数据的底层格式是不同硬件不同的,但是被D3D运行时认可后就都变成这里面D3DFORMAT枚举类里面的某种格式   支持的格式及常见写法 1. (A\R\G\B)bit

D3D9学习笔记(三) Device

2.1架构 2.2类型 基本的device类型:hal:硬件渲染(发布).这也不是直接访问硬件驱动,而是访问在上一层的hal.(在顶点处理过程中,如果硬件处理失败,可尝试混合处理及纯软处理,设定标志D3DCREATE_MIXED_VERTEXPROCESSING)                                        soft软件渲染(但是这种软渲染并不一定拥有同当前硬件相同的渲染能力,所以要经常检查)                                   

D3D9学习笔记(九) effect (hlsl)

effect其实整合了shader和render state的控制两大部分内容 9.1 effect文件基本框架 part1 :shader state包括全局变量 shader数据结构定义,shader的实现 part2 :texture and sampler state,这个通常是全局变量,用于shader中,通常要定义在shader的实现之前 part3 其他的render state设置,写在technique的pass里,这才是effect文件的主入口 effet中任何一个变量后面都

D3D9学习笔记(五) State

一个state就是对(固定)渲染管线的某个特性或参数的一次设置 state block 记录了一个序列很多的state,可以保存相似的一连串对管线的设置 4.0.1创建state block 1.创建一个State Block并将当前state加入 IDirect3DDevice9::CreateStateBlock() 2.自动的捕捉一短时间的state变化 IDirect3DStateBlock9* pStateBlock = NULL; pd3dDevice->BeginStateBloc

JSP学习笔记(七)-----猜数字游戏

js|笔记 1. 这是一个猜数字的游戏,通过使用JSP调用JavaBean2. 需要两个文件,number.jsp和NumberGuessBean.java3. 先看number.jsp代码:<html><jsp:useBean id="number" class="NumberGuessBean" scope="session" /><jsp:setProperty name="number"

D3D9学习笔记(六) 坐标系统及坐标变换 几何体

6.1坐标系统 D3D9采用左手系,即Z轴朝里 平面法向也是用右手 6.2生成和设置坐标转换矩阵 world trans D3DXMatrixRotationX D3DXMatrixTranslation.. view trans D3DXMatrixLookAtLH   优化 频繁的set 变换矩阵的开销很大,因此可以本地记录world  view矩阵,然后只set 一个整体的world_view矩阵,而让view矩阵永远为单位帧   IDirect3DDevice9::SetTransfor

设计模式学习笔记(七)—Observer观察者模式

<设计模式>一书对Observer是这样描述的: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新. 举个例子,在现实生活中,父母与孩子是最亲密的人.父母做为孩子(被观察者)的监护人(观察者),当孩子和别人打架后,一定会告诉他的父母这件事(呵呵,当孩子很小时,通常会告诉父母,长大了以后,可能不会,这里的孩子指的是小孩子),当孩子获得奖学金后,也一定会告诉他的父母.下面我用Observer实现这个程序.代码如下: import java.ut

Unmi的Struts2学习笔记(七)

小时候,大人们的谆谆教诲:做人要诚实.并真以此为做人原则.长大后才知 道何谓社会.譬如530,再如艳照门,风声乍起之时,有人辟谣:直东窗事发后, 道貌岸然者有之.恬不知耻者亦有之.原本成功就不属于规矩之人.纵观,无玄 武门之血腥,何来一代宗皇:老毛若不有理而造反,一味守规矩,或为一介书匠 耳.雅各一碗红豆汤便谋得以扫的长子权,再行骗去亚伯拉罕的祝福,并顺理成 章让耶和华与他同在,可见上帝之"贤明"?.高等教育中有一句,顺利的是骗 子,倒霉的是傻子,我是?不还有企业家的原罪吗?有时竟被社

hibernate3学习笔记(七) Criteria Queries

仍然接着前面的例子来讲:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/Java/201101/23637.htm 示例代码如下: 1.package com.hb3.pack_01;2.3.import java.util.Iterator;4.import java.util.List;5. 6.import org.hibernate.Criteria;7.import org.hibernate.Hibernate;8.i