HLSL Editor
The HLSL editor allows you to create custom video
generators, effects, audio visualizations and transitions by coding the GPU in HLSL.
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,p2,p3,p4,p5 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);
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,p2,p3,p4,p5 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);
float2 center : packoffset(c1.z);
float dpi : packoffset(c2.x);
};
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);
float2 center : packoffset(c1.z);
float dpi : packoffset(c2.x);
};
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).