OSD Tessellation shader Interface
Basic
Starting with 3.0, Osd tessellation shaders can be used as a set of functions from client shader code. In order to tessellate Osd patches, client shader code should perform the following steps (regular B-spline patch case):
- In a tessellation control shader
- fetch a PatchParam for the current patch
- call OsdComputePerPatchVertexBSpline() to compute OsdPerPatchVertexBezier.
- compute tessellation level. To prevent cracks on transition patches, two vec4 parameters (tessOuterHi, tessOuterLo) will be needed in addition to built-in gl_TessLevelInner/Outers.
- In a tessellation evaluation shader
- call OsdGetTessParameterization() to remap gl_TessCoord to a patch parameter at which to evaluate.
- call OsdEvalPatchBezier()/OsdEvalPatchGregory() to evaluate the current patch.
The following is a minimal example of GLSL code explaining how client shader code uses OpenSubdiv shader functions to tessellate patches of a patch table.
Tessellation Control Shader Example (for BSpline patches)
Tessellation Evaluation Shader Example (for BSpline patches)
Basis Conversion
B-spline Patch
The following diagram shows how the Osd shaders process b-spline patches.

While regular patches are expressed as b-spline patches in Far::PatchTable, the Osd shader converts them into Bezier basis patches for simplicity and efficiency. This conversion is performed in the tessellation control stage. The boundary edge evaluation and single crease matrix evaluation are also resolved during this conversion. OsdComputePerPatchVertexBSpline() can be used for this process. The resulting Bezier control vertices are stored in OsdPerPatchVertexBezier struct.
The tessellation evaluation shader takes an array of OsdPerPatchVertexBezier struct, and then evaluates the patch using the OsdEvalPatchBezier() function.
Gregory Basis Patch
In a similar way, Gregory basis patches are processed as follows:

OsdComputePerPatchVertexGregoryBasis() can be used for the Gregory patches (although no basis conversion involved for the Gregory patches) and the resulting vertices are stored in a OsdPerPatchVertexGreogryBasis struct.
The tessellation evaluation shader takes an array of OsdPerPatchVertexGregoryBasis struct, and then evaluates the patch using the OsdEvalPatchGregory() function.
Legacy Gregory Patch (2.x compatibility)
OpenSubdiv 3.0 also supports 2.x style Gregory patch evaluation (see far_overview). In order to evaluate a legacy Gregory patch, client needs to bind extra buffers and to perform extra steps in the vertex shader as shown in the following diagram:

Tessellation levels
Osd provides both uniform and screen-space adaptive tessellation level computation.
- Uniform tessellation
- OsdGetTessLevelsUniform()
- Screen-space adaptive tessellation
- OsdGetTessLevelsAdaptiveLimitPoints()
Because of the nature of feature adaptive subdivision, we need to pay extra attention for a patch's outer tessellation level for the screen-space adaptive case so that cracks don't appear.
An edge of the patch marked as a transition edge is split into two segments (Hi and Lo).

The Osd shaders uses these two segments to ensure the same tessellation along the edge between different levels of subdivision. In the following example, suppose the left hand side patch has determined the tessellation level of its right edge to be 5. gl_TessLevelOuter is set to 5 for the edge, and at the same time we also pass 2 and 3 to the tessellation evaluation shader as separate levels for the two segments of the edge split at the middle.

Then the tessellation evaluation shader takes gl_TessCoord and those two values, and remaps gl_TessCoord using OsdGetTessParameterization() to ensure the parameters are consistent across adjacent patches.

These tessellation levels can be computed by OsdGetTessLevelsAdaptiveLimitPoints() in the tessellation control shader. Note that this function requires all 16 bezier control points, you need to call barrier() to ensure the conversion is done for all invocations. See osd/glslPatchBSpline.glsl for more details.
Release Notes (3.0.0)
- Currently OsdGetTessParameterization doesn't support fraction spacing. It will be fixed in a future release.