glTF icon indicating copy to clipboard operation
glTF copied to clipboard

Subdivision surfaces via bezier patches

Open myaaaaaaaaa opened this issue 2 years ago • 0 comments

Introduction

It's possible to take a model meant for Catmull-Clark subdivision and convert it into a list of Bezier patches.

The proof-of-concept here shows that it's possible to get results very close to Catmull-Clark this way, even at very low polycounts:

1690833275 1690833137 GREEN: Original lowpoly quad model ||| YELLOW: Bezier patch control points ||| RED: Bezier patch subdivision surface ||| BLUE: Catmull-Clark subdivision surface, for comparison ||| WHITE: Quad/Bezier patch borders

1690833156 Circle test. Note how Bezier patch subdivision surfaces (RED) need fewer points than Catmull-Clark subdivision surfaces (BLUE) to create rounder circles.

1690833235 Bevel test. Support loops work the same way for both surfaces.

Rationale

Subdivision surfaces are a widely desired feature, see:

  • #1362
  • #1687
  • #1783

The industry-standard algorithm for subdivision surfaces is the Catmull-Clark method, which has a number of downsides that makes it ill-suited for inclusion into glTF:

  • Topology information is necessary since vertices must take a weighted average of nearby vertices. This information must somehow be stored in glTF or rebuilt by importers, adding complexity no matter which option is chosen.
  • Supporting auxiliary data such as edge creases would be ideal, but this would require even more information to be stored in glTF and implemented in every renderer.
  • It's unclear how UVs must be subdivided at runtime, as there are cases where UVs should be kept sharp. Blender has a set of options to control this.
  • The requirement for topology information makes Catmull-Clark a poor fit for hardware tessellation, since tessellation prefers a list of independent patches to properly take advantage of GPU parallelism.

Instead, by introducing an intermediate step where a Catmull-Clark subdivision surface is first converted to a "Bezier patch subdivision surface", external applications can "bake" all of this information into the control points of the Bezier patches. This reduces the complexity of the data that needs to be stored within glTF, since now it only needs to store a very simple Bezier cage where every 16 mesh.primitive.attributes form the control points of a 4x4 Bezier patch.

Beziergon svg Splines can be created by specifying Bezier curves in a piecewise manner. While every individual Bezier curve is independent, as long as the control points are linear, the final curve will be seamless. A similar property holds with Bezier patches.

By carefully placing control points during conversion, we can keep all of the desired properties of Catmull-Clark subdivision surfaces (G1 continuity, edge creases, etc) and shift the burden of implementing them to DCC exporters or specialized converters, which lines up with the philosophy of glTF.

While the proof-of-concept converter demonstrated above is not able to match the exact curvature of Catmull-Clark, adoption of a Bezier patch primitive mode would enable applications to experiment with solvers that can match it more closely if this is desired.

myaaaaaaaaa avatar Jul 31 '23 18:07 myaaaaaaaaa