有没有办法纯粹在着色器中应用正弦波失真效果?
2D 图像的正弦波失真是一种经典的视觉效果:拍摄 2D 图像并通过根据正弦波移动像素来沿 X 或 Y 轴扭曲图像。它最终看起来像这样:
我已经看到了一些代码示例,以及执行此操作的标准方法OpenGL似乎是,对于尺寸为(x,y)的图像:
for each column from 0 to X
draw a single quad one pixel wide and y pixels high, offset by a sine wave value
当然,这涉及客户端的大量工作。有什么方法可以绘制单个四边形并使用着色器将失真工作卸载到 GPU 上吗?仅顶点和片段着色器;我使用的是 OpenGL 2,因此没有可用的几何着色器。
我知道我可以使用片段着色器来采样由正弦波偏移的纹理坐标,但是将它们放置在由四边形定义的原始框之外的位置会很棘手,而且我不希望输出为像示例图片中那样进行剪辑。有什么办法可以解决这个问题吗?
Sinewave distortion of a 2D image is a classic visual effect: taking a 2D image and warping it along either the X or the Y axis by shifting pixels according to a sine wave. It ends up looking something like this:
I've seen a few examples of code for it, and the standard way to do this with OpenGL seems to be, for a an image of dimensions (x, y):
for each column from 0 to X
draw a single quad one pixel wide and y pixels high, offset by a sine wave value
Of course, this involves a lot of work on the client-side. Is there any way to draw a single quad and offload the distortion work to the GPU with shaders? Only vertex and fragment shaders; I'm using OpenGL 2, so there are no geometry shaders available.
I know I could use a fragment shader to sample texture coordinates that are offset by a sine wave, but getting them to place at locations outside the original box defined by the quad would be tricky, and I'd prefer not to have the output be clipped like in the sample picture. Is there any way around this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,这可以使用着色器来完成。使用顶点着色器,您可以在网格上应用正弦失真。片段着色器可以调制纹理坐标,但不能调制目标像素位置;片段着色器是收集器,不能进行数据分散。
更新
纹理坐标调制的工作示例:
片段着色器部分是这样的:
更新 - “扩展”的着色器:
Yes, this can be done using shaders. Using a vertex shader you can apply a sine distortion on a grid. A fragment shader can modulate the texture coordinate, but not the target pixel location; fragment shaders are gatherers and can not do data scattering.
Update
Working example for texture coordinate modulation:
The fragment shader part is this:
Update – a shader that "expands":
对于给定的输入四边形,渲染四边形
2 * max_amplitude
更高(也许使用顶点着色器?),并在像素着色器中丢弃当前不是sin()
的像素就到了。这样您就可以到达原始四边形的“外部”。
For a given input quad render a quad
2 * max_amplitude
taller (maybe with a vertex shader?) and in your pixel shader discard pixels that aren't currently beingsin()
'd onto.That way you can reach "outside" your original quad.