我的顶点着色器中有一个 uniform,其值可以从 0 变为 1,无需插值。但是,我希望它随时间进行插值,但我不想在 Javascript 中(从 CPU)执行此操作。我希望它在变化时(发生在某些用户输入时)从 0 插值到 1(或返回)。
(我确实有一个递增的 uTime
制服,我想我可以用它来解决这个问题)?
我希望这足以清楚地解释我的问题。 TIA。
最佳答案
我想,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 interpolation额外使用 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给出一个值,该值根据 Radian 中的 Angular 在 -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),则需要一些其他信息。添加另一个类型为 float
的统一变量 (uTarget),并将其设置为 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);
// [...]
}
关于javascript - 根据时间插入变化的值(glsl),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59335783/