DX9纹理失真的问题

hugo514 2004-06-21 09:28:57
我用一张800*600的BMP图片作为纹理贴到800*600分辨率的全屏屏幕上,但是图像出现了一定的模糊,不能保持和原图一致,但是在DDRAW下则可以保持和原图一致,请问高手这是为什么呀?
...全文
433 20 打赏 收藏 举报
写回复
20 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
hugo514 2004-06-26
强呀,果然是会自动拉伸到Power of Two的大小的,我碰到的问题还有一个就是当我使用D3DX_FILTER_NONE来不使用过滤的时候,原来800*600的图片就不能在800*600分辨率的屏上完全显示出来,现在想想,原来是自动拉伸到1024*1024了,所以无法全部显示出来了,一直都想不通这个问题,这次一下就解决了,哈哈,多谢各位高手!
  • 打赏
  • 举报
回复
hugo514 2004-06-26
问题总算解决了,再次多谢两位高手!
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
请教一下:纹理必须为2的n次幂是不是所有的情况都适用?设想一个面片投影到屏幕上为4*3个相素,原图片也为4*3个,你拉伸到4*4的图片去做纹理,用什么样的算法去放大图片呢?如何保证同原图的一致?(如何配合图片的拉伸算法和纹理过滤的算法)?
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
KingofMagic:你说的是浮点数约减的问题吧,看看我上面说的第3点吧,纹理变换导致的精度约减。
但就这一点来说:用最近点采样,不过我认为,即使是1024*768的纹理,放在1024*768的屏幕大的矩形上,由于大小相近,应该也不会出现严重的模糊的情况,所以我才没有提这点。你无非是认为乘1024,浮点数Exp部分加10.而乘768会出现浮点数基数部分有比较大的变化,导致采样位置不准,会损失精度。对不?但是别忘了,插值出来的纹理坐标是根据,两顶点投影到屏幕的像素宽度来决定的。在上面这种情况下,768早就做了除数了。
当纹理图片同面片大小相同,而768小于1024,就精度来看,误采样的概率是很小的。通常出现采样不准的情况只有在纹理比图片大或纹理比图片小的情况下才会出现在,这种情况出现的问题不是纹理模糊,而是某些像素处的纹理会出现突变!所以,我一开始就排除了这种可能。要不你回去试验一下,不要以为世界上就你懂!
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
KingofMagic(大魔头) :得向你好好学习呀,作了3年的绘图系统,居然还不知道有DirectX会自动的将纹理转化为Power of Two的大小。遗憾的是没有D3DXCreateTextureFromFile的原代码,所以不知道如何对他Scale后的纹理在采样的时候进行矫正回来。我想出两种方法
(1)用了一个高斯采样函数模版进行(四角效果不好)。
(2)快速付里叶变换然后反变换(效果好,但是速度慢)。
但不知到具体的。
谁知道或有源码呀?
  • 打赏
  • 举报
回复
hugo514 2004-06-25
哇,都是高手呀,说的这些东西看得我头都晕了,回去研究ing!
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
to:Mybios
你感觉到装如纹理更快不可能是因为显卡在计算乘法时候乘以2^n比非2^n的时候乘法更快的问题,因为这在简单场景中根本感觉不出来,而且很少有显示卡支持非POW2纹理的。所以你真正做纹理的不论你是用的800*600的图片还是1024*1024的图片最终在纹理中还是1024*1024的大小,快的原因是1024*1024的图片装入时候不会进行插值拉伸的操作而800*600的在D3DXCreateTextureFromFile或D3DXCreateTextureFromFileEx函数中会执行拉伸的操作。所以快慢应该在这里出现的。
  • 打赏
  • 举报
回复
ITLADY 2004-06-25
up
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
完全明白了,如果你的显示卡要求D3DPTEXTURECAPS_POW2,那么你必须用2的n次方大小的纹理,而你用的是D3DX中的函数装入纹理,那么在装如纹理的时候已经把你的纹理拉伸成了1024*1024,但是在拉伸过程中由于进行像素插值产生了模糊。所以最接近原来屏幕的方法是将图象大小改为1024*1024但是不进行原来图片的缩放,多出的部分填充为原图片边界颜色,而同屏幕一样大小的2个三角形右下角顶点纹理坐标改为u=800.0/1024.0 v=600.0/1024.0。(注意用最近点采样还是一样会出现三角形交界处的不一致,但是如果用线形插值采样那么很多地方不会是原来的颜色而是经过平滑处理了的,还是同原来的图像不同,头痛死!)
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
下面引自 〈Real-time Rendering Tricks and Techniques in DirectX〉
Width,Height,and the Power of Two
Most graphics cards and implementations restrict texture dimensions to powers of two,This means that textures are restricted to sizes such as 1*1,16*16,128*128,and so on,Note that this dose not mean that they need to square.Sizes such as 128*16 are also legal.There are a couple of reasons for this restriction,but the biggest reason is that dimensions which are powers of two are easier for the decice to manipulate quichly.In future versions which are powers of two are easier for the device to manipulate quickly.In future versions of hardware,this requirement might be relaxed,but for the foreseeable future,you should expect that the hardware will require textures to have dimensions with powers of two.
  • 打赏
  • 举报
