如何使用three.js实现两种颜色之间的渐变动画?

7
我有一个three.js对象,它有一个给定的颜色。我想要平滑地将其动画化为另一种颜色。在动画过程中,它应该只显示起点和终点之间的直接渐变。也就是说,它不应该在RGB颜色空间内线性执行缓动。我甚至不确定在HSV空间内进行线性缓动是否会看起来很好。
如何在three.js对象上实现这种颜色缓动效果?
1个回答

5

我有一个版本,可以在HSV空间中制作补间动画。但不完美,因为在过程中可能会出现许多不同的色调。

Three.js没有包含从THREE.Color获取HSV值的方法。所以,需要添加一个:

THREE.Color.prototype.getHSV = function()
{
    var rr, gg, bb,
        h, s,
        r = this.r,
        g = this.g,
        b = this.b,
        v = Math.max(r, g, b),
        diff = v - Math.min(r, g, b),
        diffc = function(c)
        {
            return (v - c) / 6 / diff + 1 / 2;
        };

    if (diff == 0) {
        h = s = 0;
    } else {
        s = diff / v;
        rr = diffc(r);
        gg = diffc(g);
        bb = diffc(b);

        if (r === v) {
            h = bb - gg;
        } else if (g === v) {
            h = (1 / 3) + rr - bb;
        } else if (b === v) {
            h = (2 / 3) + gg - rr;
        }
        if (h < 0) {
            h += 1;
        } else if (h > 1) {
            h -= 1;
        }
    }
    return {
        h: h,
        s: s,
        v: v
    };
};

然后,缓动就相对简单了:
new TWEEN.Tween(mesh.material.color.getHSV())
    .to({h: h, s: s, v: v}, 200)
    .easing(TWEEN.Easing.Quartic.In)
    .onUpdate(
        function()
        {
            mesh.material.color.setHSV(this.h, this.s, this.v);
        }
    )
    .start();

我很想听到更符合感知自然的过渡方式。


2
用 RGB 試試看呢? new TWEEN.Tween(mesh.material.color).to({r: 1, g: 0, b: 0 }, 200).start() - mrdoob
@mrdoob,我以前在RGB空间内进行线性混合的实验往往会产生丑陋的中间颜色。不过我会再试一次。目前为止,上述方法似乎运作得相当不错。 - Drew Noakes
啊,我误解了你。是的,听起来你的方法很好。 - mrdoob
请问我该如何将这个实现到 tween.js 中? - thednp
2
有人有这个的fiddlejs吗?我总是得到“object.material.color.setHSV不是一个函数”的错误... - binoculars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接