使用GLSL / HLSL全屏着色器修复视频投影仪变形的方法

时间:2014-09-02 12:21:59

标签: glsl hlsl fragment-shader virtual-reality

我在VR领域工作,对投影屏幕的良好校准非常重要,并且由于难以调整的天花板安装和其他硬件特性,我正在寻找一种全屏着色器方法来“校正”形状屏幕。

大多数2D或3D引擎允许通过在可以自定义方式变形或渲染的四边形上重绘渲染结果来应用全屏效果或变形。

第一个想法是使用顶点着色器来偏移此屏幕四角的角落,因此图像变形为四边形(如投影仪上的硬件梯形),但对于要求来说还不够 (这种方法在math.stackexchange上用实时小提琴演示进行了描述)。

在我的目标案例中:

  • 图像变形在大多数时间内必须是非线性的,因此需要9或16个控制点才能进行更精细的调整。
  • 图像的边框不直(镜筒或枕头效果),因此即使控制点很少,图像也必须以曲面方式扭曲。否则,变形将在每个控制点的极限之间产生可见的线性接缝。 理想情况下,知道3x3或4x4网格的每个控制点的校正位置,方法是为全屏幕上绘制的图像的纹理坐标定义连续变换 quad:

u,v => corrected_u,corrected_v

您可以找到插图here

  • 我看到了一些在2D或3D中工作的FFD算法,它可以“轻柔地”变形图像或网格,就好像它是由橡胶制成的,但是the implementation seems heavy for a real-time shader
  • 我还想到了基于体重的变形,就像我们在squeletal / soft-bodies动画中所做的那样,但似乎不确定控制点的重量。 您是否知道可以帮助我解决问题的方法,算法或一般方法?
  • 我看到一些基于网格的变形,就像新的Oculus Rift DK2需要它自己的变形一样,但大多数2D / 3D引擎只使用标准的4个顶点组成的单个四边形。

2 个答案:

答案 0 :(得分:0)

继续我的研究,我找到了一种方法。 我创建了一个1D RGB纹理,对应于" ramp"或余弦值。这将是偏移参数在0..1轴上的3个影响系数,其中3个系数分别为0,0.5和1:

  • 红色在x = 0时从1开始,在x = .5
  • 时下降到0
  • 绿色从0开始,在x = 0时开始,在x = 0.5时变为1,在x = 1时变为0
  • 蓝色在x = 0.1时从0开始,在x = 1
  • 时上升到1

有了这些,从9个float2制服我可以非常轻柔地在图像上插入我的参数(在水平方向上有3个查找,在垂直方向上有最后一个查找)。

然后,一个插值,我偏移纹理坐标与它们的工作:-D 这或多或少是使用纹理查找加速的坐标的加权插值。

答案 1 :(得分:0)

如果您需要非线性变形,Bezier Surfaces非常方便且易于实现。

您可以预先在CPU中构建它们,也可以使用硬件细分(示例提供here