【问题标题】:Skew an image using openGL shaders使用 openGL 着色器倾斜图像
【发布时间】:2014-03-05 02:43:39
【问题描述】:

为了减轻我的艺术家的工作量,我正在为图像制作一个简单的骨骼动画系统。我已经概念化了所有部分的工作原理。但要让它以我想要的方式动画,我需要能够实时倾斜图像。 (如果我做不到,我仍然知道如何使它工作,但如果我可以倾斜图像以添加透视效果会更漂亮)

我使用的是 SFML,它不支持图像倾斜。有人告诉我我需要在图像上使用 OpenGL 着色器,但我得到的所有建议都是“学习 GLSL”。所以我想也许这里有人可以帮帮我。

有人知道我应该从哪里开始吗?或者怎么做?

基本上,我希望能够对图像进行变形以使其具有透视性(如下面的模型所示)

左侧的图像在顶部和底部倾斜。右侧的图像左右倾斜。

【问题讨论】:

  • 我不熟悉 SFML。但是,根据您要倾斜的内容,这可能非常容易。如果您需要渲染整个场景然后倾斜,您必须学习如何渲染到纹理。如果您只需要一些倾斜的库存纹理,那么它就像根据其他人在这里提出的问题的倾斜变换矩阵调整着色器中的纹理矩阵一样简单:stackoverflow.com/questions/673216/skew-matrix-algorithm 对于学习着色器,您应该研究如何写在这里:lighthouse3d.com/tutorials/glsl-core-tutorial
  • 您不需要着色器来倾斜图像。渲染到纹理,然后定位就够了
  • @BЈовић SFML 无法定位到 3 个维度。所以我不知道该怎么做。
  • SFML 只是创建一个窗口。你需要在opengl中完成
  • @BЈовић,你有什么推荐的教程吗? (是的,我也在谷歌上搜索它,但我假设你比我更了解 openGL,所以你会更好地了解在哪里看)

标签: c++ opengl glsl sfml


【解决方案1】:

如何在 GLSL 中倾斜纹理的一个示例是以下(优化不佳)着色器。理想情况下,您可能希望在常规程序中实际预先计算变换矩阵并将其作为统一传递,这样您就不会在每次通过着色器时重新计算变换。如果您仍想在着色器中计算变换,请将偏斜因子作为制服传递。否则,每次要更改倾斜因子时,您都必须打开着色器并对其进行编辑。

这也适用于屏幕对齐的四边形。

垂直

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));
}

片段

precision highp float;

uniform sampler2D sceneTexture;

varying vec2 texCoord;

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

【讨论】:

    【解决方案2】:

    这最终比我想象的要简单得多。 SFML 有一个 vertexArray 类,允许在不需要使用 openGL 的情况下绘制自定义四边形。

    我最终使用的代码如下(对于遇到此问题的其他人):

    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);
    

    要绘制它,您可以在通常告诉窗口绘制内容的任何位置调用以下代码。

    window.draw(lines,&texture);
    

    如果你想倾斜图像,你只需改变角落的位置。效果很好。有了这些信息,您应该能够创建一个自定义的可绘制类。您必须编写一些代码(set_position、rotate、skew 等),但您只需要更改角的位置并进行绘制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 2012-02-17
      相关资源
      最近更新 更多