简体   繁体   English

将当前时间传递给OpenGL ES 2.0着色器以进行纹理动画:动画在一定时间后停止

[英]Passing current time to OpenGL ES 2.0 shader for texture-animation: animation stops after certain time

I want to pass the current time to my Shader for texture-animation like this: 我想将当前时间传递给我的Shader纹理动画,如下所示:

float shaderTime = (float)((helper::getMillis() - device.stat.startTime));
glUniform1f(uTime, shaderTime);

To animate the texture I do: GLSL Fragment Shader: 为我的纹理设置动画:GLSL Fragment Shader:

#if defined GL_ES && defined GL_FRAGMENT_PRECISION_HIGH
    #define HIGHFLOAT highp
#endif
uniform HIGHFLOAT float uTime;

...

void main()
{
    vec2 coord = vTexCoord.xy;
    coord.x += uTime*0.001;

    gl_FragColor = texture2D(uTex, coord);
}

My problem is: if I run the program for a while: 我的问题是:如果我运行程序一段时间:

  • The first minute: Everything is animating fine 第一分钟:一切都很好动画

  • After ~5 minutes: The animation stutters 约5分钟后:动画口吃

  • After ~10 minutes: The animation has stopped 约10分钟后:动画停止了

Any Ideas how to fix this? 任何想法如何解决这一问题?

floats lose precision as they get larger which will result in the stuttering as the number gets larger. 漂浮物随着它们变大而失去精确度,这将导致随着数量变大而出现口吃。 Also the coordinates that you can use to sample a texture will have a numerical limit so will fail after you go over it. 此外,您可以用来对纹理进行采样的坐标将具有数字限制,因此在您查看之后将失败。

You should wrap your time value so it doesn't go over a certain point. 你应该包装你的时间值,以便它不会超过某一点。 For example, adding 1.5 to the UV coordinates across an entire triangle is the same as adding 0.5, so just wrap your values so that uTime*0.001 is always between 0 and 1. 例如,在整个三角形的UV坐标上添加1.5与添加0.5相同,因此只需包装您的值,使uTime * 0.001始终在0和1之间。

You can also consider switching time to be an integer so that it doesn't lose precision. 您还可以考虑将时间切换为整数,以便不会丢失精度。 You can multiply this integer by a constant delta value in your shader. 您可以在着色器中将此整数乘以常量delta值。 eg multiply by 1/30 if your framerate is 30fps. 例如,如果您的帧率为30fps,则乘以1/30。

Like Muzza says, the coordinates that using to sample a texture will have a limit. 就像Muzza所说,用于采样纹理的坐标将有一个限制。 This leads to the problem you face. 这会导致您遇到的问题。

There are also some alternative methods to do texture-animation without modify the fragment shader. 还有一些替代方法可以在不修改片段着色器的情况下进行纹理动画。 For example, revise the projection matrix to choose which part of the texture you want to see. 例如,修改投影矩阵以选择要查看的纹理部分。 Modify the view port when the time goes is another way can help. 时间过去修改视口是另一种方法可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM