diff --git a/documentation/far_overview.rst b/documentation/far_overview.rst index 04b3eae2..f7b3e717 100644 --- a/documentation/far_overview.rst +++ b/documentation/far_overview.rst @@ -294,42 +294,21 @@ to refine primvar data. Far::PatchTable ================ -The patch table is a serialized topology representation. This container is -generated using *Far::PatchTableFactory* from an instance -*Far::TopologyRefiner* after a refinement has been applied. The -FarPatchTableFactory traverses the data-structures of the TopologyRefiner and -serializes the sub-faces into collections of bi-linear and bi-cubic patches as -dictated by the refinement mode (uniform or adaptive). The patches are then -sorted into arrays based on their types. +PatchTable is the collection of patches derived from the refined faces of a particular mesh topology. -.. container:: notebox - - **Release Notes (3.0.0)** - - The organization and API of Far::PatchTable is likely to change - in the 3.1 release to accommodate additional functionality including: - smooth face-varying interpolation on patches, and dynamic feature - adaptive isolation (DFAS), and patch evaluation of Loop subdivision - surfaces. +This collection is created using *Far::PatchTableFactory* from an instance +of *Far::TopologyRefiner* after refinement has been applied. Patch Arrays ************ -The patch table is a collection of control vertex indices. Meshes are decomposed -into a collection of patches, which can be of different types. Each type -has different requirements for the internal organization of its -control-vertices. A PatchArray contains a sequence of multiple patches that -share a common set of attributes. +The PatchTable is organized into patch arrays. All patches in each array have +the same type except for face-varying patch arrays which may have a mix of regular and irregular patch types. -While all patches in a PatchArray will have the same type, each patch in the -array is associated with a distinct *PatchParam* which specifies additional -information about the individual patch. +The *PatchDescriptor* provides the fundamental description of a patch, including the number of control points per patch as well as the basis for patch evaluation. -Each PatchArray contains a patch *Descriptor* that provides the fundamental -description of the patches in the array. - -The PatchArray *ArrayRange* provides the indices necessary to track the records -of individual patches in the table. +Each patch in the array is associated with a *PatchParam* which +specifies additional information about the individual patch. .. image:: images/far_patchtables.png :align: center @@ -350,19 +329,21 @@ PatchTable: +---------------------+------+---------------------------------------------+ | LINES | 2 | Lines : useful for cage drawing | +---------------------+------+---------------------------------------------+ -| QUADS | 4 | Bi-linear quads-only patches | +| QUADS | 4 | Bi-linear quadrilaterals | +---------------------+------+---------------------------------------------+ -| TRIANGLES | 3 | Bi-linear triangles-only mesh | +| TRIANGLES | 3 | Linear triangles | +---------------------+------+---------------------------------------------+ -| LOOP | n/a | Loop patch (currently unsupported) | +| LOOP | 12 | Quartic triangular Box-spline patches | +---------------------+------+---------------------------------------------+ -| REGULAR | 16 | B-spline Basis patches | +| REGULAR | 16 | Bi-cubic B-spline patches | +---------------------+------+---------------------------------------------+ | GREGORY | 4 | Legacy Gregory patches | +---------------------+------+---------------------------------------------+ | GREGORY_BOUNDARY | 4 | Legacy Gregory Boundary patches | +---------------------+------+---------------------------------------------+ -| GREGORY_BASIS | 20 | Gregory Basis patches | +| GREGORY_BASIS | 20 | Bi-cubic quadrilateral Gregory patches | ++---------------------+------+---------------------------------------------+ +| GREGORY_TRIANGLE | 18 | Quartic triangular Gregory patches | +---------------------+------+---------------------------------------------+ @@ -372,6 +353,10 @@ table as well as the method used to evaluate values. Patch Parameterization ********************** +Here we describe the encoding of the patch parameterization for +quadrilateral patches. The encoding for triangular patches is similar, +please see the API documentation of Far::PatchParam for details. + Each patch represents a specific portion of the parametric space of the coarse topological face identified by the PatchParam FaceId. As topological refinement progresses through successive levels, each resulting patch @@ -435,11 +420,9 @@ sharpness parameter. .. container:: notebox - **Release Notes (3.0.0)** + **Release Notes (3.x)** - Currently, the crease sharpness parameter is encoded as a separate - PatchArray within the PatchTable. This parameter may be combined - with the other PatchParam values in future releases. Also, evaluation + Evaluation of single-crease patches is currently only implemented for OSD patch drawing, but we expect to implement support in all of the evaluation code paths for future releases. @@ -453,15 +436,6 @@ adaptively to the points of the coarse mesh. However, the final patches generated from irregular faces, e.g. patches incident on an extraordinary vertex might have a representation which requires additional local points. -.. container:: notebox - - **Release Notes (3.0.0)** - - Currently, representations which require local points also require - the use of a StencilTable to compute the values of local points. - This requirement, as well as the rest of the API related to local - points may change in future releases. - Legacy Gregory Patches ********************** @@ -472,15 +446,6 @@ Legacy Gregory patches are used, the PatchTable must also have an alternative representation of the mesh topology encoded as a vertex valence table and a quad offsets table. -.. container:: notebox - - **Release Notes (3.0.0)** - - The encoding and support for Legacy Gregory patches may change - in future releases. The current encoding of the vertex valence - and quad offsets tables may be prohibitively expensive for some - use cases. - Far::StencilTable ================== diff --git a/documentation/osd_overview.rst b/documentation/osd_overview.rst index 6ae8e468..032ee07f 100644 --- a/documentation/osd_overview.rst +++ b/documentation/osd_overview.rst @@ -42,8 +42,8 @@ The main roles of **Osd** are: Compute limit surfaces by limit stencils on CPU/GPU backends - **Limit Evaluation with PatchTable** Compute limit surfaces by patch evaluation on CPU/GPU backends - - **OpenGL/DX11 Drawing with hardware tessellation** - Provide GLSL/HLSL tessellation functions for patch table + - **OpenGL/DX11/Metal Drawing with hardware tessellation** + Provide GLSL/HLSL/Metal tessellation functions for patch table - **Interleaved/Batched buffer configuration** Provide consistent buffer descriptor to deal with arbitrary buffer layout. - **Cross-Platform Implementation** @@ -98,7 +98,8 @@ as a stencil tables as long as Evaluator::EvalStencils() can access the necessar +-----------------------------+-----------------------+-------------------------+ | DX11 ComputeShader (GPU) | D3D11ComputeEvaluator | D3D11StencilTable | +-----------------------------+-----------------------+-------------------------+ - +| Metal (GPU) | MTLComputeEvaluator | MTLStencilTable | ++-----------------------------+-----------------------+-------------------------+ Limit Stencil Evaluation ======================== @@ -141,17 +142,18 @@ Once all control vertices and local points are resolved by the stencil evaluatio | DX11 ComputeShader (GPU) | | D3D11ComputeEvaluator | D3D11PatchTable | | | | (*)not yet supported | | +-----------------------------+-------------------------+-------------------------+ +| Metal ComputeShader (GPU) | | MTLComputeEvaluator | MTLPatchTable | ++-----------------------------+-------------------------+-------------------------+ .. container:: notebox - **Release Notes (3.0.0)** + **Release Notes (3.x)** - * GPU limit evaluation backends (Evaluator::EvalPatches()) only support - BSpline patches. Clients need to specify BSpline approximation for endcap - when creating a patch table. See `end capping `__. + * Osd evaluation backends (Evaluator::EvalPatches()) do not support + evaluation of single-crease or Legacy Gregory patch types. -OpenGL/DX11 Drawing with Hardware Tessellation -============================================== +OpenGL/DX11/Metal Drawing with Hardware Tessellation +==================================================== One of the most interesting use cases of the **Osd** layer is realtime drawing of subdivision surfaces using hardware tessellation. This is somewhat similar to @@ -265,6 +267,8 @@ The methods that need to be implemented for the Evaluators are: +-----------------------+------------------------+------------------+ | D3D11ComputeEvaluator | D3D11 UAV | BindD3D11UAV() | +-----------------------+------------------------+------------------+ +| MTLComputeEvaluator | MTLBuffer | BindMTLBuffer() | ++-----------------------+------------------------+------------------+ The buffers can use these methods as a trigger of interop. **Osd** provides a default implementation of interop buffer for most of the backend combinations. diff --git a/documentation/osd_shader_interface.rst b/documentation/osd_shader_interface.rst index 5ac237e2..92340a47 100644 --- a/documentation/osd_shader_interface.rst +++ b/documentation/osd_shader_interface.rst @@ -50,8 +50,8 @@ The following is a minimal example of GLSL code explaining how client shader cod uses OpenSubdiv shader functions to tessellate patches of a patch table. -Tessellation Control Shader Example (for BSpline patches) -********************************************************* +Tessellation Control Shader Example (for B-Spline patches) +********************************************************** .. code:: glsl @@ -88,8 +88,8 @@ Tessellation Control Shader Example (for BSpline patches) -Tessellation Evaluation Shader Example (for BSpline patches) -************************************************************ +Tessellation Evaluation Shader Example (for B-Spline patches) +************************************************************* .. code:: glsl @@ -160,7 +160,8 @@ are stored in a OsdPerPatchVertexGreogryBasis struct. .. code:: glsl - void OsdComputePerPatchVertexGregoryBasis( + void + OsdComputePerPatchVertexGregoryBasis( ivec3 patchParam, int ID, vec3 cv, out OsdPerPatchVertexGregoryBasis result) The tessellation evaluation shader takes an array of OsdPerPatchVertexGregoryBasis struct, @@ -174,6 +175,54 @@ and then evaluates the patch using the OsdEvalPatchGregory() function. out vec3 N, out vec3 dNu, out vec3 dNv) +Box-spline Triangle Patch +************************* + +While regular triangle patches are expressed as triangular box-spline patches in Far::PatchTable, +the **Osd** shader converts them into triangular Bezier patches for consistency. +This conversion is performed in the tessellation control stage. The boundary edge evaluation is resolved during this conversion. +OsdComputePerPatchVertexBoxSplineTriangle() can be used for this process. +The resulting Bezier control vertices are stored in OsdPerPatchVertexBezier struct. + +.. code:: glsl + + void + OsdComputePerPatchVertexBoxSplineTriangle( + ivec3 patchParam, int ID, vec3 cv[12], out OsdPerPatchVertexBezier result); + +The tessellation evaluation shader takes an array of OsdPerPatchVertexBezier struct, +and then evaluates the patch using the OsdEvalPatchBezierTriangle() function. + +.. code:: glsl + + void OsdEvalPatchBezierTriangle(ivec3 patchParam, vec2 UV, + OsdPerPatchVertexBezier cv[15], + out vec3 P, out vec3 dPu, out vec3 dPv, + out vec3 N, out vec3 dNu, out vec3 dNv) + + +Gregory Triangle Patch +********************** + +OsdComputePerPatchVertexGregoryBasis() can be used for the quartic triangular Gregory patches (although no basis conversion involved for the Gregory triangle patches) and the resulting vertices are stored in a OsdPerPatchVertexGreogryBasis struct. + +.. code:: glsl + + void + OsdComputePerPatchVertexGregoryBasis( + ivec3 patchParam, int ID, vec3 cv, out OsdPerPatchVertexGregoryBasis result) + +The tessellation evaluation shader takes an array of OsdPerPatchVertexGregoryBasis struct, +and then evaluates the patch using the OsdEvalPatchGregoryTriangle() function. + +.. code:: glsl + + void + OsdEvalPatchGregoryTriangle(ivec3 patchParam, vec2 UV, vec3 cv[18], + out vec3 P, out vec3 dPu, out vec3 dPv, + out vec3 N, out vec3 dNu, out vec3 dNv) + + Legacy Gregory Patch (2.x compatibility) **************************************** @@ -190,12 +239,6 @@ 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. @@ -212,31 +255,63 @@ as separate levels for the two segments of the edge split at the middle. .. image:: images/osd_shader_transition.png -Then the tessellation evaluation shader takes gl_TessCoord and those two values, and remaps -gl_TessCoord using OsdGetTessParameterization() to ensure the parameters are consistent +Tessellation levels at each tessellated vertex +********************************************** + +The tessellation evaluation shader takes gl_TessCoord and those two values, and remaps +gl_TessCoord using OsdGetTessParameterization() or OsdGetTessLevelParameterizationTriangle() to ensure the parameters are consistent across adjacent patches. +.. code:: glsl + + vec2 OsdGetTessParameterization(vec2 uv, vec4 tessOuterLo, vec4 tessOuterHi); + +.. code:: glsl + + vec2 OsdGetTessParameterizationTriangle(vec3 uvw, vec4 tessOuterLo, vec4 tessOuterHi); + .. image:: images/osd_shader_param_remap.png -.. code:: glsl +Tessellation levels computed at each patch +****************************************** - vec2 OsdGetTessParameterization(vec2 uv, vec4 tessOuterLo, vec4 tessOuterHi) - -These tessellation levels can be computed by OsdGetTessLevelsAdaptiveLimitPoints() -in the tessellation control shader. Note that this function requires all 16 bezier control +These tessellation levels can be computed the corresponding method in the tesselation control shader. Note that these functions potentially requires all bezier control points, you need to call barrier() to ensure the conversion is done for all invocations. See osd/glslPatchBSpline.glsl for more details. +Uniform +~~~~~~~ + .. code:: glsl - void OsdGetTessLevelsAdaptiveLimitPoints(OsdPerPatchVertexBezier cpBezier[16], - ivec3 patchParam, - out vec4 tessLevelOuter, out vec2 tessLevelInner, - out vec4 tessOuterLo, out vec4 tessOuterHi) + void + OsdGetTessLevelsUniform(ivec3 patchParam, + out vec4 tessLevelOuter, out vec2 tessLevelInner, + out vec4 tessOuterLo, out vec4 tessOuterHi) -.. container:: notebox +.. code:: glsl - **Release Notes (3.0.0)** + void + OsdGetTessLevelsUniformTriangle(ivec3 patchParam, + out vec4 tessLevelOuter, out vec2 tessLevelInner, + out vec4 tessOuterLo, out vec4 tessOuterHi) - * Currently OsdGetTessParameterization doesn't support fraction spacing. - It will be fixed in a future release. + +Screenspace +~~~~~~~~~~~ + +.. code:: glsl + + void OsdEvalPatchBezierTessLevels( + OsdPerPatchVertexBezier cpBezier[16], + ivec3 patchParam, + out vec4 tessLevelOuter, out vec2 tessLevelInner, + out vec4 tessOuterLo, out vec4 tessOuterHi); + +.. code:: glsl + + void OsdEvalPatchBezierTriangleTessLevels( + vec3 cv[15], + ivec3 patchParam, + out vec4 tessLevelOuter, out vec2 tessLevelInner, + out vec4 tessOuterLo, out vec4 tessOuterHi);