简体   繁体   English

使用openGL着色器歪斜图像

[英]Skew an image using openGL shaders

To lighten the work-load on my artist, I'm working on making a bare-bones skeletal animation system for images. 为了减轻我的艺术家的工作负担,我正致力于为图像制作一个简单的骨骼动画系统。 I've conceptualized how all the parts work. 我已经概念化了所有部件的工作原理。 But to make it animate how I want to, I need to be able to skew an image in real time. 但是为了让它成为我想要的动画,我需要能够实时扭曲图像。 (If I can't do that, I still know how to make it work, but it'd be a lot prettier if I could skew images to add perspective) (如果我不能这样做,我仍然知道如何使它工作,但如果我可以扭曲图像来增加视角,它会更漂亮)

I'm using SFML, which doesn't support image skewing. 我正在使用SFML,它不支持图像偏移。 I've been told I'd need to use OpenGL shaders on the image, but all the advice I got on that was "learn GLSL". 我被告知我需要在图像上使用OpenGL着色器,但我得到的所有建议都是“学习GLSL”。 So I figured maybe someone over here could help me out a bit. 所以我想也许这边的人可以帮我一点。

Does anyone know where I should start with this? 有谁知道我应该从哪里开始? Or how to do it? 或者怎么做?

Basically, I want to be able to deforem an image to give it perspective (as shown in the following mockup) 基本上,我希望能够为图像赋予视角(如下面的模型所示)

在此输入图像描述 The images on the left are being skewed at the top and bottom. 左侧的图像在顶部和底部倾斜。 The images on the right are being skewed at the left and right. 右侧的图像左右倾斜。

An example of how to skew a texture in GLSL would be the following (poorly poorly optimized) shader. 如何在GLSL中扭​​曲纹理的示例将是以下(优化不佳的)着色器。 Idealy, you would want to actually precompute your transform matrix inside your regular program and pass it in as a uniform so that you aren't recomputing the transform every move through the shader. 理想情况下,您可能希望在常规程序中预先计算变换矩阵并将其作为一个统一传递,这样您就不会在每次移动着色器时重新计算变换。 If you still wanted to compute the transform in the shader, pass the skew factors in as uniforms instead. 如果您仍想在着色器中计算变换,请将偏斜因子作为制服传递。 Otherwise, you'll have to open the shader and edit it every time you want to change the skew factor. 否则,每次要更改偏斜系数时,都必须打开着色器并进行编辑。

This is for a screen aligned quad as well. 这也适用于屏幕对齐的四边形。

Vert 韦尔

attribute vec3 aVertexPosition;

varying vec2 texCoord;

void main(void){
   // Set regular texture coords
   texCoord = ((vec2(aVertexPosition.xy) + 1.0) / 2.0);

   // How much we want to skew each axis by
   float xSkew = 0.0;
   float ySkew = 0.0;

   // Create a transform that will skew our texture coords
   mat3 trans = mat3(
      1.0       , tan(xSkew), 0.0,
      tan(ySkew), 1.0,        0.0,
      0.0       , 0.0,        1.0
   );

   // Apply the transform to our tex coords
   texCoord = (trans * (vec3(texCoord.xy, 0.0))).xy;

   // Set vertex position
   gl_Position = (vec4(aVertexPosition, 1.0));
}

Frag FRAG

precision highp float;

uniform sampler2D sceneTexture;

varying vec2 texCoord;

void main(void){
   gl_FragColor = texture2D(sceneTexture, texCoord);
}

This ended up being significantly simpler than I thought it was. 这最终比我想象的要简单得多。 SFML has a vertexArray class that allows drawing custom quads without requiring the use of openGL. SFML有一个vertexArray类,允许绘制自定义四边形而无需使用openGL。

The code I ended up going with is as follows (for anyone else who runs into this problem): 我最终得到的代码如下(对于遇到此问题的其他人):

sf::Texture texture;
texture.loadFromFile("texture.png");
sf::Vector2u size = texture.getSize();

sf::VertexArray box(sf::Quads, 4);


box[0].position = sf::Vector2f(0, 0);      // top left corner position
box[1].position = sf::Vector2f(0, 100);    // bottom left corner position
box[2].position = sf::Vector2f(100, 100);  // bottom right corner position
box[3].position = sf::Vector2f(100, 100);  // top right corner position

box[0].texCoords = sf::Vector2f(0,0);
box[1].texCoords = sf::Vector2f(0,size.y-1);
box[2].texCoords = sf::Vector2f(size.x-1,size.y-1);
box[3].texCoords = sf::Vector2f(size.x-1,0);

To draw it, you call the following code wherever you usually tell your window to draw stuff. 要绘制它,只要您通常告诉窗口绘制内容,就可以调用以下代码。

window.draw(lines,&texture);

If you want to skew the image, you just change the positions of the corners. 如果要倾斜图像,只需更改角点的位置即可。 Works great. 效果很好。 With this information, you should be able to create a custom drawable class. 有了这些信息,您应该能够创建自定义可绘制类。 You'll have to write a bit of code (set_position, rotate, skew, etc), but you just need to change the position of the corners and draw. 你必须编写一些代码(set_position,rotate,skew等),但你只需要改变角落的位置并绘制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM