屏幕像素与纹理像素(Pixel和Texe,像素和纹素l)

在使用d3d来渲染GUI元素时,可能很多人都碰到过一些让人抓狂的灵异问题,例如整个界面变模糊,边缘偏差一个像素,甚至在不同显卡上的表现还不一样……

这一般都是Pixel和Texel的对应出了问题导致的,界面元素的渲染的主要特点是一般是要求屏幕像素和纹理像素严格一一对应,这个在2d绘图中看来很自然的事,到了3d环境下似乎变得不那么简单。

d3d的特点是确定投影范围(记住渲染UI要使用正交投影)以后,“整数位置坐标”对应的是屏幕像素中心,而“整数纹理坐标”对应的却是纹理像素的边缘,这就是一切罪恶的根源。怎么理解这句话呢?请继续往下看……

一般来说渲染GUI时我们会把视口大小设置为和背缓分辨率一致,这样3d坐标的单位“1”就和屏幕上1个像素对应;而纹理坐标则用待渲染图元的像素尺寸占整张纹理像素尺寸的比例来确定。这里面有什么问题呢?

我们举个极端的例子,假设我们要在坐标0,0点附近用一张4×4的纹理渲染一个4×4像素的正方形,我们用两个三角形来渲染,4个顶点坐标(这里忽略z值)分别为(0,0),(4,0),(0,4),(4,4);因为图元使用了整张纹理,所以三角形的uv坐标为左上角(0,0),右下角(1,1)。

上中黑色的X,Y轴为投影后的逻辑坐标轴,可以看到它们是穿过像素(灰色方格代表像素)中心的。另外红色方格代表的是纹理坐标的像素。

现在大家可以比较直观的看到,屏幕像素和纹理像素是不重合的。那实际绘制的结果会是什么样的呢?我们知道,显卡在光栅化的时候决定一个像素是否渲染是看该像素中心是否位于三角形内。再看上图我们会发现,三角形边缘刚好穿过了某些像素的中心,那到底这些像素是算在三角形内还是三角形外呢?很遗憾,由于浮点精度,显卡驱动等原因,结果可能是不确定的,也就是说你最终可能得到的是下面两个之一(运气好的话)

 

同时,采样纹理时也是按像素中心点的uv坐标来采样的,图中可以看出要采样uv位置也都落在纹理像素的边缘上!如果用的是点采样(D3DTEXF_POINT)的话这里又是另一个不确定因素。

那这个问题怎么解决呢?说出来很简单(虽然感觉有点土),就是把三角形的顶点位置偏移半个像素(下图左),或者将摄像机位置偏移半个像素(这样投影坐标轴就落在像素边缘,而不是中心了,下图右)也可以,总之就是让Pixel和Texel重合,三角形的边(除了“斜边”)都落在像素边缘,Pixel的uv也都落在Texel中心点,于是天下就太平了……

以上讨论的仅限于我相对熟悉的D3d9,据说在OpenGL里不是这样,而且我印象中D3d10也有所改变。

 

参考:

http://www.360doc.com/content/12/0311/02/655789_193396009.shtml

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值