Programming
Fundamentals
Setting Up Development Environment
UnigineScript
High-Level Systems
C++
C#
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
Rendering-Related 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

    Tessellation Output Primitive Type

    SET_TOPOLOGY_PRIMITIVE( VALUE)

    Defines the output primitive type for the tessellator.

    Arguments

      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:

      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:

      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:

      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:

      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:

      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