2014-01-07 32 views
3

在曲线渲染中实现Blinn/Loop算法时,我意识到在循环曲线类型上有一个特殊情况。如他们的paper(4.4小节,第6-7页)所述,他们说曲线应该分成两部分,但我真的很困惑如何获得交点。如何在Blinn/Loop的分辨率独立曲线渲染中解决渲染伪影?

这是我的绘制结果: enter image description here

正如在文件中指出,此工件发生时或者td/sdte/se在于之间值[0,1]。

我的源代码:

... 

case CURVE_TYPE_LOOP: 

    td = d2 + sqrt(4.0 * d1 * d3 - 3.0 * d2 *d2); 
    sd = 2.0 * d1; 

    te = d2 - sqrt(4.0 * d1 * d3 - 3.0 * d2 * d2); 
    se = 2.0 * d1; 

    if((td/sd > 0.0 && td/ sd < 1.0) || (te/se > 0.0 && te/ se < 1.0)) 
     std::cout << "error\n"; 

    // F matrix will be multiplied with inverse M3 to obtain tex coords (I use Eigen library btw...) 
    F << td * te,     td * td * te,        td * te * te,       1,  
     (-se * td) - (se * te), (-se * td * td) - (2.0 * sd * te * td),  (-sd * te * te) - (2.0 * se * td * te), 0, 
     sd * se,     te * sd * sd + 2.0 * se * td* sd,   td * se * se + 2 * sd * te * se,  0, 
     0,       -sd * sd * se,        -sd * se * se,       0; 

    break; 

... 

回答

4

解决它,

我应该得到的分裂值t,

这里是我的代码:

// get t 
double splitLoop = -1.0; 

switch (curve_type) 
{ 

case CURVE_TYPE_UNKNOWN: 
    break; 

case CURVE_TYPE_SERPENTINE: 

    tl = d2 + ((1.0/sqrt(3.0)) * sqrt(3.0 * d2 * d2 - 4.0 * d1 * d3)); 
    sl = 2.0 * d1; 

    tm = d2 - ((1.0/sqrt(3.0)) * sqrt(3.0 * d2 * d2 - 4.0 * d1 * d3)); 
    sm = 2.0 * d1; 

    F << tl * tm,     tl * tl * tl,   tm * tm * tm,   1, 
     -(sm * tl) -(sl * tm),  -(3.0 * sl * tl * tl), -(3.0 * sm * tm * tm), 0, 
     sl * sm,     3.0 * sl * sl * tl,  3.0 * sm * sm * tm, 0, 
     0,       -(sl * sl * sl),  -(sm * sm * sm),  0; 

    break; 

case CURVE_TYPE_LOOP: 

    td = d2 + sqrt(4.0 * d1 * d3 - 3.0 * d2 *d2); 
    sd = 2.0 * d1; 

    te = d2 - sqrt(4.0 * d1 * d3 - 3.0 * d2 * d2); 
    se = 2.0 * d1; 

    // Get splitting t 
    if((td/sd) > 0.0 && (td/sd) < 1.0) 
    { 
     splitLoop = td/sd; 
    } 
    else if((te/se) > 0.0 && (te/ se) < 1.0) 
    { 
     splitLoop = te/se; 
    } 

    F << td * te,     td * td * te,        td * te * te,       1,  
      (-se * td) - (se * te), (-se * td * td) - (2.0 * sd * te * td),  (-sd * te * te) - (2.0 * se * td * te), 0, 
      sd * se,    te * sd * sd + 2.0 * se * td* sd,   td * se * se + 2 * sd * te * se,  0, 
      0,      -sd * sd * se,        -sd * se * se,       0; 

    break; 

case CURVE_TYPE_QUADRATIC: 
    break; 

case CURVE_TYPE_LINE: 
    break; 

} 

if(splitLoop > 0.0 && splitLoop < 1.0) 
{ 
    // SPLIT 
    double x01 = (x1 - x0) * splitLoop + x0; 
    double y01 = (y1 - y0) * splitLoop + y0; 

    double x12 = (x2 - x1) * splitLoop + x1; 
    double y12 = (y2 - y1) * splitLoop + y1; 

    double x23 = (x3 - x2) * splitLoop + x2; 
    double y23 = (y3 - y2) * splitLoop + y2; 

    double x012 = (x12 - x01) * splitLoop + x01; 
    double y012 = (y12 - y01) * splitLoop + y01; 

    double x123 = (x23 - x12) * splitLoop + x12; 
    double y123 = (y23 - y12) * splitLoop + y12; 

    double x= (x123 - x012) * splitLoop + x012; 
    double y= (y123 - y012) * splitLoop + y012; 

    // CURVE A (recursive) 
    DrawCubic(x0, y0, x01, y01, x012, y012, x0123, y0123); 

    // CURVE B (recursive) 
    DrawCubic(x0123, y0123, x123, y123, x23, y23, x3, y3); 
} 
else 
{ 
    // Draw as usual... 

} 

== ==编辑

当我再次尝试一段时间后,当我的程序的td/sdte/se子曲线的值再次位于[0,1]之间时,由于我的程序使用递归调用DrawCubic(),导致递归堆存在数值错误错误。在此期间,我使用'hack'解决方案,在递归调用中我不会调用DrawCurve()(确保递归只调用一次)。到目前为止,结果非常令人满意,我没有看到任何神器。

任何反馈是真正欢迎,因为我不是在数值计算真的很好:)

enter image description here

+0

感谢的人,谢谢你,我重新在我的游戏引擎这个项目。我放弃了它,但感谢您对我原来的主题的回复:[链接](http://stackoverflow.com/questions/15519142/resolution-independent-cubic-bezier-drawing-on-gpu-blinn-loop/15599317?noredirect = 1#comment31532567_15599317),我正试图让它再次运作。 – scippie

+0

刚回来告诉你,你的解决方案完美无缺。谢谢! – scippie

+0

太棒了!如果我遇到问题,我会再提出一个问题 – azer89