我如何在图形着色器中创建图像变形器?
How can i create an image morpher inside a graphics shader?
图像变形主要是一种图形设计 SFX,使用艺术家决定的一些点将一张图片适应另一张图片,艺术家必须将眼睛的某些关键区域与另一张肖像上的关键区域相匹配,然后进行一些算法调整整个图片从一张变成另一张。
我想用着色器做一些类似的事情,它可以加载任意2个图形并自动选择图片同类区域中颜色最相似的区域并自动实时变形两张图片加工。也许基于着色器的版本在逻辑上会更快地完成任务?除了我什至不明白它是如何工作的。
如果您知道,请不要担心关于该过程的完整回复,如果您保存模糊的背景概念和关键字,关于如何在图形着色器中尝试 2d 纹理变形,那就太好了。
还有更多变形方法,您所描述的变形方法是基于几何的。
插值变形
你有 2 个具有相似属性的数据集(例如 2 个图像都是 2D 的)并通过一些参数在它们之间进行插值。对于 2D 图像,如果两个图像的分辨率相同,则可以使用 线性插值 ,否则可以使用 三线性插值 。
因此,您只需从每张图像中选取相应的像素,然后为某些参数插入实际颜色 t=<0,1>
。对于相同的分辨率是这样的:
for (y=0;y<img1.height;y++)
for (x=0;x<img1.width;x++)
img.pixel[x][y]=(1.0-t)*img1.pixel[x][y] + t*img2.pixel[x][y];
其中 img1,img2
是输入图像,img
是输出。请注意 t
是浮点数,因此您需要改写以避免整数舍入问题或使用比例 t=<0,256>
并通过右移 8 位或 /256
来更正结果对于您需要的不同大小首先在两个源图像中双线性插值相应的 (x,y)
位置。
All 这可以在片段着色器中很容易地完成。只需将 img1,img2
绑定到纹理单元 0,1
从中选择纹理元素插值并输出最终颜色。双线性坐标插值由 GLSL 自动完成,因为无论分辨率如何,纹理坐标都归一化为 <0,1>
。在 Vertex 中,您只需传递纹理和顶点坐标。在主程序端,您只需绘制一个覆盖最终图像输出的四边形...
几何变形
您有 2 个多边形(或匹配点)并在这两个多边形之间插入它们的位置。例如这样的事情:Morph a cube to coil。这适用于矢量图形。你只需要有 points corespondency 然后插值类似于 #1.
for (i=0;i<points;i++)
{
p(i).x=(1.0-t)*p1.x + t*p2.x
p(i).y=(1.0-t)*p1.y + t*p2.y
}
其中 p1(i),p2(i)
是来自每个输入几何集的 i-th
点,p(i)
是来自最终结果的点...
为了增强视觉外观,线性插值与特定轨迹(如 BEZIER 曲线)交换,因此变形看起来更酷。例如,参见
- Path generation for non-intersecting disc movement on a plane
要实现这一点,您需要使用几何着色器(甚至可能是镶嵌着色器)。您需要将两个多边形作为单个基元传递,然后几何着色器应该对实际多边形进行插值并将其传递给顶点着色器。
粒子群变形
在这种情况下,您可以通过匹配颜色在源图像中找到对应的像素。然后将每个像素作为粒子处理,并使用参数 t
创建从 img1
中的位置到 img2
的路径。它与 #2 相同,但您得到的只是点而不是多边形区域。粒子有它的 color,position
你插值两者......因为你获得精确颜色匹配和计数的机会非常小......(直方图将是相同的)这是很可能的。
混合变形
是#1,#2,#3
的任意组合
我相信还有更多的变形方法,这些只是我所知道的。此外,变形不仅可以在空间域中完成...
图像变形主要是一种图形设计 SFX,使用艺术家决定的一些点将一张图片适应另一张图片,艺术家必须将眼睛的某些关键区域与另一张肖像上的关键区域相匹配,然后进行一些算法调整整个图片从一张变成另一张。
我想用着色器做一些类似的事情,它可以加载任意2个图形并自动选择图片同类区域中颜色最相似的区域并自动实时变形两张图片加工。也许基于着色器的版本在逻辑上会更快地完成任务?除了我什至不明白它是如何工作的。
如果您知道,请不要担心关于该过程的完整回复,如果您保存模糊的背景概念和关键字,关于如何在图形着色器中尝试 2d 纹理变形,那就太好了。
还有更多变形方法,您所描述的变形方法是基于几何的。
插值变形
你有 2 个具有相似属性的数据集(例如 2 个图像都是 2D 的)并通过一些参数在它们之间进行插值。对于 2D 图像,如果两个图像的分辨率相同,则可以使用 线性插值 ,否则可以使用 三线性插值 。
因此,您只需从每张图像中选取相应的像素,然后为某些参数插入实际颜色
t=<0,1>
。对于相同的分辨率是这样的:for (y=0;y<img1.height;y++) for (x=0;x<img1.width;x++) img.pixel[x][y]=(1.0-t)*img1.pixel[x][y] + t*img2.pixel[x][y];
其中
img1,img2
是输入图像,img
是输出。请注意t
是浮点数,因此您需要改写以避免整数舍入问题或使用比例t=<0,256>
并通过右移 8 位或/256
来更正结果对于您需要的不同大小首先在两个源图像中双线性插值相应的(x,y)
位置。All 这可以在片段着色器中很容易地完成。只需将
img1,img2
绑定到纹理单元0,1
从中选择纹理元素插值并输出最终颜色。双线性坐标插值由 GLSL 自动完成,因为无论分辨率如何,纹理坐标都归一化为<0,1>
。在 Vertex 中,您只需传递纹理和顶点坐标。在主程序端,您只需绘制一个覆盖最终图像输出的四边形...几何变形
您有 2 个多边形(或匹配点)并在这两个多边形之间插入它们的位置。例如这样的事情:Morph a cube to coil。这适用于矢量图形。你只需要有 points corespondency 然后插值类似于 #1.
for (i=0;i<points;i++) { p(i).x=(1.0-t)*p1.x + t*p2.x p(i).y=(1.0-t)*p1.y + t*p2.y }
其中
p1(i),p2(i)
是来自每个输入几何集的i-th
点,p(i)
是来自最终结果的点...为了增强视觉外观,线性插值与特定轨迹(如 BEZIER 曲线)交换,因此变形看起来更酷。例如,参见
- Path generation for non-intersecting disc movement on a plane
要实现这一点,您需要使用几何着色器(甚至可能是镶嵌着色器)。您需要将两个多边形作为单个基元传递,然后几何着色器应该对实际多边形进行插值并将其传递给顶点着色器。
粒子群变形
在这种情况下,您可以通过匹配颜色在源图像中找到对应的像素。然后将每个像素作为粒子处理,并使用参数
t
创建从img1
中的位置到img2
的路径。它与 #2 相同,但您得到的只是点而不是多边形区域。粒子有它的color,position
你插值两者......因为你获得精确颜色匹配和计数的机会非常小......(直方图将是相同的)这是很可能的。混合变形
是#1,#2,#3
的任意组合
我相信还有更多的变形方法,这些只是我所知道的。此外,变形不仅可以在空间域中完成...