首页 > 解决方案 > 根据时间插值变化的值 (glsl)

问题描述

我的顶点着色器中有一个制服,其值可以从 0 变为 1,无需插值。但是,我希望它随着时间的推移进行插值,但我不想在 Javascript(来自 CPU)中执行此操作。我希望它在更改时(发生在某些用户输入上)从 0 插值到 1(或返回)。

(我确实有一个递增的uTime制服,我想我可以用它来解决这个问题)?

我希望这足以清楚地解释我的问题。TIA。

标签: javascriptglslshader

解决方案


我想,这uTime包含以毫秒为单位的时间。将该值除以时间跨度,得到一个在时间跨度内增加 1 的值。
该值的小数部分不断地从 0.0 变为 1.0,并再次从 0.0 开始。一个数的小数部分可以通过 计算fract。例如:(
如果单位uTime是秒,那么timespan必须是3.0)

uniform float uTime; // time in milliseconds

void main()
{
    const float timespan = 3000.0; // e.g. 3 seconds
    float w = fract(uTime / timespan);

    // [...]
}

对于Hermite 插值,另外使用smoothstep

uniform float uTime; // time in milliseconds

void main()
{
    const float timespan = 3000.0; // e.g. 3 seconds
    float w = smoothstep(0.0, 1.0, fract(uTime / timespan));

    // [...]
}

另一个不错的效果可以通过使用sin. Sine给出的值在 -1.0 和 1.0 之间连续变化,具体取决于弧度[0.0, 2*PI] 中的角度,例如:

uniform float float uTime; // time in milliseconds

void main()
{
    const float timespan = 3000.0; // e.g. 3 seconds
    float w = sin(2.0 * 3.14159 * uTime / timespan) * 0.5 + 0.5;

    // [...]
}

如果你想在某个时间点开始动画,那么你需要一个uStartTime表示时间点的第二个统一变量 ( )。变量必须具有与 相同的单位uTime
当动画必须开始时,设置uStartTime. 开始时它的值为 0。如果uStartTime小于或等于uTime,则动画为 0.0。这是罕见的情况,只是片刻,何时uStartTime设置。它uTime大于或等于uStartTime + timespan动画的 1.0。您无需计算小数部分,而是将clamp当前时间与开始时间的差值计算为 0.0 到 1.0 的范围。例如:

uniform float uTime; // time in milliseconds
uniform float uStartTime; 

void main()
{
    const float timespan = 3000.0; // e.g. 3 seconds
    float w = clamp((uTime-uStartTime) / timespan, 0.0, 1.0);

    // [...]
}

如果要设置插值方向(从 0 到 1 或 1 到 0),取决于“方向”,您需要一些附加信息。添加另一个类型的统一变量 (uTarget)float并将其设置为 0.0 或 1.0。该值定义插值目标:

uniform float uTime; // time in milliseconds
uniform float uStartTime; 
uniform float uTarget; // 0.0 or 1.0 

void main()
{
    const float timespan = 3000.0; // e.g. 3 seconds
    float w = clamp((uTime-uStartTime) / timespan, 0.0, 1.0);
    w = mix(1.0-w, w, uTarget);

    // [...]
}

推荐阅读