1

我想编写一个着色器来创建类似于用于coverflows的图像反射。

// 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;
mat4 rot = mat4( -1.0, 0.0, 0.0, 0.0,
                  0.0, -1.0, 0.0, 0.0,
                  0.0, 0.0, 1.0, 0.0,
                  0.0, 0.0, 0.0, 1.0 );
void main()
{
  gl_Position = (u_projectionMatrix * u_modelViewMatrix) * a_position * rot;
  v_color = a_color;
  v_texCoord = a_texcoord;
}

// Fragment Shader
varying highp vec2 v_texCoord;
uniform sampler2D u_texture0;
uniform int slices;
void main()
{
  lowp vec3 w = vec3(1.0,1.0,1.0);
  lowp vec3 b = vec3(0.0,0.0,0.0);
  lowp vec3 mix = mix(b, w, (v_texCoord.y-(float(slices)/10.0)));
  gl_FragColor = texture2D(u_texture0,v_texCoord) * vec4(mix, 1.0);
}

但是这个着色器正在创建以下内容: 当前结果 而且我不知道如何水平“翻转”图像,我在旋转矩阵中尝试了很多不同的参数(我什至尝试使用所谓的“镜像矩阵”)但我不知道如何在原始图像的底部反映图像。

4

1 回答 1

2

如果您正在谈论 images.google.com 为“coverflow”结果返回的内容,那么您根本不需要旋转矩阵。

void main()
{
  gl_Position = (u_projectionMatrix * u_modelViewMatrix) * a_position;
  v_color = a_color;
  v_texCoord = vec2(a_texcoord.x, 1.0 - a_texcoord.y);
}

只需垂直翻转即可。

如果您坚持使用矩阵并想要制作一个“镜像”着色器(将其作为对象并将其放在“地板”下进行反射的着色器),那么您需要镜像矩阵(不要忘记调整正面/背面剔除):

mat4(1.0, 0.0, 0.0, 0.0,
    0.0, -1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0 );

而且你必须知道地板在哪里。

gl_Position = (u_projectionMatrix * u_modelViewMatrix) * (a_position * mirrorMatrix - floor);

或者,您可以将地板平移放入相同的矩阵中。基本上,要针对任意高度进行镜像,您需要组合三个变换(伪代码)。

translate(0, -floorHeight, 0) * scale(1, -1, 1) * translate(0, floorHeight, 0).

并将它们放入您的矩阵中。

将模型视图矩阵拆分为“模型”(对象/世界)和“视图”矩阵也可能有意义。这样,执行此类转换会更容易。

于 2012-03-02T14:33:39.117 回答