Welcome Guest ( Log In | Register )


Important

The forums will be closing permanently the weekend of March 15th. Please see the notice in the announcements forum for details.

 
Vdshader, Software shader engine
« Next Oldest | Next Newest » Track this topic | Email this topic | Print this topic
phaeron
Posted: Mar 17 2012, 12:34 AM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



I finally got around to doing some fixes and updates to my vdshader filter:
http://www.virtualdub.org/downloads/vdshader-1.3.zip
http://www.virtualdub.org/downloads/vdshad...der-1.3-src.zip

vdshader is a filter for running shaders written in a subset of HLSL/Cg on the CPU on video, with an interactive editing environment. This allows much faster prototyping of simple filters than can be done in C/C++.

A full changelog is in the changes.txt file in the binary archive, but here are some of the updates in V1.3:

  • Fixed several crashes.
  • Fixed horizontal interpolator offset in some cases.
  • Fixed border pixel handling on textures.
  • Multi frame windows and multi-source fetching are now supported.
  • The parser now allows "half" types and the "static" keyword.
  • Texture shaders are now supported.


 
    Top
Rumbah
Posted: Jun 4 2012, 03:28 PM


Newbie


Group: Members
Posts: 5
Member No.: 34980
Joined: 4-June 12



I just saw this filter and think it is great as it can take the graphic card hassle away that comes with gpu enhanced filters (starting a filter multiple times, playing a 3d game while filtering etc.).

After tinkering with it a bit a few questions came to my mind:

Is it possible to access the resolution of the input video so that you can do single pixel steps to the sides?

Is it possible to enlarge the video with a shader?

Can this filter be called by Avisynth? I tried with e.g:
CODE
LoadVirtualdubPlugin("D:\Downloads\VirtualDub-1.8.0\plugins\vdshader.vdf", "ShaderCompiler", preroll=0)
a=FFAudioSource("testremux.mkv")
v=FFvideosource("testremux.mkv")
Audiodub(v,a)
ShaderCompiler(0, 0, 1, "D:\\Downloads\\VirtualDub-1.8.0\\FXFilters\\testtt.fx", 0, "")
but I always get an invalid arguments error message. (saving the processing settings in VirtualDub results to
CODE
VirtualDub.video.filters.instance[0].Config(0, 0, 1, "D:\\Downloads\\VirtualDub-1.8.0\\FXFilters\\testtt.fx", 0, "");
)

I hope someone can help me with some of these questions.

Thanks in advance
Rumbah

PS: The questions came to my mind while thinking about porting xBR (http://board.byuu.org/viewtopic.php?p=58705#p58705) to VirtualDub via the shader plugin.
 
     Top
phaeron
Posted: Jun 9 2012, 11:55 PM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



Figured out what was wrong with the script params -- I had broken the definitions when I retargeted the filter. This version should work:

http://virtualdub.org/beta/vdshader-1.4-test2.zip
http://virtualdub.org/beta/vdshader-1.4-test2-src.zip

However... using this filter in Avisynth will be a crapshoot. Basic operation appears to work, but the filter API version that Avisynth supports is very old and technically is older than this filter needs. Multi-source and multi-frame fetching will not work in this scenario. Avisynth only supports one filter per DLL here so you should not use the predefined filter mechanism.

Also, do not attempt to load the filter in Avisynth from VirtualDub's plugins/plugins32 directory -- this will cause both VirtualDub and Avisynth to use the same plugin DLL, which will blow up because both will try to init the filter.

QUOTE
Is it possible to access the resolution of the input video so that you can do single pixel steps to the sides?


Yes -- you will need to extern constant registers c0 and c1. c0.xy contains the width/height of the source, while c1.xy contains the inverse values. Adding c1.xy*offset to the UV sampling coordinates will step by offset texels. I need to add some mechanism to get this per-source instead of only on source 0.

(As a side note, this is much easier in Pixel Shader 4.0, which allows for direct texel offsets... but emulating that profile is a huge can of worms. One day I would like to have vdshader also be able to actually run the pixel shaders on hardware.)

QUOTE
Is it possible to enlarge the video with a shader?


Yes, but not in the shader itself. You need to configure vdshader to target a larger frame size. It will then run the shader over a bigger bitmap. The filtering parameters on the sampler will determine whether point sampling or bilinear filtering is used.
 
    Top
Rumbah
Posted: Jun 10 2012, 02:05 PM


Newbie


Group: Members
Posts: 5
Member No.: 34980
Joined: 4-June 12



Thank you, the test version 2 now works with avisynth. The filter I'll try to use just works on the picture so I won't need multi source or multi frame stuff and this is much easier than writing an Avisynth plugin, at least for me as a programming newbie.

In the meantime I explored vdshader a bit more and ran into a compiler error that I don't understand. I use the following shader:
CODE

texture vd_srctexture;

static float coef           = 2.0;
static float3 dtt           = float3(65536,255,1);
static float y_weight        = 48.0;
static float u_weight        = 7.0;
static float v_weight        = 6.0;
static float3x3 yuv          = float3x3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813);
static float3 yuv_weighted = float3(14.352, 28.176, 5.472);
//static float3x3 yuv_weighted = float3x3(y_weight*yuv[0], u_weight*yuv[1], v_weight*yuv[2]);
//static float3x3 yuv_weighted = float3x3(y_weight*yuv.[0], u_weight*yuv[1], v_weight*yuv[2]);

