Opengl es GLSL着色器-如何计算纹理的高度?

Opengl es GLSL着色器-如何计算纹理的高度?,opengl-es,glsl,vertex-shader,Opengl Es,Glsl,Vertex Shader,在这个问题上,我问了如何创建“镜像”纹理,现在我想在y轴上将这个“镜像”图像向下移动,大约是图像的高度。 我用不同的高度值尝试了类似的方法,但我找不到合适的解决方案: // Vertex Shader uniform highp mat4 u_modelViewMatrix; uniform highp mat4 u_projectionMatrix; attribute highp vec4 a_position; attribute lowp vec4 a_color; attribute

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

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

传递到
texture2D
的坐标始终在两个轴上的[0,1]范围内对源进行采样,而不管原始纹理大小和纵横比。因此,膝反射回答是纹理的高度始终为1.0


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

传递到
texture2D
的坐标始终在该范围内对源进行采样[0,1)在两个轴上,不管原始纹理大小和纵横比。因此,膝反射回答是纹理的高度始终为1.0


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

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

如果改为在屏幕空间中进行修改,则可以上下移动图像等。因此,请更改gl_位置值:

((u_projectionMatrix * u_modelViewMatrix) * pos + Vec4(0,HEIGHT,0,0))
请注意,此时您将处于屏幕空间;因此请检查视口的尺寸

最后,实现所需效果的更好方法是使用旋转矩阵翻转和倾斜图像。
然后将该矩阵与图像的旋转相结合(与modelviewmatrix相结合)

您可以选择将模型矩阵乘以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;

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

如果改为在屏幕空间中进行修改,则可以上下移动图像等。因此,请更改gl_位置值:

((u_projectionMatrix * u_modelViewMatrix) * pos + Vec4(0,HEIGHT,0,0))
请注意,此时您将处于屏幕空间;因此请检查视口的尺寸

最后,实现所需效果的更好方法是使用旋转矩阵翻转和倾斜图像。
然后将该矩阵与图像的旋转相结合(与modelviewmatrix相结合)

您可以选择将模型矩阵乘以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提到的高度值。我用旋转矩阵进行了尝试,但如何确保旋转后的图像始终位于原始图像的正下方?对于高度,您可以均匀地通过,并进行高度/视区高度。不过,更好的方法是使用矩阵进行CPU端的计算。确保它是al在您的CPP/ObjC代码中,您可以通过以下方式执行类似的操作:original_mdl_mat=…;rotated_mdl_mat=Matrix.CreateTranslation(0,-image.Height,0)*Matrix.CreateRotationY(180)*original_mdl_mat;然后将original_mdl_mat传递给顶点着色器以渲染普通图像,然后旋转_mdl_mat以渲染旋转后的图像。注意:我在这里使用DirectX/XNA表示法,但您应该能够将其适应OpenGL-ES。问题是我对cpu上发生的事情没有任何影响,因为我是针对n接口,仅允许更改着色器,该接口不单独提供模型、视图和投影。我只能访问结合视图矩阵和投影矩阵的模型。该接口提供的另一个矩阵是普通矩阵。Mhhh,不幸的是,您没有太多选项:(您总是可以尝试在GPU上构建旋转矩阵:/yes,这是我已经做过的,但是我不知道它使用的是哪个坐标进行旋转。我认为它使用的是视图的中间部分,这非常令人恼火和沮丧;)…但到目前为止非常感谢!但我仍然需要找到一种方法来计算Tommy提到的高度值。我使用旋转矩阵进行了尝试,但如何确保旋转后的图像始终位于原始图像的正下方?对于高度,您可以均匀通过,并执行高度/视口高度。不过,更好的方法是执行CPU端使用矩阵。为了确保它始终位于CPP/ObjC代码的正下方,您可以在CPP/ObjC代码中执行类似操作:original_mdl_mat=…;rotated_mdl_mat=matrix.CreateTranslation(0,-image.Height,0)*matrix.CreateRotationY(180)*original_mdl_mat;然后将original_mdl_mat传递给顶点着色器以渲染普通图像,然后旋转_mdl_mat以渲染旋转后的图像。注意:我在这里使用DirectX/XNA表示法,但您应该能够将其适应OpenGL-ES。问题是我对cpu上发生的事情没有任何影响,因为我是针对n接口,仅允许更改着色器,该接口不单独提供模型、视图和投影。我只能访问结合视图矩阵和投影矩阵的模型。该接口提供的另一个矩阵是普通矩阵。Mhhh,不幸的是,您没有太多选项:(您可以尝试在GPU上构建旋转矩阵:/yes,这是我已经做过的,但是我不知道它使用的是哪个坐标进行旋转。我认为它使用的是视图的中间部分,这非常令人恼火和沮丧;)…但非常感谢您!