【问题标题】:GLSL Shader - How to calculate the height of a texture?GLSL Shader - 如何计算纹理的高度?
【发布时间】:2012-03-06 17:33:51
【问题描述】:

this 问题中,我询问了如何创建“镜像”纹理,现在我想将这个“镜像”图像在 y 轴上围绕图像高度向下移动。 我用不同的 HEIGHT 值尝试了类似的方法,但找不到合适的解决方案:

// Vertex Shader
uniform highp mat4 u_modelViewMatrix;
uniform highp mat4 u_projectionMatrix;
attribute highp vec4 a_position;
attribute lowp vec4 a_color;
attribute highp vec2 a_texcoord;
varying lowp vec4 v_color;
varying highp vec2 v_texCoord;
void main()
{
    highp vec4 pos = a_position;
    pos.y = pos.y - HEIGHT;
    gl_Position = (u_projectionMatrix * u_modelViewMatrix) * pos;
    v_color = a_color;
v_texCoord = vec2(a_texcoord.x, 1.0 - a_texcoord.y);
}

【问题讨论】:

    标签: opengl-es glsl vertex-shader


    【解决方案1】:

    您在代码 sn-p 中实际更改的是顶点的 Y 位置...这肯定不是您想要做的。
    a_position 是您的模型空间位置;以四边形为中心的坐标系(我假设您使用四边形来显示纹理)。

    如果您改为在屏幕空间中进行修改,您将能够上下移动图像等...因此更改 gl_Position 值:

    ((u_projectionMatrix * u_modelViewMatrix) * pos + Vec4(0,HEIGHT,0,0))
    

    请注意,您将在屏幕空间中;所以请检查视口的尺寸。

    最后,实现你想要的效果的更好方法是使用旋转矩阵来翻转和倾斜图像。
    然后,您可以将此矩阵与图像的旋转相结合(将其与模型视图矩阵结合)。

    您可以选择将模型矩阵乘以 CPU 上的视图投影:

    original_mdl_mat = ...;
    rotated_mdl_mat = Matrix.CreateTranslation(0, -image.Height, 0) * Matrix.CreateRotationY(180) * original_mdl_mat;
    mvm_original_mat = Projection * View * original_mdl_mat;
    mvm_rotated_mat = Projection * View * rotated_mdl_mat;
    

    或在 GPU 上:

    uniform highp mat4 u_model;
    uniform highp mat4 u_viewMatrix;
    uniform highp mat4 u_projectionMatrix;
    gl_Position = (u_projectionMatrix * u_model * u_viewMatrix) * pos;
    

    【讨论】:

    • 但我仍然需要找到一种方法来计算 Tommy 提到的 HEIGHT 值。我用旋转矩阵试过了,但是如何确保旋转后的图像总是在原始图像的正下方?
    • 对于高度,您可以通过制服传递并执行 HEIGHT/viewport_height。然而,更好的方法是在 CPU 端使用矩阵。为了确保它总是正确的,你可以在你的 CPP/ObjC 代码中做类似的事情: original_mdl_mat = ...; rotate_mdl_mat = Matrix.CreateTranslation(0, -image.Height, 0) * Matrix.CreateRotationY(180) * original_mdl_mat;然后将 original_mdl_mat 传递给您的 Vertex 着色器以渲染正常图像,并通过 rotate_mdl_mat 渲染旋转后的图像。注意:我在这里使用 DirectX/XNA 表示法,但您应该能够将其调整为 OpenGL-ES。
    • 问题是我对 cpu 上发生的事情没有任何影响,因为我对一个只允许更改着色器的接口进行编程,并且该接口不单独提供模型、视图和投影。我只能访问与视图矩阵和投影矩阵相结合的模型。接口提供的另一个矩阵是普通矩阵。
    • Mhhh,不幸的是你没有太多选择:(你总是可以尝试在 GPU 上构建一个旋转矩阵:/
    • 是的,这就是我已经做过的,但是我无法确定它用于旋转的坐标。我认为它正在使用视图的中间,这非常令人恼火和令人沮丧;)......但到目前为止非常感谢!
    【解决方案2】:

    无论原始纹理大小和纵横比如何,传递给texture2D 的坐标始终在两个轴上的 [0, 1) 范围内对源进行采样。所以一个下意识的答案是纹理的高度总是 1.0。

    如果您想知道包含纹理的源图像的高度(以像素为单位),那么您需要自己提供(可能作为制服),因为它不会以其他方式暴露。

    【讨论】:

      猜你喜欢
      • 2017-01-13
      • 2023-04-09
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      相关资源
      最近更新 更多