sampler src = sampler_state {
Texture = (vd_srctexture);
MinFilter = point;
MagFilter = point;
AddressU = clamp;
AddressV = clamp;
};

static float magnification <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 100;
float vd_tunablesteps = 100;
> = 27;

static float height <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 100;
float vd_tunablesteps = 100;
> = 81;

static float width <
bool vd_tunable = true;
float vd_tunablemin = 0;
float vd_tunablemax = 100;
float vd_tunablesteps = 100;
> = 81;


float4 df(float4 A, float4 B)
{
return float4(abs(A-B));
}


float4 weighted_distance(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h)
{
return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h));
}



float4 PS(float2 uv: TEXCOORD0) : COLOR0 {

float stepx = float(magnification/width);
float stepy = float(magnification/height);
float2 dx = float2(stepx, 0.0);
float2 dy = float2(0.0, stepy);
bool4 edr;
bool4 edr_left;
bool4 edr_up;
bool4 px;  // px = pixel, edr = edge detection rule
bool4 interp_restriction_lv1;
bool4 interp_restriction_lv2_left;
bool4 interp_restriction_lv2_up;
bool4 nc; // new_color
bool4 fx;
bool4 fx_left;
bool4 fx_up; // inequations of straight lines.

float2 fp = frac(uv*float2(width, height));


float3 A = tex2D(src, uv -dx -dy).xyz;
float3 B = tex2D(src, uv     -dy).xyz;
float3 C = tex2D(src, uv +dx -dy).xyz;
float3 D = tex2D(src, uv -dx    ).xyz;
float3 E = tex2D(src, uv        ).xyz;
float3 F = tex2D(src, uv +dx    ).xyz;
float3 G = tex2D(src, uv -dx +dy).xyz;
float3 H = tex2D(src, uv     +dy).xyz;
float3 I = tex2D(src, uv +dx +dy).xyz;

float3 A1 = tex2D(src, uv     -dx -2.0*dy).xyz;
float3 Y1 = tex2D(src, uv     +dx -2.0*dy).xyz;
float3 A0 = tex2D(src, uv -2.0*dx     -dy).xyz;
float3 G0 = tex2D(src, uv -2.0*dx     +dy).xyz;
float3 C4 = tex2D(src, uv +2.0*dx     -dy).xyz;
float3 I4 = tex2D(src, uv +2.0*dx     +dy).xyz;
float3 G5 = tex2D(src, uv     -dx +2.0*dy).xyz;
float3 I5 = tex2D(src, uv     +dx +2.0*dy).xyz;
float3 B1 = tex2D(src, uv         -2.0*dy).xyz;
float3 D0 = tex2D(src, uv -2.0*dx        ).xyz;
float3 H5 = tex2D(src, uv         +2.0*dy).xyz;
float3 F4 = tex2D(src, uv +2.0*dx        ).xyz;

float4 b = mul( float4x3(B, D, H, F), yuv_weighted );
float4 c = mul( float4x3(C, A, G, I), yuv_weighted );
float4 e = mul( float4x3(E, E, E, E), yuv_weighted );
float4 d = b.yzwx;
float4 f = b.wxyz;
float4 g = c.zwxy;
float4 h = b.zwxy;
float4 i = c.wxyz;

float4 i4 = mul( float4x3(I4, Y1, A0, G5), yuv_weighted );
float4 i5 = mul( float4x3(I5, C4, A1, G0), yuv_weighted );
float4 h5 = mul( float4x3(H5, F4, B1, D0), yuv_weighted );
float4 f4 = h5.yzwx;

float4 Ao = float4( 1.0, -1.0, -1.0, 1.0 );
float4 Bo = float4( 1.0,  1.0, -1.0,-1.0 );
float4 Co = float4( 1.5,  0.5, -0.5, 0.5 );
float4 Ax = float4( 1.0, -1.0, -1.0, 1.0 );
float4 Bx = float4( 0.5,  2.0, -0.5,-2.0 );
float4 Cx = float4( 1.0,  1.0, -0.5, 0.0 );
float4 Ay = float4( 1.0, -1.0, -1.0, 1.0 );
float4 By = float4( 2.0,  0.5, -2.0,-0.5 );
float4 Cy = float4( 2.0,  0.0, -1.0, 0.5 );

// These inequations define the line below which interpolation occurs.
fx      = (Ao*fp.y+Bo*fp.x > Co);
fx_left = (Ax*fp.y+Bx*fp.x > Cx);
fx_up   = (Ay*fp.y+By*fp.x > Cy);

interp_restriction_lv1      = ((e!=f) && (e!=h));
interp_restriction_lv2_left = ((e!=g) && (d!=g));
interp_restriction_lv2_up   = ((e!=c) && (b!=c));

edr      = (weighted_distance( e, c, g, i, h5, f4, h, f) < weighted_distance( h, d, i5, f, i4, b, e, i)) && interp_restriction_lv1;
edr_left = ((coef*df(f,g)) <= df(h,c)) && interp_restriction_lv2_left;
edr_up   = (df(f,g) >= (coef*df(h,c))) && interp_restriction_lv2_up;

nc = ( edr && (fx || edr_left && fx_left || edr_up && fx_up) );

px = (df(e,f) <= df(e,h));

float3 res = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : nc.w ? px.w ? H : D : E;

return float3(res);

}

