难道一个顶点着色器被用于翻页的效果? [英] Could a vertex shader be used for a page turn effect?

查看:397
本文介绍了难道一个顶点着色器被用于翻页的效果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做的Open GL ES在过去,但相当长的一段前。从什么我现在看,似乎还有很多更偏重于管理自己的矩阵堆栈,并直接推你的矩阵分解成一个顶点着色器来定位你的对象。

I've done Open GL ES in the past, but quite a while ago. From what I'm reading now, it seems there is a lot more emphasis on managing your own matrix stacks and pushing your matrices directly into a vertex shader to position your objects.

这是一个好主意,但我只是想知道你打算走多远着色器。我不知道,如果他们只负责简单的事情,或者我可以使用它们的翻页效果。肯定会有很多的数学题需要计算。感觉就像这是一个很好的地方做,但我没有经验,知道是否有任何陷阱这个问题。

This is all well and good, but I'm just wondering how far you're meant to go with shaders. I don't know if they are only for simple things, or can I use them for a page turn effect. There will definitely be a lot of math that needs to be calculated. It feels like this is a good place to do it, but I don't have the experience to know if there are any gotchas with this.

我要输入映射到一个手指位置到着色器的一个点,那么着色器将抵消在网状这使得在页面的每个顶点,基于手指的位置。

I was going to input a point which maps to a finger position to the shader, then the shader would offset each vertex in a mesh which makes up the page, based on the finger position.

我要和OpenGL ES 2.0的尝试这一个Android应用程序。

I'm going to attempt this in an Android App with OpenGl ES 2.0.

因此​​,

问题

这看起来像一个合理的做法,如果不是,这将是获得最大给我需要的效果和MODEN的OpenGL API的图形芯片的最好方法是什么?

我到目前为止已经研究

我已经通过了一些博客和教程,包括教程现代Open GL的的阅读,但着色器始终是照明或只是基本定位。我想计算的翻页效果,可能需要更多的数学比是我见过的着色器,但我不知道怎么在着色器多少数学那就太过分了!

I've read through a number of blogs and tutorials, including Tutorials for Modern Open GL, but the shaders are always for lighting or just basic positioning. I'm thinking the calculations for a page turn effect might require more math than are in the shaders I've seen, but I don't know how much math in a shader would be too much!

我知道我应该放弃这个去看看,但我有一点点的时间,直到该项目开工和我是真的在此刻研究!

I know I should just give this a go and see, but I've got a bit of time until this project starts and I was just really researching at the moment!

更新

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

Just as an update, I recently found out there is an instruction limit for shaders, so one requirement will be that I am able to get all my page turn math within the instruction limit.

推荐答案

我已经实现在OpenGL ES 2.0的顶点着色器页面卷曲效果,我将与大家分享这个code。它使用纹理坐标来控制页面的旋转角度。以此方式,转动不会受三角形网格的在场景中的位置,只多远向下顶点是卷曲页面上。这工作很好,但我最终放弃了这种做法的更简单的实现,其中卷曲与在页面上,并使用纹理伪造一些阴影效果呈现平坦短短三角形伪造。做完左右逢源,我怀疑可能是所有的页面卷曲的效果在那里完成的假冒方式,因为它只是简单得多实施和调试。

I have implemented a page curl effect in an OpenGL ES 2.0 vertex shader and I will share this code with you. It uses the texture coordinates to control the rotation angle of the page. This way, the rotation is not affected by the position of the triangle mesh in the scene, only how far down the vertices are on the curled page. This works well, but I eventually abandoned this approach for a much simpler implementation where the curl was faked with just a few triangles rendered flat over the page and using textures to fake some shadow effects. Having done it both ways, I suspect that probably all of the page curl effects out there are done the fake way because it is just much simpler to implement and debug.

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

这篇关于难道一个顶点着色器被用于翻页的效果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