C++ 如何解决Blinn/Loop';s分辨率独立曲线渲染?
在实现Blinn/Loop的曲线绘制算法时,我意识到在循环曲线类型上有一个特例。正如他们(第6-7页第4.4小节)中所述,他们说曲线应该分为两部分,但我真的很困惑如何获得交点 以下是我的渲染结果: 如本文所述,当C++ 如何解决Blinn/Loop';s分辨率独立曲线渲染?,c++,opengl,graphics,shader,bezier,C++,Opengl,Graphics,Shader,Bezier,在实现Blinn/Loop的曲线绘制算法时,我意识到在循环曲线类型上有一个特例。正如他们(第6-7页第4.4小节)中所述,他们说曲线应该分为两部分,但我真的很困惑如何获得交点 以下是我的渲染结果: 如本文所述,当td/sd或te/se介于值[0,1]之间时,会出现此伪影 我的源代码: ... case CURVE_TYPE_LOOP: td = d2 + sqrt(4.0 * d1 * d3 - 3.0 * d2 *d2); sd = 2.0 * d1;
td/sd
或te/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;
...
。。。
案例曲线类型循环:
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;
如果((td/sd>0.0&&td/sd<1.0)| |(te/se>0.0&&te/se<1.0))
std::cout解决了它
我应该得到分割值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 x0123 = (x123 - x012) * splitLoop + x012;
double y0123 = (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...
}
//get t
双splitLoop=-1.0;
道岔(曲线型)
{
案例曲线类型未知:
打破
案例曲线_类型_蛇形:
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 0.0&(td/sd)<1.0)
{
splitLoop=td/sd;
}
如果((te/se)>0.0&(te/se)<1.0,则为其他情况
{
splitLoop=te/se;
}
F 0.0&&splitLoop<1.0)
{
//分裂
双x01=(x1-x0)*拆分环+x0;
双y01=(y1-y0)*拆分环+y0;
双x12=(x2-x1)*拆分环+x1;
双y12=(y2-y1)*拆分环+y1;
双x23=(x3-x2)*拆分环+x2;
双y23=(y3-y2)*拆分环+y2;
双x012=(x12-x01)*拆分环+x01;
双y012=(y12-y01)*分流环+y01;
双x123=(x23-x12)*拆分环+x12;
双y123=(y23-y12)*拆分环+y12;
双x0123=(x123-x012)*拆分环+x012;
双y0123=(y123-y012)*拆分环+y012;
//曲线A(递归)
抽立方(x0,y0,x01,y01,x012,y012,x0123,y0123);
//曲线B(递归)
抽立方(x0123、y0123、x123、y123、x23、y23、x3、y3);
}
其他的
{
//像往常一样画画。。。
}
==编辑==
在我再次试验一段时间后,当子曲线上的td/sd
或te/se
的值再次位于[0,1]之间时,我的程序上出现了一个数字错误,因为我的程序通过调用DrawCubic()
,使用递归,这导致了递归堆错误
同时,我使用“hack”解决方案,在递归调用中不调用DrawCurve()
(确保只调用一次递归)。到目前为止,结果非常令人满意,我没有看到任何工件
任何反馈都非常受欢迎,因为我在数值计算方面不是很好:)