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

友情提示 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 : 严格来讲,像素是点,而不是正方形

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个小程序员的成长笔记

CSS3中的变形处理

变形分类 缩放 使用scale方法来实现文字或图像的缩放,在参数中指定缩放倍率。例如“scale(0.5)”,表示缩小50 倾斜 使用skew方法来...

2907
来自专栏前端下午茶

CSS 中重要的层叠概念

最近在项目的过程中遇到了一个问题,menu-bar希望始终显示在最上面,而在之后的元素都显示在它之下,当时设置了 z-index 也没有效果,不知道什么原因,因...

1072
来自专栏cnblogs

Css3新特性应用之过渡与动画

一、缓动效果 学习和利用贝塞尔曲线,默认支持ease,ease-in,ease-out,ease-in-out和linear等 还提供一个cubic-beize...

3107
来自专栏MelonTeam专栏

抠图技术初探

图像抠图英文名叫 image matting,顾名思义就是将目标图像从背景中分离出来的一种图像处理技术。根据图像背景的复杂程度,一般分为纯色背景抠图(“绿幕”或...

73911
来自专栏一个小程序员的成长笔记

CSS3动画功能

1.transition功能 transition属性的使用方法:transition:property duration timing-function; 其...

3986
来自专栏闵开慧

html中align属性

成员名称 说明 AbsBottom 图像的下边缘与同一行中最大元素的下边缘对齐。 AbsMiddle 图像的中间与同一行...

3425
来自专栏SpiritLing

CSS3 translate、transform、transition区别

translate:移动,     transform的一个方法               通过 translate() 方法,元素从其当前位置移动,根据给定...

3735
来自专栏图形学与OpenGL

6.5编程实例-立方体透视投影

GLint winWidth = 600, winHeight = 600; //设置初始化窗口大小

2171
来自专栏进击的程序猿

Kaggle初探--房价预测案例之数据分析

本文数据来源kaggle的House Prices: Advanced Regression Techniques大赛。

2553
来自专栏杨龙飞前端

css3中的translate,transform,transition的区别

1644

扫码关注云+社区

领取腾讯云代金券