特殊纹理拉伸而不变形

我正在尝试在着色器中实现特殊的纹理拉伸效果。 这里是我如何定义我的紫外线,然后抽样我的纹理,没有什么特别的。

// uv_ST contains the tiling and offset values uv.xy = uv.xy * uv_ST.xy + uv_ST.zw 

如下图所示,当您平铺/拉伸夹持的纹理时,会给出标准的平铺/拉伸和偏移行为。 第一是正常的,第二是抵消,最后是拉伸。

在这里输入图像说明

但是我想要避免拉伸时的变形行为,我想保持边缘,当拉伸我的纹理,或者简单地在中间切割和拉伸。 下面是一个例子。

在这里输入图像说明

在采样纹理之前定义我的uvs时,我怎么能在我的着色器中做到这一点?

所以,基本上你要找的是9 Slice Scaling 。 但是,这只是延伸纹理,所以边缘和角落保持不变(有点)。

  • 两个角落的角落都是1:1。
  • 边缘是1:Y还是X:1,取决于它们是水平的还是垂直的(即,不均匀,但是由于所有像素都相同,所以拉伸方向不被注意)。
  • 该中心然后是X:Y,因为它只是一个坚实的填充,通常是不被注意到的。

但是,你似乎也需要这个中心来解决问题。 有一种方法可以完成这个任务,但是你必须使用相同的math方法来编写9-slice缩放。 而且你似乎只是朝着一个方向拉伸(这会使它更容易)。

你的用例没有预先构建的解决scheme,但它应该很容易解决! 只需要计算你需要保留多less个像素,并确保将其绘制成确切的大小。 然后你可以伸出中间来填充所需的空间(或者至less伸展下一个 ),然后再次以确切的大小绘制另一个边。

九补丁algorithm是一个非常好的和强大的解决scheme,如果你使用的纹理,但我最终通过使用完全程序化的解决scheme。

我只是画一个这样的圆框。

 float udRoundBox( vec3 p, vec3 b, float r ) { return length(max(abs(p)-b,0.0))-r; } 

如果你不需要,你可以简单地避免第三维。 这个方法来自Inigo Quilez的Distance函数文章 。