前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Half-Pixel Offset 究竟是个什么鬼?

Half-Pixel Offset 究竟是个什么鬼?

作者头像
用户2615200
发布2018-08-02 17:01:18
9530
发布2018-08-02 17:01:18
举报

友情提示 Half-Pixel Offset 其实算是个过时话题,请依据个人情况谨慎了解 :)

讲述之前我们先明确几个概念:

  • 窗口由正方形(注1)的像素(pixel)组成,每个像素只能显示一种颜色,并且像素坐标的原点在左上角像素的中心点(重要)
  • 纹理也是由正方形的纹素(texel)组成,每个纹素代表一种颜色,并且纹素坐标的原点在左上角纹素的左上角(重要)
  • 纹理的采样使用的是双线性(Bilinear)插值的方式(更多的细节可以看这里)

需要了解的概念就是这些,现在我们尝试在像素坐标的原点处绘制一个 2 * 2 大小的正方形,还记的像素坐标的原点是在像素的中心吗?我们想要绘制的正方形大概是这个样子:

由于像素是离散的,我们需要将绘制的正方形与像素尽可能的”对齐”(这里涉及到光栅化的规则,有兴趣的朋友可以去这里了解),所以实际绘制的正方形是这个样子的:

考虑到我们是从像素坐标的原点开始定义正方形的,所以上图所示的实际绘制结果也是符合预期的(正方形左上角与窗口左上角是对齐的)

现在我们想要将上面的纹理映射到刚才所绘制的正方形上去,为此我们需要为正方形的每个顶点计算纹素坐标,计算过程很简单,相关结果如下图所示:

简单想象一下,通过上面的纹理映射,我们期望得到的绘制结果是这个样子的:

但实际上,我们得到的绘制结果却是这个样子的:

什么鬼 ?

不急,我们来简单梳理一下~

回忆一下最开始需要绘制的的正方形示意图,我们在上面标注下纹素坐标:

根据上图中像素对应的纹素坐标,我们可以计算出像素对应的纹素颜色(此处我们没有详细讲解计算的方法,不清楚的朋友可以理解为取纹素坐标附近的四个像素的加权平均值即可):

于是我们便得到了上面那个令人诧异的绘制结果~

怎么修正这个问题呢?

一种方法是直接偏移像素的纹素坐标,拿上面的正方形绘制为例,我们在采样纹素点(0, 0)时做一个(0.25, 0.25)的偏移,即采样(0 + 0.25, 0 + 0.25)点的纹理,这样我们便能采样到预期的纹理颜色了

不过更通用的做法,还是直接偏移顶点的像素坐标,仍然拿上面的正方形绘制举例,我们对正方形的各个顶点做一个(-0.5, -0.5)像素的偏移,那么实际绘制的正方形就是这个样子的:

此时,各个像素中点对应的纹素坐标如下图所示:

根据纹素坐标计算一下像素颜色即可发现我们采样到了预期的纹理颜色:

而上述那么(-0.5, -0.5)的像素偏移,即是 Half-Pixel Offset

Half-Pixel Offset 只会在 Direct3D 9 及之前的Direct3D版本上出现,本质原因是像素坐标和纹素坐标定义不一致,OpenGL的像素坐标和纹素坐标定义是一致的,Direct3D 10以后也统一了像素坐标和纹素坐标的定义, Half-Pixel Offset 的问题也就不再存在了

如果你对于这个话题还有进一步了解的兴趣,可以再看看这里,这里,这里,和这里

注1 : 严格来讲,像素是点,而不是正方形
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年05月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 注1 : 严格来讲,像素是点,而不是正方形
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档