Ily*_*lya 9 algorithm bezier triangulation fragment-shader stage3d
我的任务是通过Stage3d(Adobe Flash)技术渲染二次贝塞尔曲线(路径),该技术没有开箱即用的任何扩展(而OpenGl拥有它,据我所知).是的,有一个Starling-Extension-Graphics,但是它使用简单的方法将曲线段划分为许多直线,这为我的长曲线路径生成了很多三角形.
所以..有一种完美的方式来渲染Loop和Blinn的分辨率独立形状.我已经阅读了GPUGems3文章(gpugems3_ch25.html)并将该片段着色器移植到AGAL2:
二次曲线像素着色器
float4 QuadraticPS(float2 p : TEXCOORD0,
float4 color : COLOR0) : COLOR
{
// Gradients
float2 px = ddx(p);
float2 py = ddy(p);
// Chain rule
float fx = (2*p.x)*px.x - px.y;
float fy = (2*p.x)*py.x - py.y;
// Signed distance
float sd = (p.x*p.x - p.y)/sqrt(fx*fx + fy*fy);
// Linear alpha
float alpha = thickness - abs(sd);
if (alpha > 1) // Inside
color.a = 1;
else if (alpha < 0) // Outside
clip(-1);
else
// Near boundary
color.a = alpha;
return color;
}
Run Code Online (Sandbox Code Playgroud)
有用.但是有两个基本问题:
我不明白那个算法:(.我读过有关签名的距离场,衍生物和其他...我想了很多时间再读一遍 - 但没有结果!我的问题是:有没有人帮我解释发生了什么那个着色器(逐行(!),如果可能的话)?
第二个问题是曲线被夹在三角形的拐角处并且具有可变的厚度.请看图片:https: //monosnap.com/file/84EBOuQ1czNM5lprQ5VlnRUKP2mKmW 因此,如果我画一条路径,它看起来像这样:https://monosnap.com/file/54Zs5Xui6s3BL6lNdZRCx9ibcV2bCF
我喜欢这种方法,每个曲线段使用一个三角形,因为不需要任何几何.而且我不需要非常粗的曲线(1-2 px非常好),但是可变厚度是个问题.有谁能够帮我?
(抱歉我的英语.这不是我的母语.)
[Spektre编辑]刚刚发表评论和无效答案
我计划每个曲线段使用一个三角形,类似于图片

对于3个控制点贝塞尔曲线,我会:
放大控制点以包括曲线周围的区域以避免伪影

这种方式很快,计算A',B',C'起来没有问题,A,B,C反之亦然.如果比例恒定(例如scale=1.25)则为最大可用曲线thickness<=2.0*min(|control_point-M|)*(scale-1.0).
为了更安全地放大,您可以计算所需的精确比例(例如在几何着色器中)并将其传递给顶点和片段......以上所有都可以通过几何着色器完成.您应该使用透明度将曲线正确连接在一起.平均中间点应该保持不变M=A+B+C=A'+B'+C'
如果透明度不是一种选择
然后你需要改变方法,以便传递控制点和纹理内部的位置.
float使用控制点创建一个2D 纹理
float pnt[9][N]pnt[0,1,2][] 是控制点 A(x,y,z)pnt[3,4,5][] 是控制点 B(x,y,z)pnt[6,7,8][] 是控制点 C(x,y,z)还可以创建1D颜色纹理
rgba col[N]x两个纹理的轴分辨率= N是贝塞尔曲线的数量现在绘制单个四边形覆盖整个屏幕
并且在片段着色器内部检查像素是否在任何曲线内.如果是则输出其颜色......
对于高贝塞尔曲线计数,这可能变得非常慢 N
[edit1]几乎共线控制点
对于那些我会使用四边形

D,E是A,B周围的镜像点CD=C+C-AE=C+C-BC 是中间点 M = (A+B+D+E)/4 = C = (A'+B'+C'+D')/4A',B',C',D'是扩大的A,B,D,E控制点A'=C+(A -C)*scaleB'=C+(B -C)*scaleA =C+(A'-C)/scaleB =C+(B'-C)/scale这可以用于任何Bezier,而不仅仅是几乎共线,但它使用更大的多边形,因此性能会更慢(然后真正需要更多碎片)