Draw Quadratic Curve on GPU

前端 未结 1 1764
北海茫月
北海茫月 2020-11-27 07:16

My task is to render quadratic Bezier curve (path) via Stage3d (Adobe Flash) technology, which have no any extensions for that drawing out-of-the box (while OpenGl have it,

相关标签:
1条回答
  • 2020-11-27 07:40

    For 3 control point Bezier curves I would:

    1. use triangles as primitives
    2. enlarge control points to include area around curve to avoid artifacts

    triangle enlargement

    This way is fast and there is no problem to compute A',B',C' from A,B,C and vice versa. If the scale is constant (for example scale=1.25) then the max usable curve thickness<=2.0*min(|control_point-M|)*(scale-1.0).

    For safer enlargement you can compute exact scale needed (for example in geometry shader) and pass it to vertex and fragment ... All of above can be done by Geometry shader. You should use transparency to correctly join the curves together. The average middle point should stay the same M=A+B+C=A'+B'+C'

    if transparency is not an option

    Then you need to change the approach so pass control points and position inside textures.

    1. create one 2D float texture with control points
    • something like float pnt[9][N]
    • pnt[0,1,2][] is control point A(x,y,z)
    • pnt[3,4,5][] is control point B(x,y,z)
    • pnt[6,7,8][] is control point C(x,y,z)
    1. also create 1D color texture
    • something like rgba col[N]
    • The x axis resolution of both textures = N is the number of Bezier curves
    1. now draw single Quad covering entire screen

    And inside fragment shader check if pixel is inside any of the curve. If yes output its color ...

    This can get very slow for high Bezier curve count N

    [edit1] almost collinear control points

    for those I would use Quads

    quad enlarge

    • D,E are mirrored points A,B around C
    • D=C+C-A
    • E=C+C-B
    • C is the middle point M = (A+B+D+E)/4 = C = (A'+B'+C'+D')/4
    • and A',B',C',D' are enlarged A,B,D,E control points
    • A'=C+(A -C)*scale
    • B'=C+(B -C)*scale
    • A =C+(A'-C)/scale
    • B =C+(B'-C)/scale

    This can be used for any Bezier not just almost colinear but it uses larger polygons so it will be slower on performance (more fragments then really needed)

    Here more advanced/optimized GLSL approach with complete implementation of cubic BEZIER curves:

    • rendering 2D cubic BEZIER with GLSL
    0 讨论(0)
提交回复
热议问题