technique {
pass {
 PixelShader = compile ps_3_0 PS();
}
}

When I try to use it I get:
CODE

D:\Downloads\VirtualDub-1.8.0\FXFilters\test.fx(155,37): Error! Shader validation failed: Uninitialized register components read.

adding a "return px;" under return "float3(res);" results in:
CODE
D:\Downloads\VirtualDub-1.8.0\FXFilters\test.fx(156,36): Error! Internal compiler error: Uninitialized temp register used
//
// Generated by VirtualDub Shader Compiler
//
// Registers:
//
//   Name              Reg   Size
//   ----------------- ----- ----
//   uv                v0    1
//   src               s0    1

   def c0, 81, 81, 0, 0
   def c1, 0.333333, 0, 0, 0
   def c2, 0, 0.333333, 0, 0
   def c3, 0.333333, -0.333333, 0, 0
   def c4, 0.333333, -0.666667, 0, 0
   def c5, 0.666667, -0.333333, 0, 0
   def c6, 0.666667, 0, 0, 0
   def c7, 0, 0.666667, 0, 0
   def c8, 14.352, 28.176, 0, 0
   def c9, 0, 0, 0, 0
   def c10, 1, -1, -1, 1
   def c11, 0.5, 2, -0.5, -2
   def c12, 0, 1, 0, 0
   def c13, 2, 2, 2, 2
   mul r0.x, v0.x, c0.x
   frc r1.x, r0.x
   sub r2.xy, v0, c1
   sub r3.xy, r2, c2
   texld r4.xy, r3, s0
   sub r5.xy, v0, c2
   texld r6.xy, r5, s0
   add r7.xy, v0, c3
   texld r8.xy, r7, s0
   sub r9.xy, v0, c1
   texld r10.xy, r9, s0
   texld r11.xy, v0, s0
   add r12.xy, v0, c4
   texld r13.xy, r12, s0
   add r14.xy, v0, c5
   texld r15.xy, r14, s0
   add r16.xy, v0, c6
   add r17.xy, r16, c2
   add r18.xy, v0, c1
   add r19.xy, r18, c7
   texld r20.xy, r19, s0
   add r21.xy, v0, c7
   texld r22.xy, r21, s0
   add r23.xy, v0, c6
   texld r24.xy, r23, s0
   dp2add r25.x, r6, c8, c9.x
   dp2add r25.y, r10, c8, c9.x
   dp2add r26.x, r8, c8, c9.x
   dp2add r26.y, r4, c8, c9.x
   dp2add r27.x, r11, c8, c9.x
   dp2add r27.y, r11, c8, c9.x
   dp2add r28.y, r15, c8, c9.x
   dp2add r29.x, r22, c8, c9.x
   sub r30.x, r27.x, r26.z
   sub r31.x, r25.y, r26.z
   sub r32.zw, r27, r26
   abs r33.w, r32.w
   sub r34.zw, r27, r26.zwxy
   abs r35.w, r34.w
   sub r36.w, r26.z, r29.w
   sub r37.zw, r25.zwxy, r25.yzwx
   abs r38.w, r37.w
   sub r39.zw, r25.zwxy, r28
   abs r40.w, r39.w
   sub r54.w, r25.z, r29.w
   sub r58.zw, r26.wxyz, r27.zwxy
   abs r59.w, r58.w
   sub r61.w, r26.y, r27.w
   sub r64.w, r26.y, r27.w
   sub r66, r28, r26.wxyz
   abs r67, r66
   sub r68, r28, r26.zwxy
   abs r69, r68
   sub r70, r69, r67
   cmp r71, r70, c12.y, c12.x
   mov o0, r71

