DirectX9中Pixel Coordinates System的一个怪异特性

来源:互联网 发布:淘宝关键词提取工具 编辑:程序博客网 时间:2024/05/29 05:03

http://drilian.com/2008/11/25/understanding-half-pixel-and-half-texel-offsets/

这个文章解释的很详细,他的blog里面也有很多的文章,值得一看哦~.


总结下来就是这样:


在DirectX9中, NDC的坐标系的范围是从左往右x: (-1.0f, 1.0f),  从屏幕上方到下方y: (1.0f, -1.0f), 从屏幕外到屏幕深处z:(-1.0f, 1.0f )。

此时绘制一个全屏矩形,这个矩形的左上角的NDC坐标(忽略z)为( -1.0f , 1.0f )。 

这个矩形的左上角正对的是屏幕Pixel Coordinates System下坐标为(0,0)的像素的正中心。


在一些后期特效的处理中,我们常常通过这个全屏矩形NDC坐标来直接映射到纹理坐标取纹理.

那么问题在这里,DirectX9中的Texel Coordinates System下, 对应(0.0f, 0.0f)的是这个纹理中“最左上角Texel的左上角”!

而在DirectX9中的Pixel Coordinates System下 , 对应(-1.0f, 1.0f)的是这个纹理中“最左上角Pixel的中心”!


Pixel Coordinates System(-1.0f, 1.0f)的点会映射到Texel Coordinates System(0.0f, 0.0f),那么会出现这样的情况:

由于这个全屏矩形的左上角对应整个屏幕“最左上角Pixel的中心”, 直接将全屏纹理输入会发生Texel中心点和Pixel中心点错位,导致各种插值的错误。


假设原始图片的分辨率和当前屏幕的宽高比相同, 那么最好的情况是原始图片的每一个Texel和屏幕的每一个Pixel中心一一对应。

我们想要处于“最左上角Pixel的中心”对应的全屏矩形片段的Texel为“最左上角Texel的中心”。


由于屏幕宽高和贴图宽高相同,都用width height表示:


两种做法


1. 绘制全屏矩形的时候,直接在vs中把自己的uv坐标加上( 0.5f / width,  0.5f / height )。

    也就是全屏矩形最左上角,对应“最左上角Pixel的中心”的片段的纹理直接从“最左上角Texel的中心”开始展开。

2.  绘制这个全屏矩形的时候,vs中计算的顶点位置结果,要对这个结果加上( -1.0f / width,  1.0 / height ), 即往左上偏移半个像素。

    这样做的结果就是在偏移过后,目前处于“最左上角Pixel的中心”的全屏矩形片段的Texel Coordinates System为(0.5f / width,  0.5f / height )即“最左上角Texel的中心”。

   这种做法对于msaa也有好处,具体可以看前面老外的文章


     





0 0