Skip to content

Instantly share code, notes, and snippets.

@ylmrx
Last active July 17, 2023 19:26
Show Gist options
  • Save ylmrx/5f301d242552afa682fe64d14b299631 to your computer and use it in GitHub Desktop.
Save ylmrx/5f301d242552afa682fe64d14b299631 to your computer and use it in GitHub Desktop.
// https://www.shadertoy.com/view/XlBcRV
//RWTexture2D<float4> outputTexture : register(u0);
Texture2D<float4> inputTexture : register(t0);
sampler texSampler : register(s0);
cbuffer ParamConstants : register(b0)
{
float4 Fill;
float4 Background;
}
cbuffer TimeConstants : register(b1)
{
float globalTime;
float time;
float runTime;
float beatTime;
}
cbuffer Resolution : register(b1)
{
float TargetWidth;
float TargetHeight;
}
struct vsOutput
{
float4 position : SV_POSITION;
float2 texCoord : TEXCOORD;
};
#define mod(x,y) (x-y*floor(x/y))
float intensity(float2 loc, float time) {
// float i0 = dot(textureLod(iChannel0, loc, lod).rgb, float3(1.0));
// float i1 = dot(textureLod(iChannel1, loc, lod).rgb, float3(1.0));
float i0 = dot(inputTexture.Sample(texSampler, loc).rgb, float3(1.));
float i1 = dot(inputTexture.Sample(texSampler, loc).rgb, float3(1.));
return lerp(i0, i1, time);
}
float4 psMain(vsOutput psInput) : SV_TARGET
{
float2 uv = psInput.texCoord;
float4 ic = inputTexture.Sample(texSampler, uv);
float aspect = TargetWidth/TargetHeight;
uv -=.5;
uv.x *= aspect;
// lucas-kanade optical flow
// https://en.wikipedia.org/wiki/Lucas%E2%80%93Kanade_method
float2x2 AtA = float2x2(0.0, 0.0, 0.0, 0.0);
float2 Atb = float2(0.0, 0.0);
float xstart = uv.x;
float2 px_step = 4. / uv.xy;
for (int i = 0; i < 7; ++i) {
uv.x = xstart;
for (int j = 0; j < 7; ++j) {
float I = intensity(uv, 0.0);
float It = I - intensity(uv, 1.0);
float Ix = intensity(uv + float2(1.0, 0.0) * px_step, 0.0) - I;
float Iy = intensity(uv + float2(0.0, 1.0) * px_step, 0.0) - I;
AtA += float2x2(Ix * Ix, Ix * Iy, Ix * Iy, Iy * Iy);
Atb -= float2(It * Ix, It * Iy);
uv.x += px_step.x;
}
uv.y += px_step.y;
}
float2x2 AtAinv = float2x2(AtA[0][0], -AtA[0][1], -AtA[1][0], AtA[1][1]) /
(AtA[0][0] * AtA[1][1] - AtA[1][0] * AtA[0][1]);
float2 flow = mul(AtAinv, Atb);
return float4(0.5 + .1 * flow.r,0.0,1.0);
// return float4(1,1,1,1);
}
//RWTexture2D<float4> outputTexture : register(u0);
Texture2D<float4> inputTextureA : register(t0);
Texture2D<float4> inputTextureB : register(t1);
sampler texSampler : register(s0);
cbuffer ParamConstants : register(b0)
{
float4 Fill;
float4 Background;
}
cbuffer TimeConstants : register(b1)
{
float globalTime;
float time;
float runTime;
float beatTime;
}
cbuffer Resolution : register(b1)
{
float TargetWidth;
float TargetHeight;
}
struct vsOutput
{
float4 position : SV_POSITION;
float2 texCoord : TEXCOORD;
};
#define mod(x,y) (x-y*floor(x/y))
float intensity(float2 loc, float time) {
// float i0 = dot(textureLod(iChannel0, loc, lod).rgb, float3(1.0));
// float i1 = dot(textureLod(iChannel1, loc, lod).rgb, float3(1.0));
float i0 = dot(inputTextureA.SampleLevel(texSampler, loc, 2.).rgb, float3(1,1,1));
float i1 = dot(inputTextureB.SampleLevel(texSampler, loc, 2.).rgb, float3(1,1,1));
return lerp(i0, i1, time);
// return float(0.);
}
float4 psMain(vsOutput psInput) : SV_TARGET
{
float2 uv = psInput.texCoord;
float aspect = TargetWidth/TargetHeight;
uv -=.5;
uv.x *= aspect;
// lucas-kanade optical flow
// https://en.wikipedia.org/wiki/Lucas%E2%80%93Kanade_method
float2x2 AtA = float2x2(0.0, 0.0, 0.0, 0.0);
float2 Atb = float2(0.0, 0.0);
float xstart = uv.x;
float2 px_step = 4. / uv.xy;
for (int i = 0; i < 7; ++i) {
uv.x = xstart;
for (int j = 0; j < 7; ++j) {
float I = intensity(uv, 0.0);
float It = I - intensity(uv, 1.0);
float Ix = intensity(uv + float2(1.0, 0.0) * px_step, 0.0) - I;
float Iy = intensity(uv + float2(0.0, 1.0) * px_step, 0.0) - I;
AtA += float2x2(Ix * Ix, Ix * Iy, Ix * Iy, Iy * Iy);
Atb -= float2(It * Ix, It * Iy);
uv.x += px_step.x;
}
uv.y += px_step.y;
}
float2x2 AtAinv = float2x2(AtA[0][0], -AtA[0][1], -AtA[1][0], AtA[1][1]) /
(AtA[0][0] * AtA[1][1] - AtA[1][0] * AtA[0][1]);
float2 flow = mul(AtAinv, Atb);
return float4(0.5 + .1 * flow,0.0,1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment