1
$\begingroup$

As an information, Vulkan is a low-level abstraction layer thru modern GPU. It allows programmers to program the GPU and assemble rendering pipeline. On that pipeline, there are modules of program which are called "shaders". As a programmer, we only have control on programmable shaders, not fixed shaders. For simplicity, let's only use two types of programmable shaders:

  1. Vertex Shader

    A program for calculating geometric transformation for each point. Every 3 points always represent a triangle, but can be configured to be 3 lines or 3 dots.

  2. Fragment Shader

    This is per-pixel program to calculate color for each pixel on that triangles (or lines).

From those shaders, I would like to implement bezier curve (for shape) and scanline algorithm for fill color, rendered with GPU. The planned result would be like this.

Heart shape drawn with bezier and scanline

The Problem

  1. To draw Bezier lines, pixel position must be set. Whereas in fragment shader, the pixel position cannot be set by programmer because GPU already set the position.
  2. As far as I know, generating curved lines is not possible by only set control points as vertices. Any workaround for this problem?
  3. Even if the bezier can be drawn by GPU, how do I implement scanline algorithm for adding fill color with fragment shader?

NOTE: I already explored learning resources via internet. However, none of them actually talks about bezier curve + scanline algorithm implementation with Vulkan. Perhaps I missed something? Please let me know

$\endgroup$

1 Answer 1

1
$\begingroup$

The typical solution is to compute a bounding structure using triangles that would be transformed by the vertex shader. The bounding structure is computed to be large enough to fit the entire curve that will be drawn inside of it. It can be anything from a simple quad to a tightly fitted polygon.

The fragment shader then does the work of deciding which fragments get colored by figuring out if a fragment lies in the area shaded by the curve. If a fragment isn't shaded then either the fragment is discarded, it is set to some background color, or it's alpha value is set to be fully transparent depending on programs needs. And of course if it is shaded the color is set to the curve color.

Normally the computations are done in object space to help simplify some of the logic/computations in the fragment shader.

There are a variety of approach's used to determine if a fragment should be discarded or not for Bezier curves. Such as computing the winding of each curve segment and determining which side of the winding the fragment falls on. Usually the winding is reduced to having a positive and a negative side. If a fragment falls on the positive side of every curve it is kept, otherwise it is discarded.

BTW this is a very general description of how fonts can be drawn directly from font outlines.

The reason you don't find a lot of information about this on the web is because it generally falls under more advanced techniques, there have also been attempts to create generalized algorithms that have several aliasing problems resulting from numerical instability.

$\endgroup$
1
  • $\begingroup$ "...by figuring out if a fragment lies in the area shaded by the curve" Thanks for the answer, would you please point the equation for that statement? $\endgroup$ Jan 2, 2022 at 3:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.