Algorithm 在GPU上绘制二次曲线

Algorithm 在GPU上绘制二次曲线,algorithm,fragment-shader,bezier,triangulation,stage3d,Algorithm,Fragment Shader,Bezier,Triangulation,Stage3d,我的任务是通过Stage3d(adobeflash)技术绘制二次贝塞尔曲线(path),该技术对开箱即用的绘图没有任何扩展(据我所知,OpenGl有它)。是的,有一个Starling扩展图形,但它使用简单的方法将曲线段划分为许多直线,这会为我的长曲线路径生成许多三角形 所以。。对于Loop和Blinn,有一种渲染分辨率无关的形状的完美方法。我读过GPUGems3文章(GPUGems3_ch25.html) 并将片段着色器移植到AGAL2: 二次曲线像素着色器 float4quadraticps(

我的任务是通过Stage3d(adobeflash)技术绘制二次贝塞尔曲线(path),该技术对开箱即用的绘图没有任何扩展(据我所知,OpenGl有它)。是的,有一个Starling扩展图形,但它使用简单的方法将曲线段划分为许多直线,这会为我的长曲线路径生成许多三角形

所以。。对于Loop和Blinn,有一种渲染分辨率无关的形状的完美方法。我读过GPUGems3文章(GPUGems3_ch25.html) 并将片段着色器移植到AGAL2:

二次曲线像素着色器

float4quadraticps(float2p:TEXCOORD0,
float4颜色:COLOR0):颜色
{  
//梯度
float2px=ddx(p);
float2py=ddy(p);
//链规
浮动汇率=(2*p.x)*px.x-px.y;
浮动fy=(2*p.x)*py.x-py.y;
//符号距离
浮动标准差=(p.x*p.x-p.y)/sqrt(fx*fx+fy*fy);
//线性α
浮动α=厚度-绝对值(sd);
如果(alpha>1)//内部
颜色a=1;
else如果(alpha<0)//外部
夹子(-1);
其他的
//近边界
颜色a=α;
返回颜色;
}  
它起作用了。但有两个基本问题:

  • 我不理解这个算法:(.我读了有符号距离场、导数和其他……我想了好几个小时,然后又读了一遍——但没有结果!我的问题是:有人帮我解释该着色器中发生了什么(如果可能的话,逐行(!))

  • 第二个问题是,曲线被剪裁在三角形的拐角处,并且厚度可变。请看图片: 如果我画一条路径,它看起来像这样:

  • 我喜欢每个曲线段使用一个三角形的方法,因为不需要任何几何图形。我不需要非常厚的曲线(1-2 px非常好),但可变厚度是个问题。有人能帮我吗

    (对不起,我的英语不是我的母语。)

    [edit1 by Spektre]刚从评论中删除,回答无效

    我计划每个曲线段使用一个三角形,如图所示

    • 路径由许多三角形组成
    • 每个路径段一条(二次曲线)
    • 如果所有控制点共线(位于同一直线上)或几乎共线,如何处理此方法的问题?

    对于3个控制点的贝塞尔曲线,我会:

  • 使用三角形作为基本体
  • 放大控制点以包括曲线周围的区域,以避免瑕疵

  • 这种方法速度很快,从
    A,B,C
    计算
    A',B',C'
    没有问题,反之亦然。如果比例是常数(例如
    scale=1.25
    ),则最大可用曲线
    厚度添加您使用的二次曲线等细节(方程式)每个曲线面片有多少个控制点等…这看起来像是在使用三角形基本体(产生厚度伪影的原因)可能是四边形,如果是四边形,效果会更好(其中控制点以定义的方式位于四边形面片内,如四边形是控制点四边形的不断扩大,或其他任何情况,但这对于一般曲线来说很棘手)或者单独提供控制点作为另一个属性布局谢谢你,Spektre!我想画任何由3个控制点描述的二次Bezier曲线。现在我认为最好的方法是:1.使用一个恒定的放大四边形(2个三角形)作为“画布”在这里,我可以按程序绘制任何东西2.找到具体的二次qurve方程()并将其传递给片段着色器,而不是Loop/Blinn默认方程(u^2-v=0).3.用Loop/Blinn算法绘制新的方程。看看这个你可以很容易地修改代码以满足你的低阶BEZIER…非常感谢你,Spektre!太棒了!!!这是我想的,但我不会写!它可能工作得很快!嗯…我不明白为什么我需要使用透明度…你是什么意思?second方法现在也不完全清楚…(@Ilya如果你只有单色贝塞尔曲线,那么你不需要透明度,但你需要扔掉曲线没有使用的碎片。否则三角形的空白区域(包括重叠/放大区域)将清除已绘制的bezier曲线…第二种方法是,对于每个像素/片段,循环通过所有bezier曲线的所有控制点,如果在三角形内部,则计算它是否属于该bezier曲线,并设置颜色…是的,我想丢弃曲线未使用的片段,如您所说。我计划使用一个三角形p呃,一个曲线段,如下图所示。这种方法的一个问题是,如果所有控制点都是共线的(位于同一条直线上),或者几乎是共线的呢?
    
    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;  
    }