在顶点着色器中旋转时出现奇怪的效果

时间:2016-05-29 07:05:12

标签: ios opengl-es

所以我试图创建一个实例化效果。我采用了常规的矩形纹理着色器并添加到属性中。 BTW我的游戏是2d和OpenGL es 2.0

  1. 告诉它是否是第一个第二个或第三个等的ID
  2. 位置偏移(因此它们可以在屏幕上移动)
  3. 时间
  4. 基于ID,我将基于矩形Time和实例id来设置旋转动画。我需要在GPU中执行此操作,因为我的cpu开销已经相当高了。

    我找到了一个glsl函数声称可以创建一个基于角度的旋转矩阵,但最终会产生一个真正扭曲的效果。我需要对矩阵做的只是在2d屏幕上围绕矩形的点(0.5,0.0)(底部中心)旋转一个角度。

    然而,这个新的旋转功能根本无法正常工作,坐标位于奇怪的位置,我很确定锚点不是0.5,0.0。

    旧版本(在左下角绘制,只是一个普通的矩形)(注意:我没有更改任何pos或新版本中的tc信息,只需要旋转)

    precision highp float;
    
    attribute vec2 pos;
    attribute vec2 tc;
    attribute float instance;
    
    uniform mat4 matrix;
    uniform float time;
    uniform vec2 position;
    
    varying vec2 v_texcoord;
    
    void main()
    {
        gl_Position = matrix/* * rotationMatrix(vec3(1.0), 3.14 * instance)*/ * vec4(pos, 1.0, 1.0);
        v_texcoord = tc;
    }
    

    新版本(添加了旋转和位置)

    precision highp float;
    
    attribute vec2 pos;
    attribute vec2 tc;
    attribute float instance;
    
    uniform mat4 matrix;
    uniform float time;
    uniform vec2 position;
    
    varying vec2 v_texcoord;
    
    mat4 rotationMatrix(vec3 axis, float angle)
    {
        axis = normalize(axis);
        float s = sin(angle);
        float c = cos(angle);
        float oc = 1.0 - c;
    
        return mat4(oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
                    oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
                    oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
                    0.0,                                0.0,                                0.0,                                1.0);
    }
    void main()
    {
        gl_Position = matrix * rotationMatrix(vec3(1.0), 3.14 * instance) * vec4(pos + position, 1.0, 1.0);
        v_texcoord = tc;
    }
    

    知道为什么吗?

1 个答案:

答案 0 :(得分:0)

在您找到的用于构建旋转矩阵的公式中,定义轴的向量需要是单位向量,即它需要具有长度1.在您的示例中不是这种情况。当您写vec3(1.0)时,vec3(1.0, 1.0, 1.0)对应sqrt(3.0),这是一个长度为normalize(vec3(1.0)) 的向量。

简单的解决方法是规范化矢量:

vec3(1.0 / sqrt(3.0))

或直接将其写为单位长度向量:

(1.0, 1.0, 1.0)

根据您的描述,它实际上听起来只是想围绕其中一个坐标轴旋转,因此不清楚为什么要使用pos作为旋转轴。

例如,要围绕z轴将anglefloat c = cos(angle); float s = sin(angle); gl_Position = vec4(c * pos.x - s * pos.y, s * pos.x + c * pos.y, pos.zw); 旋转,我甚至不会为构建矩阵而烦恼。只需将旋转直接写为:

SELECT *
FROM ((SELECT a.*,  b.*,  c.i_num_items,  FIELD(fk_c_locale_code,  'sv_SE') as locale_order
FROM (oc_t_category as a)
INNER  JOIN oc_t_category_description as b ON a.pk_i_id = b.fk_i_category_id
LEFT  JOIN oc_t_category_stats  as c  ON a.pk_i_id = c.fk_i_category_id
WHERE b.s_name != ''
AND a.b_enabled = 1
ORDER BY locale_order DESC) dummytable)
GROUP BY pk_i_id
ORDER BY i_position ASC