UUSL Tessellation
Since UUSL supports tessellation, there are additional functions, semantics and parameters for tessellation shaders.
Tessellation requires new shader types: hull (also known as control) shader and evaluation (also known as domain). Hull shaders have a *.hull extension, evaluation shaders have a *.eval extension.
The essential thing of the tessellation is SET_QUAD_DOMAIN define. It defines the type of tessellator input: if you use it the tessellator will have quads input, otherwise triangles.
Tessellation Attributes
You should specify the tessellation attributes in both tessellation shaders (hull and evaluation). These attributes defines the type of patches, and primitive topologies.
Domain Patch Type
If you have used the SET_QUAD_DOMAIN define, the engine will use the quad patches:
#define DOMAIN_PATCH quads
#define DOMAIN_PATCH [domain("quad")]
#define DOMAIN_PATCH_VERTICES 4
Otherwise, the engine will use triangle patches:
#define DOMAIN_PATCH triangles
#define DOMAIN_PATCH [domain("tri")]
#define DOMAIN_PATCH_VERTICES 3
Partitioning Scheme
Partitioning scheme of the tessellator is defined by the SET_PARTITIONING function:
SET_PARTITIONING(value VALUE)
Specifies the partitioning scheme the tessellator should use for dividing patches.Arguments
- value VALUE - The partitioning attribute. The value can be one of the following:
- PARTITIONING_FRAC_ODD - the tessellation factor is rounded to the next odd integer within the [min;max] range.
Equivalents
fractional_odd_spacing
[partitioning("fractional_odd")]
- PARTITIONING_FRAC_EVEN - the tessellation factor is rounded to the next even integer within the [min;max] range.
Equivalents
fractional_even_spacing
[partitioning("fractional_even")]
- PARTITIONING_POW2 - the tessellation is rounded to the next greatest power of 2, yielding the effective range [1, 2, 4, 8, 16, 32, 64].
Equivalents
[partitioning("pow2")]
- PARTITIONING_INTEGER - the tessellation factor is always rounded up to the nearest integral value, in the range within the [min;max] range.
Equivalents
[partitioning("Integer")]
- PARTITIONING_FRAC_ODD - the tessellation factor is rounded to the next odd integer within the [min;max] range.
Tessellation Output Primitive Type
SET_TOPOLOGY_PRIMITIVE(value VALUE)
Defines the output primitive type for the tessellator.Arguments
- value VALUE - The output primitive type attribute. The value can be one of the following:
- TRIANGLE_CW means clockwise-wound triangles (vertices rotate clockwise around the triangle's center).
Equivalents
cw
[outputtopology("triangle_cw")]
- TRIANGLE_CCW triangle_cw means counter-clockwise-wound triangles (vertices rotate counter-clockwise around the triangle's center).
Equivalents
ccw
[outputtopology("triangle_ccw")]
- TRIANGLE_CW means clockwise-wound triangles (vertices rotate clockwise around the triangle's center).
Tessellation Semantics
Redefined UUSL semantics allows you to create unified input\output shader structures for both graphics APIs.
Hull (Control) Shader Semantics
Initialization semantics for hull (control) shader:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
INIT_CONTROL_IN(TYPE,NUM) | in TYPE s_texcoord_ ## NUM ## []; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds (initializes) a control (hull) shader input semantic. |
INIT_CONTROL_OUT | out TYPE s_tess_texcoord_ ## NUM ## []; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds (initializes) a control shader output data semantic. |
Here is a usage example of hull shader input and output structure:
STRUCT(CONTROL_IN)
INIT_POSITION
INIT_CONTROL_IN(float4,0)
INIT_CONTROL_IN(float3,1)
END
STRUCT(CONTROL_OUT)
INIT_POSITION
INIT_CONTROL_OUT(float4,0)
END
// end of structures
Use the following pre-defined variables to use the input\output control shader semantics:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
OUT_PATCH_EDGE(INDEX) | edges[INDEX] | output.edges[INDEX] | Defines the tessellation amount on each edge of a patch. |
OUT_CONTROL_DATA(NUM) | s_tess_texcoord_ ## NUM ## [gl_InvocationID] | output.data_ ## NUM | An output texture coordinates variable. |
IN_CONTROL_DATA(NUM,ID) | s_texcoord_ ## NUM ## [ ## ID ## ] | input[ ## ID ## ].data_ ## NUM | An input texture coordinates variable. |
OUT_CONTROL_POSITION | gl_out[gl_InvocationID].gl_Position | output.position | An output position system-value variable. |
IN_CONTROL_POSITION(ID) | gl_in[ ## ID ## ].gl_Position | input[ ## ID ## ].position | An input position variable. |
CONTROL_POINT_ID | gl_InvocationID | --- | Contains the coordinate of the vertex within the current patch. |
If you have used the SET_QUAD_DOMAIN define, you should specify the index for this output semantic:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
OUT_PATCH_INSIDE(INDEX) | inside[INDEX] | output.inside[INDEX] | Defines the tessellation amount within a patch surface. |
OUT_PATCH_INSIDE | inside | output.inside | Defines the tessellation amount within a patch surface. |
Evaluation (Domain) Shader Semantics
Initialization semantics:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
INIT_EVALUATE_IN(TYPE,NUM) | in TYPE s_tess_texcoord_ ## NUM ## []; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds an input data semantic. |
INIT_EVALUATE_OUT(TYPE,NUM) | out TYPE s_texcoord_ ## NUM; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds an output data semantic. |
Here is a usage example of evaluation shader input and output structure:
STRUCT(EVALUATE_IN)
INIT_POSITION
INIT_EVALUATE_IN(float4,0)
END
STRUCT(EVALUATE_OUT)
INIT_POSITION
INIT_EVALUATE_OUT(float2,0)
INIT_EVALUATE_OUT(float3,1)
INIT_EVALUATE_OUT(float3,2)
INIT_EVALUATE_OUT(float3,3)
INIT_EVALUATE_OUT(float,4)
INIT_CUSTOM_DEPTH_VERTEX_OUT
END
// end of structures
Use the following pre-defined variables to use the input\output control shader semantics:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
OUT_EVALUATE_DATA(NUM) | s_texcoord_ ## NUM | output.data_ ## NUM | An output texture coordinates variable. |
IN_EVALUATE_PATCH_DATA(NUM,ID) | s_tess_texcoord_ ## NUM ## [ ## ID ## ] | input[ ## ID ## ].data_ ## NUM | An input patch data semantic. |
OUT_EVALUATE_POSITION(NUM,ID) | gl_Position | output.position | An output position system-value variable. |
IN_EVALUATE_PATCH_POSITION(ID) | gl_in[ ## ID ## ].gl_Position | input[ ## ID ## ].position | An input patch data position semantic value. |
DOMAIN_LOCATION | gl_TessCoord | patch_constant.coords | Contains the coordinate of the vertex within the current patch. Defines the location on the hull of the current domain point being evaluated. |
Tessellation Main Functions
Control Shader Main Function
Hull shader requires the main shader function and patch constant function.
Patch Constant Function
To start and end the main function of the control patch constant data, use the following instructions:
MAIN_PATCH_CONSTANT_BEGIN(CONTROL_IN)
<your code here>
END_PATCH_CONSTANT
//end
This code is equivalent to:
//if SET_QUAD_DOMAIN defined
void patch_constant(out float edges[4], out float[2] inside) {
<your code here>
}
//else
void patch_constant(out float edges[3], out float inside) {
<your code here>
}
CONTROL_CONSTANT_OUT patch_constant(InputPatch<CONTROL_IN,DOMAIN_PATCH_VERTICES> input) {
CONTROL_CONSTANT_OUT output = (CONTROL_CONSTANT_OUT)0;
<your code here>
return output; }
//
Hull Shader Function
To start and end the main function of the hull shader, use the following instructions:
MAIN_CONTROL_BEGIN(CONTROL_OUT, CONTROL_IN)
<your code here>
END_CONTROL
//end
This code is equivalent to:
#ifdef SET_QUAD_DOMAIN
layout(vertices = 4) out;
void main() {
if(gl_InvocationID == 0) {
float edges_factor[4];
float inside_factor[2];
patch_constant(edges_factor,inside_factor);
gl_TessLevelOuter[0] = edges_factor[0];
gl_TessLevelOuter[1] = edges_factor[1];
gl_TessLevelOuter[2] = edges_factor[2];
gl_TessLevelOuter[3] = edges_factor[3];
gl_TessLevelInner[0] = inside_factor[0];
gl_TessLevelInner[1] = inside_factor[1];
}
<your code here>
}
#else
layout(vertices = 3) out;
void main() {
if(gl_InvocationID == 0) {
float edges_factor[3];
float inside_factor;
patch_constant(edges_factor,inside_factor);
gl_TessLevelOuter[0] = edges_factor[0];
gl_TessLevelOuter[1] = edges_factor[1];
gl_TessLevelOuter[2] = edges_factor[2];
gl_TessLevelInner[0] = inside_factor;
}
<your code here>
}
#endif
DOMAIN_PATCH
[maxtessfactor(64.0f)]
[outputcontrolpoints(DOMAIN_PATCH_VERTICES)]
[patchconstantfunc("patch_constant")]
CONTROL_PARTITIONING_TYPE
CONTROL_TOPOLOGY_PRIMITIVE_TYPE
CONTROL_OUT main(InputPatch<CONTROL_IN,DOMAIN_PATCH_VERTICES> input,uint CONTROL_POINT_ID : SV_OUTPUTCONTROLPOINTID) {
CONTROL_OUT output;
<your code here>
return output; }
Evaluation Shader Main Function
To start and end the main function of the evaluation shader, use the following instructions:
MAIN_EVALUATE_BEGIN(EVALUATE_OUT, EVALUTATE_IN)
<your code here>
END_EVALUATE
//end
This code is equivalent to:
layout(DOMAIN_PATCH,CONTROL_PARTITIONING_TYPE,CONTROL_TOPOLOGY_PRIMITIVE_TYPE) in;
void main() {
<your code here>
}
DOMAIN_PATCH
EVALUATE_OUT main(EVALUATE_CONSTANT_IN patch_constant,const OutputPatch<EVALUATE_IN,DOMAIN_PATCH_VERTICES> input) {
EVALUATE_OUT output;
<your code here>
return output; }
//