2014-02-14 36 views
0

过去我已经完成Open GL ES,但不久前。从我现在阅读的内容来看,似乎更多地强调管理自己的矩阵堆栈,并将矩阵直接推送到顶点着色器中以定位对象。顶点着色器可以用于翻页效果吗?

这是一切都很好,但我只是想知道你有多远去着色器。我不知道他们是仅仅为了简单的事情,还是我可以使用它们来实现翻页效果。肯定会有很多数学需要计算。感觉这是一个很好的地方,但我没有经验来了解是否有任何问题。

我打算输入一个映射到手指位置的着色点,然后着色器会根据手指位置偏移组成页面的网格中的每个顶点。

我打算在OpenGl ES 2.0的Android应用程序中尝试此操作。

所以,

问题

这个问题似乎是一个合理的办法,如果不是,这将是如何充分利用图形芯片的给我需要的效果的最佳途径和现代的OpenGL APIs?

我已经研究到目前为止

我已经通过了一些博客和教程,包括Tutorials for Modern Open GL的阅读,但着色器总是用于照明或只是基本的定位。我认为计算翻页效果可能需要比我见过的着色器更多的数学计算,但我不知道着色器中的数学计算会有多少太多!

我知道我应该给这个去看看,但我有一些时间,直到这个项目开始,我只是真的在研究当下!

更新

只是作为一个更新,我最近发现有用于着色器指令的限制,所以一个要求是,我能得到指令范围内我所有的翻页数学。

+0

我在OpenGL ES 2.0顶点着色器中实现了页面卷曲效果,我将与您分享此代码。它使用纹理坐标来控制页面的旋转角度。这样,旋转不受场景中三角形网格的位置影响,只有卷曲页面上的顶点向下多远。这个效果很好,但我最终放弃了这种方法,实现了一个更简单的实现,其中卷曲伪装成只有几个三角形在页面上平放,并使用纹理来伪造阴影效果。 – ClayMontgomery

+0

@ClayMontgomery随时发布您的答案! :) – Andy

+0

对于选民来说,你能给我一些建设性的反馈意见,我会试着改进这个问题吗? :) – Andy

回答

2

我在OpenGL ES 2.0顶点着色器中实现了页面卷曲效果,我将与您分享此代码。它使用纹理坐标来控制页面的旋转角度。这样,旋转不受场景中三角形网格的位置影响,只有卷曲页面上的顶点向下多远。这个效果很好,但我最终放弃了这种方法,实现了一个更简单的实现,其中卷曲伪装成只有几个三角形在页面上平放,并使用纹理来伪造阴影效果。在完成这两种方法后,我怀疑可能所有的页面卷曲效果都是以虚假的方式完成的,因为它实现和调试简单得多。

uniform mat4 transform_matrix; 
uniform highp float radius; 
uniform mediump vec2 axis; 
uniform mediump vec2 axis_origin; 
uniform highp float tex_size; 

attribute vec2 texCoord; 

varying vec2 texCoordVarying; 
varying float shadeVarying; 

mat4 rotationxy(float angle, vec2 axis); 
mat4 translationThenRotationZ(float x, float y, float z, float angle); 

void main() 
{ 
    vec3 axisOrigin = vec3(axis_origin, radius); 
    vec2 offsetTexCoord = texCoord - axis_origin; 
    float angle = dot(offsetTexCoord, vec2(axis.y, -axis.x))/radius; 

    vec4 coord; 
    vec4 myNormal = vec4(0.0, 0.0, 1.0, 1.0); 

    if (angle <= 0.0) {      // Flat section before curl 
     coord = vec4(texCoord, 0.0, 1.0); 
    } else { 
     vec2 proj = dot(offsetTexCoord , axis) * (axis); 
     const float PI = 3.14159265358979323846264; 

     if (angle >= PI) {     // Flat section after curl 
      float axisAngle = asin(axis.x); 
      proj += axis_origin; 
      mat4 tr = translationThenRotationZ(proj.x, proj.y, 0.0, axisAngle); 
      coord = vec4((PI - angle) * radius, 0.0, (radius + radius), 1.0); 
      coord = tr * coord; 

      myNormal.z = -1.0; 
     } else {       // Curl 
      mat4 r = rotationxy(angle, axis); 

      myNormal = r * myNormal; 

      coord = vec4(proj, -axisOrigin.z, 1.0); 
      r[3][0] = axisOrigin.x; 
      r[3][1] = axisOrigin.y; 
      r[3][2] = axisOrigin.z; 
      coord = r * coord; 
     } 
    } 
    gl_Position = transform_matrix * coord; 

    shadeVarying = 0.25 + abs(myNormal.z) * 0.75; 
    texCoordVarying = texCoord/tex_size; 
} 

mat4 rotationxy(float angle, vec2 axis) 
{ 
    float x = axis.x; 
    float y = axis.y; 

    float xSqd = x * x; 
    float ySqd = y * y; 

    float xy = x * y; 

    float cosAngle = cos(angle); 
    float sinAngle = sin(angle); 

    float xsinAngle = x * sinAngle; 
    float ysinAngle = y * sinAngle; 

    float oneMinusCos = 1.0 - cosAngle; 

    float xyOneMinusCos = xy * oneMinusCos; 

    mat4 target; 
    target[0][0] = xSqd + (1.0 - xSqd)*cosAngle; 
    target[0][1] = xyOneMinusCos; 
    target[0][2] = ysinAngle; 
    target[0][3] = 0.0; 

    target[1][0] = xyOneMinusCos; 
    target[1][1] = ySqd + (1.0 - ySqd)*cosAngle; 
    target[1][2] = - xsinAngle; 
    target[1][3] = 0.0; 

    target[2][0] = - ysinAngle; 
    target[2][1] = xsinAngle; 
    target[2][2] = cosAngle; 
    target[2][3] = 0.0; 

    target[3][0] = 0.0; 
    target[3][1] = 0.0; 
    target[3][2] = 0.0; 
    target[3][3] = 1.0; 

    return target; 
} 

mat4 translationThenRotationZ(float x, float y, float z, float angle) 
{ 
    float cosAngle = cos(angle); 
    float sinAngle = sin(angle); 

    mat4 target; 
    target[0][0] = cosAngle; 
    target[0][1] = -sinAngle; 
    target[0][2] = 0.0; 
    target[0][3] = 0.0; 

    target[1][0] = sinAngle; 
    target[1][1] = cosAngle; 
    target[1][2] = 0.0; 
    target[1][3] = 0.0; 

    target[2][0] = 0.0; 
    target[2][1] = 0.0; 
    target[2][2] = 1.0; 
    target[2][3] = 0.0; 

    target[3][0] = x; 
    target[3][1] = y; 
    target[3][2] = z; 
    target[3][3] = 1.0; 

    return target; 
}