Programming
Fundamentials
Setting Up Development Environment
UnigineScript
High-Level Systems
C++
C#
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Core Library
Containers
Engine Classes
Node-Related Classes
Rendering-Related Classes
Physics-Related Classes
Bounds-Related Classes
GUI-Related Classes
Controls-Related Classes
Pathfinding-Related Classes
Utility Classes

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.

Prior Knowledge
This article assumes you have prior knowledge of the tessellation. Also, read the following topics before proceeding:

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:

OpenGL
#define DOMAIN_PATCH quads
Direct3D
#define DOMAIN_PATCH [domain("quad")]
#define DOMAIN_PATCH_VERTICES 4

Otherwise, the engine will use triangle patches:

OpenGL
#define DOMAIN_PATCH triangles
Direct3D
#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)

Specifies the partitioning scheme the tessellator should use for dividing patches.

Arguments

  • 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

      OpenGL
      fractional_odd_spacing
      Direct3D
      [partitioning("fractional_odd")]
    • PARTITIONING_FRAC_EVEN - the tessellation factor is rounded to the next even integer within the [min;max] range.

      Equivalents

      OpenGL
      fractional_even_spacing
      Direct3D
      [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

      Direct3D
      [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

      Direct3D
      [partitioning("Integer")]

Tessellation Output Primitive Type

SET_TOPOLOGY_PRIMITIVE (VALUE)

Defines the output primitive type for the tessellator.

Arguments

  • 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

      OpenGL
      cw
      Direct3D
      [outputtopology("triangle_cw")]
    • TRIANGLE_CCW triangle_cw means counter-clockwise-wound triangles (vertices rotate counter-clockwise around the triangle's center).

      Equivalents

      OpenGL
      ccw
      Direct3D
      [outputtopology("triangle_ccw")]

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:

UUSLOpenGLDirect3DDescription
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_OUTout 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:

UUSL
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:

UUSLOpenGLDirect3DDescription
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_ ## NUMAn output texture coordinates variable.
IN_CONTROL_DATA(NUM,ID)s_texcoord_ ## NUM ## [ ## ID ## ]input[ ## ID ## ].data_ ## NUMAn input texture coordinates variable.
OUT_CONTROL_POSITIONgl_out[gl_InvocationID].gl_Positionoutput.positionAn output position system-value variable.
IN_CONTROL_POSITION(ID)gl_in[ ## ID ## ].gl_Positioninput[ ## ID ## ].positionAn input position variable.
CONTROL_POINT_IDgl_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:

UUSLOpenGLDirect3DDescription
OUT_PATCH_INSIDE(INDEX)inside[INDEX]output.inside[INDEX]Defines the tessellation amount within a patch surface.
OUT_PATCH_INSIDEinsideoutput.insideDefines the tessellation amount within a patch surface.

Evaluation (Domain) Shader Semantics

Initialization semantics:

UUSLOpenGLDirect3DDescription
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:

UUSL
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:

UUSLOpenGLDirect3DDescription
OUT_EVALUATE_DATA(NUM)s_texcoord_ ## NUMoutput.data_ ## NUMAn output texture coordinates variable.
IN_EVALUATE_PATCH_DATA(NUM,ID)s_tess_texcoord_ ## NUM ## [ ## ID ## ]input[ ## ID ## ].data_ ## NUMAn input patch data semantic.
OUT_EVALUATE_POSITION(NUM,ID)gl_Positionoutput.positionAn output position system-value variable.
IN_EVALUATE_PATCH_POSITION(ID)gl_in[ ## ID ## ].gl_Positioninput[ ## ID ## ].positionAn input patch data position semantic value.
DOMAIN_LOCATIONgl_TessCoordpatch_constant.coordsContains 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:

UUSL
MAIN_PATCH_CONSTANT_BEGIN(CONTROL_IN)

	<your code here>

END_PATCH_CONSTANT

//end
Warning
You should add a new line (press Enter) after closing the instruction.

This code is equivalent to:

OpenGL
//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>

}
Direct3D
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:

UUSL
MAIN_CONTROL_BEGIN(CONTROL_OUT, CONTROL_IN)

	<your code here>

END_CONTROL

//end
Warning
You should add a new line (press Enter) after closing the instruction.

This code is equivalent to:

OpenGL
#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
Direct3D
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:

UUSL
MAIN_EVALUATE_BEGIN(EVALUATE_OUT, EVALUTATE_IN)

	<your code here>

END_EVALUATE

//end
Warning
You should add a new line (press Enter) after closing the instruction.

This code is equivalent to:

OpenGL
layout(DOMAIN_PATCH,CONTROL_PARTITIONING_TYPE,CONTROL_TOPOLOGY_PRIMITIVE_TYPE) in;
void main() { 

	<your code here>

}
Direct3D
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; }
//
Last update: 2017-07-03