// approximately 56 instruction slots used

Is this an error in the compiler or did I do anything wrong?


A few additional things I noticed while working with the shader compiler
- Having the compiler throw errors with exact line numbers is very useful but it would be a bit easier to handle if the editor itself would show the line numbers of the shader you write. Else you have to count to line e.g. 65 if an error occured there.
- I noticed that half matrices are not supported, e.g. half3x3()
matrix3x3;
- I noticed that accessing matrices as arrays does not work, e.g.
matrix3x3[0] to access the first row.


I thank you very much für this very useful plugin as it makes experimenting with image filters very easy without much knowledge of a complete programming language.

EDIT: Just a question about as a noob to C
QUOTE
Yes -- you will need to extern constant registers c0 and c1.
Is "extern float2 size = c0.xy" correct or how do I get the extern register value?
EDIT2: After searching for extern in c and not in cg i guess this one is correct?:
extern float4 c0;
float2 size = c0.xy;
 
     Top
Jam One
Posted: Jun 10 2012, 09:12 PM


Advanced Member


Group: Members
Posts: 580
Member No.: 25518
Joined: 8-May 09



QUOTE (phaeron @ Mar 17 2012, 04:34 AM)
I finally got around to doing some fixes and updates to my vdshader filter ...

Is this a replacement for the previously presented GPU Shader Filter?
...Forgive my ignorance...
 
     Top
phaeron
Posted: Jun 17 2012, 09:57 PM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



There is a go to error command... I think it's F4 on the keyboard.

