And*_*ndy 2 java shader android opengl-es-2.0
我过去曾做过 Open GL ES,但已经是很久以前的事情了。从我现在读到的内容来看,似乎更加强调管理自己的矩阵堆栈并将矩阵直接推入顶点着色器以定位对象。
这一切都很好,但我只是想知道你打算在着色器方面走多远。我不知道它们是否仅用于简单的事情,或者我可以将它们用于翻页效果。肯定会有很多数学需要计算。感觉这是一个很好的地方,但我没有经验,不知道这是否有任何问题。
我打算将映射到着色器的手指位置的点输入到着色器,然后着色器将根据手指位置偏移构成页面的网格中的每个顶点。
我将在带有 OpenGL ES 2.0 的 Android 应用程序中尝试此操作。
所以,
问题
这看起来是一个合理的方法吗?如果不是,考虑到我需要的效果和现代 OpenGL API,充分利用图形芯片的最佳方法是什么?
到目前为止我研究过的内容
我读过许多博客和教程,包括Modern Open GL 教程,但着色器始终用于照明或仅用于基本定位。我认为翻页效果的计算可能比我见过的着色器中需要更多的数学,但我不知道着色器中的数学量会太多!
我知道我应该尝试一下,但是在这个项目开始之前我还有一些时间,而且我现在正在真正地研究!
更新
作为更新,我最近发现着色器有指令限制,因此一个要求是我能够在指令限制内获得所有翻页数学。
我已经在 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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1615 次 |
最近记录: |