GLSL双精度复数幂函数

GLSL double precision complex number power function

我目前定义了以下 GLSL 函数,用于计算复数的幂。

dvec2 p2 (dvec2 t) {return (dvec2 (cmul(t,t) ));}
dvec2 p3 (dvec2 t) {return (dvec2 (cmul(cmul(t,t),t) ));}
dvec2 p4 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(t,t),t),t) ));}
dvec2 p5 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(t,t),t),t),t) ));}
dvec2 p6 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t) ));}
dvec2 p7 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t),t) ));}
dvec2 p8 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t),t),t) ));}

我可以在像

这样的复数公式中使用这些
dvec2 func (dvec2 z) { return (dvec2( cadd(csub(p4(z),cmul(c5,p2(z))),c4) ));

而且效果很好。

现在我想摆脱那些 p2、p3、p4 等函数并编写一个更通用的幂函数。所以我尝试了以下

dvec2 cpow (dvec2 c, int p) {
    for (int i = 0; i < p; i++) {
    c=cmul(c,c);
    }
    return c;
}

然后我称之为

dvec2 func   (dvec2 z) { return (dvec2( cadd(csub(cpow(z,4),cmul(c5,cpow(z,2))),c4) )); }

但它给出了不同的结果。我可以在网上找到很多复杂的电源例程,但它们都使用 log 和 trig 调用,这些调用不是双精度的,我需要这个 GLSL 代码。

任何 GLSL 大师都可以找出为什么那个简单的 cpow 循环不起作用吗?

您的转换公式是错误的...因为您乘以子结果意味着您得到的是平方而不是乘法...您必须将函数更改为:

dvec2 cpow (dvec2 c, int p) 
    {
    dvec2 a=(1.0,0.0); // assuming a.x is real part
    for (int i = 1; i <= p; i++) a=cmul(a,c);
    return a;
    }

如果你想要更快的东西,你可以使用 甚至端口到极坐标表示在那里做电源并转换回笛卡尔形式的复数。有关详细信息,请参阅:

在四分形的 GLSL 代码中寻找 vec2 cpow(vec2 a,vec2 b) // a^b