half3x3 should be easy to map. The [] operator is a bit more work. The reason is that HLSL allows expressions here, and if the indexing expression turns out not to be a constant, it will emit a nasty select tree in the code to allow it to work (temp registers can't be indexed). I suppose I could implement a restricted form for the common case.

The reason for the internal error is likely that you are attempting to return a 3-vector (float3) from a function that requires a 4-vector (float4). I need to put in proper handling code for this. In the meantime, returning float4(res, 0) should do the trick.

The filter isn't a replacement for GPU shader filter, but it does much the same, except with the CPU. Merging the two would be ideal; the main issue is that the CPU-based code doesn't produce or accept valid D3D shaders.
 
    Top
Rumbah
Posted: Jun 17 2012, 10:19 PM


Newbie


Group: Members
Posts: 5
Member No.: 34980
Joined: 4-June 12



QUOTE (phaeron @ Jun 17 2012, 09:57 PM)
There is a go to error command... I think it's F4 on the keyboard.

In the meantime, returning float4(res, 0) should do the trick.

Ah, good to know there's a keyboard shortcut to jump to the error, that should be enough.

Returning float4(res, 0) sadly does not work, if I do that I get
CODE
D:\Downloads\VirtualDub-1.8.0\FXFilters\test.fx(150,37): Error! Shader validation failed: Uninitialized register components read.



EDIT: Edited the error message as I first did a typing fault.
 
     Top
Gargamel
Posted: Dec 11 2012, 01:36 PM


Newbie


Group: Members
Posts: 6
Member No.: 35826
Joined: 11-December 12



Hi everybody,

This is my first post here, and I have first to thank you all, for we newbies or half-newbies find a lot of explanations and help in your threads.

I don't ask a question for myself (except to understand a bit), but for a good buddy, working to transfer old films through VirtualDub 1.9.11

He encounters a weird problem when using VDshader filter (v.1.2 or v.1.4-test2) to improve faded colours:
- He obtains a good result in the preview window, and he can read the modified clip by File/"Preview filtered..." OK.
- But when trying to "Save as AVI...", he sees the usual window about processing, very briefly, then VirtualDub vanishes promptly, without an error message, neither crashinfo.txt, nothing. No more in the Windows Events Log.
- That happens with VDshader only, even used alone. Other sessions using other filters run OK; no problem when he "Saves as AVI...".

But others, like myself, were not able to get such a behaviour on our systems, where everything works right. And I didn't read that issue already.

Thank you for any idea...
 
     Top
Gargamel
Posted: Dec 14 2012, 09:03 AM


Newbie


Group: Members
Posts: 6
Member No.: 35826
Joined: 11-December 12



Don't worry: finally, the concerned guy will use now ColorMill (which runs ok for him) instead of VDshader...
http://letransfert.xooit.fr/t589-Probl%C3%...er.htm?start=80
 
     Top
phaeron
Posted: Dec 17 2012, 03:03 AM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



Sorry for the delay -- I often only read the board on weekends.

I'm not sure if it is related to the problem your friend was seeing, but I did find a couple of bugs in the filter. One was related to the config dialog, so it's unlikely to be the problem, but the other was an issue with not properly handling globals being referenced in a vector initializer expression (i.e. float3(global...)), so it might have been related. The fixed version:

http://www.virtualdub.org/downloads/vdshader-1.4.zip
http://www.virtualdub.org/downloads/vdshad...der-1.4-src.zip
 
    Top
Gargamel
Posted: Dec 17 2012, 09:38 AM


Newbie


Group: Members
Posts: 6
Member No.: 35826
Joined: 11-December 12



Thanks a lot, phaeron.
Maybe he'll have to revise his script, but that issue on his single PC surprised us. As I said, he can bypass the problem thanks to another filter.
The guy isn't at home before next year smile.gif
I see that you updated the "changes.txt" yesterday, but the filter itself may be the same as your 1.4-test2 version ?
 
     Top
phaeron
Posted: Dec 27 2012, 08:40 PM


Virtualdub Developer


Group: Administrator
Posts: 7773
Member No.: 61
Joined: 30-July 02



Nope, the filter's updated. The 1.4 test-2 version still said V1.1 in its About box, but this one should say V1.4.
 
    Top
Gargamel
Posted: Jan 25 2013, 09:59 AM


Newbie


Group: Members
Posts: 6
Member No.: 35826
Joined: 11-December 12



That's OK.
Thank you again !
 
     Top
0 User(s) are reading this topic (0 Guests and 0 Anonymous Users)
0 Members:
12 replies since Mar 17 2012, 12:34 AM Track this topic | Email this topic | Print this topic

<< Back to VirtualDub Filters and Filter Development