Channels
Channels are used to declare the data that the vertex shader is going to get from the vertex buffer.
Channels must be defined within a shader{...}
block via the following syntax:
channel (type) (usage_dst) = (usage_src) [ modifier ];
Data types
Data types that follow the channel
keyword differ from those native DSHL types described in Data types and variables.
These types are considered convertable, meaning that they are always casted to native HLSL data types when piped to
variables in hlsl{...}
blocks.
This cast always happens to a 4-component vector of some basic scalar type, even if the source DSHL type is not a 4-component type.
For example, float2
type with (x, y)
components is casted to 4-component float vector via the rule (x, y, 0, 1)
.
The list below describes these convertable types as well as their casts to 4D vectors.
float1
– 1D float(x, 0, 0, 1)
float2
– 2D float(x, y, 0, 1)
float3
– 3D float(x, y, z, 1)
float4
– 4D float(x, y, z, w)
short2
– 2D signed short(x, y, 0, 1)
short4
– 4D signed short(x, y, z, w)
ubyte4
– 4D uint8_t(x, y, z, w)
color8
– 4-byte(R, G, B, A)
color in[0..1]
rangehalf2
– 2D 16-bit float(x, y, 0, 1)
half4
– 4D 16-bit float(x, y, z, w)
short2n
– 2D signed short normalized(x/32767.0, y/32767.0 , 0, 1)
short4n
– 4D signed short normalized(x/32767.0, y/32767.0 , z/32767.0, w/32767.0)
ushort2n
– 2D unsigned short normalized(x/32767.0, y/32767.0 , 0, 1)
ushort4n
– 4D unsigned short normalized(x/32767.0, y/32767.0 , z/32767.0, w/32767.0)
udec3
– 3D unsigned 10-bit float(x, y, z, 1)
dec3n
– 3D signed 10-bit float normalized(x/511.0, y/511.0, z/511.0, 1)
Data usages
Shader resource builder needs to know which data to extract from the given mesh that will be sent to your shader. This is why you need to specify channel’s usage.
pos
– positionnorm
– normalvcol
– vertex colortc
– texture coordinateslightmap
– lightmap, deprecated (legacy from the times when lightmaps were used)extra
– extra, can be used only asusage_src
(used for providing additional info for vertices)
Usually, usage_src
and usage_dst
match. But sometimes, e.g. when the extra
channel is used as usage_src
,
you must remap it to other intended usage_dst
.
Data modifiers
Data modifiers might be useful in some cases where the data from the channel should be rescaled or multiplied by some constant.
signed_pack
– converts data from[0..1]
range to[-1..1]
rangeunsigned_pack
– converts data from[-1..1]
range to[0..1]
rangebounding_pack
– rescales data from[min..max]
to[0..1]
ifusage_dst
is unsigned or[-1..1]
if it is signedmul_1k
– multiplies data by1024
mul_2k
– multiplies data by2048
mul_4k
– multiplies data by4096
mul_8k
– multiplies data by8192
mul_16k
– multiplies data by16384
mul_32767
– multiplies data by32767
and clamps it to[-32767..32767]
range
Here is a simple usage example:
shader some_shader
{
/*
Here we declare channels for the vertex shader, which
will be used by the shader compiler to generate appropriate
vertex shader declaration for this particular shader.
*/
channel float3 pos=pos; // vertex position
channel color8 vcol=vcol; // vertex color
channel float3 tc[0] = tc[0]; // vertex texture coordinate
channel float3 tc[1] = tc[1]; // another vertex texture coordinate
hlsl(vs) {
/*
This VsInput struct declares vertex information in HLSL-style.
Note that for each DSHL channel declared above, there should be a corresponding
HLSL semantic matching the declared channel.
*/
struct VsInput
{
float4 pos : POSITION; // vertex position
float4 color : COLOR0; // vertex color
float3 texcoord : TEXCOORD0; // vertex texture coordinate
float3 another_texcoord : TEXCOORD1; // another vertex texture coordinate
};
}
hlsl(vs) {
VsOutput some_vs(VsInput input)
{
// ...
}
}
}