UUSL Semantics
Redefined UUSL semantics allows you to create unified input\output shader structures for both graphics APIs.
Vertex Shader Semantics
Vertex shader semantics contain necessary input and output data for shader. You should initialize variables first and then use them.
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
INIT_ATTRIBUTE(TYPE,NUM,SEMANTICS) | in TYPE s_attribute_ ## NUM; | TYPE attribute_ ## NUM : SEMANTICS; | Adds a semantic to a vertex shader variable. |
INIT_OUT(TYPE,NUM) | out TYPE s_texcoord_ ## NUM; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds an output data semantic. |
INIT_POSITION | - | float4 position : SV_POSITION; | Adds a position system-value semantic. |
INIT_INSTANCE | - | uint instance : SV_INSTANCEID; | Adds a per-instance identifier system-value semantic. |
Here is an example of vertex shader input and output structures:
// Input vertex data
STRUCT(VERTEX_IN)
INIT_ATTRIBUTE(float4,0,POSITION) // Vertex position
INIT_ATTRIBUTE(float4,1,TEXCOORD0) // Vertex texcoord (uv)
INIT_ATTRIBUTE(float4,2,TEXCOORD1) // Vertex basis tangent
INIT_ATTRIBUTE(float4,3,TEXCOORD2) // Vertex color
END
// Our output vertex data
STRUCT(VERTEX_OUT)
INIT_POSITION // Out projected position
INIT_OUT(float4,0) // Texcoord (uv)
INIT_OUT(float3,1) // Vertex direction
END
Use the following pre-defined variables to use the input\output vertex shader semantics:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
IN_INSTANCE | gl_InstanceID | input.instance | An input per-instance identifier system-value variable. |
IN_ATTRIBUTE(NUM) | s_attribute_ ## NUM | input.attribute_ ## NUM | An input shader variable. |
OUT_DATA(NUM) | s_texcoord_ ## NUM | output.data_ ## NUM | An output texture coordinates variable. |
OUT_POSITION | gl_Position | output.position | An output position system-value variable. |
Fragment Shader Semantics
Fragment shader semantics contain necessary input and output data for shader. You should initialize variables first and then use them.
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
INIT_IN(TYPE,NUM) | in TYPE s_texcoord_ ## NUM; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Adds an input texture coordinates semantic. |
INIT_COLOR(TYPE) | out TYPE s_frag_color; | TYPE color : SV_TARGET; | Add an output diffuse or specular color semantic (single RT). |
INIT_DEPTH | - | float depth : SV_DEPTH; | Add an output depth system-value semantic. |
INIT_MRT(TYPE,NUM) | out TYPE s_frag_data_ ## NUM; | TYPE color_ ## NUM : SV_TARGET ## NUM; | Add an output color system-value semantic (some RTs). |
INIT_FRONTFACE | --- | bool frontface : SV_ISFRONTFACE; | Adds an input semantic indicates primitive face (frontface or not). |
To use the variables in the code, use the following variables:
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
IN_POSITION | gl_FragCoord | input.position | An input position value. |
IN_DATA(NUM) | s_texcoord_ ## NUM | input.data_ ## NUM | An input texture coordinates variable. |
IN_FRONTFACE | !gl_FrontFacing | input.frontface | Floating-point scalar that indicates a back-facing primitive. A negative value faces backwards, while a positive value faces the camera. |
OUT_COLOR | s_frag_color | output.color | An output color value (single RT). |
OUT_DEPTH | gl_FragDepth | output.depth | An output depth value. |
OUT_MRT(NUM) | out TYPE s_frag_data_ ## NUM; | output.color_ ## NUM | An output color value for MRTs. |
Here is a simple example of using the variable in the main function of the shader:
MAIN_BEGIN(FRAGMENT_OUT,FRAGMENT_IN)
float4 texcoord = IN_DATA(0);
/* ... other code ... */
END
Geometry Shader Semantics
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
INIT_GEOM_IN(TYPE,NUM) | in TYPE s_geom_texcoord_ ## NUM[]; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Add an input texture coordinates semantic for the geometry-shader stage. |
INIT_GEOM_OUT(TYPE,NUM) | out TYPE s_geom_texcoord_ ## NUM; | TYPE data_ ## NUM : TEXCOORD ## NUM; | Add an output texture coordinates semantic for the geometry-shader stage. |
UUSL | OpenGL | Direct3D | Description |
---|---|---|---|
IN_GEOM_DATA(NUM,INDEX) | s_geom_texcoord_ ## NUM ## [INDEX] | input[INDEX].data_ ## NUM | An input texture coordinates value. |
IN_GEOM_POSITION(INDEX) | gl_in[INDEX].gl_Position | input[INDEX].position | An input position value. |
OUT_GEOM_DATA(NUM) | s_geom_texcoord_ ## NUM | output.data_ ## NUM | An output texture coordinates value. |
TRIANGLE_IN | triangles | triangle | Input primitive type: triangle list or triangle strip. |
TRIANGLE_OUT | triangle_strip | TriangleStream | Output primitive type: a sequence of triangle primitives |
LINE_IN | lines | line | Input primitive type: line. |
LINE_OUT | line_strip | LineStream | Output primitive type: a sequence of line primitives |
Unified Shader Semantics
Unified shader semantics allows you to create single structure for both vertex and fragment shaders. It facilities the work with vertex and fragment shaders input/output structure by using single structure for both shaders: this structure will be output for vertex shader and input for fragment shader respectively.
You can write vertex and fragment shader in a single file with .shader extension. In this case, in the material you should specify this .shader file for both shader stages.
<materials version="2.0" editable="0">
<material name="mesh_base" editable="0" parameters_prefix="m" defines="VERTEX_ATTRIBUTE_GEOMETRY">
<!-- ... -->
<shader pass="auxiliary" object="mesh_static"
auxiliary="1"
defines="BASE_AUXILIARY"
vertex="core/shaders/mesh/auxiliary/auxiliary.shader"
fragment="core/shaders/mesh/auxiliary/auxiliary.shader"/>
<!-- ... -->
</material>
</materials>
UUSL | VERTEX | FRAGMENT | Description |
---|---|---|---|
INIT_DATA(TYPE,NUM,NAME) | INIT_OUT(TYPE,NUM) \ #define NAME GET_DATA(NUM) | INIT_IN(TYPE,NUM) \ #define NAME GET_DATA(NUM) | Data initialization. |
GET_DATA(V) | OUT_DATA(V) | IN_DATA(V) | Helper for getting/setting data by using data name. |
IF statement
There is also a IF_DATA(NAME) statement to execute an operation if the data is not null.
UUSL | VERTEX | FRAGMENT | Description |
---|---|---|---|
IF_DATA(NAME) | #ifdef NAME | #ifdef NAME | Opening IF conditional statement. |
ENDIF | #endif | #endif | Closing IF conditional statement. |
Here is a code snippet of shader, where shader's IF statement is used.
//input struct
STRUCT(FRAGMENT_IN)
/* ... */
#ifdef ALPHA_FADE && USE_ALPHA_FADE
INIT_DATA(float,1,DATA_ALPHA_FADE)
#endif
/* ... */
END
//main functions
MAIN_SHADOW_BEGIN(FRAGMENT_OUT,FRAGMENT_IN)
/* ... */
IF_DATA(DATA_ALPHA_FADE)
//code to execute if the data is not null
texture2DAlphaFadeDiscard(DATA_ALPHA_FADE,IN_POSITION.xy);
ENDIF
/* ... */
MAIN_SHADOW_END