回复
XCOOL 2004-06-25
to:Mybios(俊俊哥哥)
因为高宽为2的n次方这种纹理,在做纹理映射时候需要做浮点运算,而一个浮点数乘以2的n次方时候和非2的n次方时候将采用不同的指令,一个只做exp部分的加法运算,一个需要乘法运算。当然快慢不一了。不过我比较好奇的是你是怎样测试出来快慢的不同的。因为给我的感觉在好的显卡上面这个效应应该不明显?
  • 打赏
  • 举报
回复
tengulre 2004-06-25
我想是你的显卡不支持。
  • 打赏
  • 举报
回复
mybios 2004-06-24
我把800×600的图像在Photoshop里拉伸成1024×1024后,在载入到800×600矩形中速度比原来的图像载入速度快了几倍啊!!!这是什么原理?图片大了反而速度更快。。
  • 打赏
  • 举报
回复
KingofMagic 2004-06-24
哎!竟然不懂得人也可以说几句?出现了一定的模糊是因为纹理的高和宽必须是2的次幂,比如2 4 8 16 32 64 128 256 512 1024,将图片高和宽改成2的次幂就行了,多去找这方面的书刊看
  • 打赏
  • 举报
回复
hugo514 2004-06-23
不好意思呀,我突然发现我在创建设备的时候设定的格式为
BackBufferFormat = D3DFMT_A8R8G8B8,但是当我把它改成D3DFMT_R8G8B8格式后,却出现创建设备错误,请问还有哪些地方要改吗?或者是我的显卡不支持,我是GFMX440的显卡.
  • 打赏
  • 举报
回复
XCOOL 2004-06-23
应该是你的显卡不支持,我没有用过MX440的显示卡.
  • 打赏
  • 举报
回复
XCOOL 2004-06-22
那就简单了,直接设置显示属性,改平滑处理为人工方式中的关闭平滑处理。在代码中全屏幕反锯齿可能出现在2个地方。一个就是在CreateDeivce的时候,设置第5个参数指向的结构中的pPresentationParameters->MultiSampleType=D3DMULTISAMPLE_NONE可创建禁止反锯齿的设备。或者你调用了SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,xxxx)你可以去掉程序中该行。但是通常来讲,你自己反了锯齿并且没有发现的话,那么应该是第一种情况,也就是创建设备的时候就已经反锯齿了!
  • 打赏
  • 举报
回复
hugo514 2004-06-22
哈哈,终于等到有人回答了,根据你的分析加上我的判断,应该是第二点,
因为第一三四点我都已经关闭了,但是我就是不知道怎么关闭全屏抗锯齿功能呀,能不能说说怎么关闭呀!
  • 打赏
  • 举报
回复
chena224503 2004-06-22
Texels to Screen Space, Mapping
在sdk里看看这个。
  • 打赏
  • 举报
回复
XCOOL 2004-06-21
可能原因
(1)D3D在进行纹理贴图时候会进行纹理过滤。虽然你用一个2个多边形组成屏幕一样大矩形,且刚好投影覆盖整个屏幕,但是由于你的过滤方式设置为不是最近点取样的方式,那么在对多边形进行充填时候会发生在原位置采样不到原有象素的情况,导致模糊。或者你使用了MIP贴图,会在2层贴土间做线性混合。等价于图象中的模糊酸法,因为下一层贴图为上一层贴图长宽都缩放一倍的效果,下一层一个像素为上一层4个像素的平均。而纹理过滤后原来像素同这个平均值进行了加权平均。
(2)打开了全屏幕反锯齿功能,回实现相当于图象处理的平滑效果
(3)由于变换损失了纹理坐标位精度,或者纹理的像素模式不同于原图象。
(4)执行了多级纹理混合,导致了纹理同点的着色信息混合。
可能还有别的可能,这需要你去实验一下了。
  • 打赏
  • 举报
回复
发帖
游戏开发

8246

社区成员

游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
帖子事件
创建了帖子
2004-06-21 09:28
社区公告
暂无公告