HLSL Editor
The HLSL editor allows you to create custom video
generators, effects, audio visualizations and transitions by coding the GPU in HLSL.
You can include "glsl.hlsli" to your code which automatically includes the Direct2D helpers and also some glsl convertors.
To create an effect, the input takes 1 texture and 5 optional parameters, along with center/dpi, so your code for a simple invert would be that one:
// Turbo Play passes p1-p8 parameters to this effect
cbuffer constants : register(b0)
{
float progress : packoffset(c0.x);
float p1 : packoffset(c0.y);
float p2 : packoffset(c0.z);
float p3 : packoffset(c0.w);
float p4 : packoffset(c1.x);
float p5 : packoffset(c1.y);
float p6 : packoffset(c1.y);
float p7 : packoffset(c1.y);
float p8 : packoffset(c1.y);
float2 center : packoffset(c1.z);
float dpi : packoffset(c2.x);
};
Texture2D InputTexture0 : register(t0);
SamplerState InputSampler0 : register(s0);
float4 main(
float4 pos : SV_POSITION,
float4 posScene : SCENE_POSITION,
float4 uv0 : TEXCOORD0
) : SV_Target
{
float4 v1 = InputTexture0.Sample(InputSampler0,uv0.xy);
float4 v2 = 1 - v1; // simple invert
v2.a = 1.0f;
return v2;
}
To create a transition, you have two inputs, so the code to create a simple cross fade would be:
// Turbo Play passes progress 0 to 1 to this transition
// Turbo Play passes p1-p8 parameters to this effect
// If you want to compile with "d2d1effecthelpers.hlsli" and the helpers, you must compile using FXC
cbuffer constants : register(b0)
{
float progress : packoffset(c0.x);
float p1 : packoffset(c0.y);
float p2 : packoffset(c0.z);
float p3 : packoffset(c0.w);
float p4 : packoffset(c1.x);
float p5 : packoffset(c1.y);
float p6 : packoffset(c1.z);
float p7 : packoffset(c1.w);
float p8 : packoffset(c2.x);
float2 center : packoffset(c2.y);
float dpi : packoffset(c2.w);
};
Texture2D InputTexture0 : register(t0);
Texture2D InputTexture1 : register(t1);
SamplerState InputSampler0 : register(s0);
SamplerState InputSampler1 : register(s1);
float4 main(
float4 pos : SV_POSITION,
float4 posScene : SCENE_POSITION,
float4 uv0 : TEXCOORD0
) : SV_Target
{
float4 v1 = InputTexture0.Sample(InputSampler0,uv0.xy);
float4 v2 = InputTexture1.Sample(InputSampler1,uv0.xy);
float4 v3 = lerp(v1,v2,progress); // simple cross fade
return v3;
}
Here is the Swirl used by Turbo Play:
cbuffer constants : register(b0)
{
float progress : packoffset(c0.x);
float p1 : packoffset(c0.y);
float p2 : packoffset(c0.z);
float p3 : packoffset(c0.w);
float p4 : packoffset(c1.x);
float p5 : packoffset(c1.y);
float p6 : packoffset(c1.z);
float p7 : packoffset(c1.w);
float p8 : packoffset(c2.x);
float2 center : packoffset(c2.y);
float dpi : packoffset(c2.w);
};
Texture2D InputTexture0 : register(t0);
Texture2D InputTexture1 : register(t1);
SamplerState InputSampler0 : register(s0);
SamplerState InputSampler1 : register(s1);
float2 MoveBy(float2 UV, float2 MV, float2 j)
{
float2 sampleLocation =
UV
+ float2(j.x * (center.x * 2),
j.y * (center.y * 2)) *
MV; // Multiplier that converts pixel offset to sample position offset.
return sampleLocation;
}
float4 Swirl(float2 UV, float2 MV)
{
float Radius = p3;
float T = progress;
UV = MoveBy(UV, MV, float2(-p1, -p2));
float Dist = length(UV);
if (Dist < Radius)
{
float Percent = (Radius - Dist) / Radius;
float A = (T <= 0.5) ? lerp(0.0, 1.0, T / 0.5) : lerp(1.0, 0.0, (T - 0.5) / 0.5);
float Theta = Percent * Percent * A * 8.0 * 3.14159;
float S = sin(Theta);
float C = cos(Theta);
UV = float2(dot(UV, float2(C, -S)), dot(UV, float2(S, C)));
}
UV = MoveBy(UV, MV, float2(+p1, +p2));
float4 C0 = InputTexture0.Sample(InputSampler0, UV);
float4 C1 = InputTexture1.Sample(InputSampler1, UV);
return lerp(C0, C1, T);
}
float4 main(
float4 pos : SV_POSITION,
float4 posScene : SCENE_POSITION,
float4 uv0 : TEXCOORD0
) : SV_Target
{
return Swirl(uv0.xy, uv0.zw);
}
In Microsoft MSDN
here you can find more on how to write a Direct2D pixel shader.
You can either compile HLSL with the internal compiler,or, if you want to use macros,includes etc, you can use FXC.exe (from the Windows SDK).