Welcome, Guest
Username Password: Remember me

TOPIC: Documentation for developing Lightworks effects

Documentation for developing Lightworks effects 1 year, 1 month ago #143678

  • schrauber
  • OFFLINE
  • Platinum Boarder
  • Posts: 1823
  • 1 year, 1 month ago
Here we collect information about how to create Lightworks .fx effects.
In this first post I try to structure this information.

An introduction can be found in post # 143763
some posts further down on this page (author "jwrl").
Please also note the links listed there.




Here is a template for creating effects.:
It shows a program structure that you can complete with your Code.
To unfold please click on the spoiler.
:pinch: Warning: Spoiler!


.............................................................

Details:


The following chapters are structured according to this template and collect important information about the program sections (click on the spoiler to open a chapter).
It is assumed that you have understood the introduction by the author "jwrl", and the introductory links listed there. If you can contribute something, or have questions, then post this please.

File Header:
:pinch: Warning: Spoiler!


Inputs: _________ Updated: 05 March 2018
:pinch: Warning: Spoiler!


Samplers: _________ Updated: 21 January 2018
:pinch: Warning: Spoiler!


Parameters (In particular: user effect settings):
:pinch: Warning: Spoiler!

Special auto-synced parameters: _________ ( Updated: 26 November 2017 )
:pinch: Warning: Spoiler!


Definitions and declarations:_________Updated: 26 November 2017
:pinch: Warning: Spoiler!


Functions:
:pinch: Warning: Spoiler!


Shaders:
:pinch: Warning: Spoiler!


Techniques:_________Updated: 26 November 2017
:pinch: Warning: Spoiler!






Miscellaneous:

Cross-platform compatibility:_________ Updated: 21 January 2018
:pinch: Warning: Spoiler!




Swizzle operator (.rgba and .xyzw) :
:pinch: Warning: Spoiler!


[/spoiler]
Mainly automatically translated
--------------------------------------------
Windows 10, 64 Bit
Intel i5-4440 (3,1 GHz) ; Intel HD Graphics 4600
Last Edit: 3 months, 2 weeks ago by schrauber.

Documentation for developing Lightworks effects 1 year, 1 month ago #143680

  • briandrys
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 6341
  • 1 year, 1 month ago
I'll create a sticky. Users can then post links and other information here for Lightworks FX development documentation.

Documentation for developing Lightworks effects 1 year, 1 month ago #143682

  • schrauber
  • OFFLINE
  • Platinum Boarder
  • Posts: 1823
  • 1 year, 1 month ago
Ok, I've tried to structure the most important information.
Mainly automatically translated
--------------------------------------------
Windows 10, 64 Bit
Intel i5-4440 (3,1 GHz) ; Intel HD Graphics 4600
Last Edit: 1 year ago by schrauber. Reason: The post has been temporarily edited to create a draft.

Documentation for developing Lightworks effects 1 year, 1 month ago #143685

  • lghtwrks
  • OFFLINE
  • Platinum Boarder
  • Posts: 2717
  • 1 year, 1 month ago
MS - Reference for HLSL
msdn.microsoft.com/en-us/library/windows/desktop/bb509638(v=vs.85).aspx

MS - Programming Guide for HLSL
msdn.microsoft.com/en-us/library/windows/desktop/bb509635(v=vs.85).aspx


+ General Search
social.msdn.microsoft.com/search/en-US/windows?query=hlsl programming
Last Edit: 1 year, 1 month ago by lghtwrks.

Documentation for developing Lightworks effects 1 year, 1 month ago #143688

  • lghtwrks
  • OFFLINE
  • Platinum Boarder
  • Posts: 2717
  • 1 year, 1 month ago

Documentation for developing Lightworks effects 1 year, 1 month ago #143689

  • lghtwrks
  • OFFLINE
  • Platinum Boarder
  • Posts: 2717
  • 1 year, 1 month ago
The NVIDIA Shader Library - HLSL
with downloads
developer.download.nvidia.com/shaderlibrary/webpages/hlsl_shaders.html

Documentation for developing Lightworks effects 1 year, 1 month ago #143741

  • schrauber
  • OFFLINE
  • Platinum Boarder
  • Posts: 1823
  • 1 year, 1 month ago
Edit:
I have tried to show different fx.- program structures.
The drawing with only one pixel shader can be seen in the post above: 143678.
Others will follow if needed ...
Mainly automatically translated
--------------------------------------------
Windows 10, 64 Bit
Intel i5-4440 (3,1 GHz) ; Intel HD Graphics 4600
Last Edit: 1 year, 1 month ago by schrauber.

Documentation for developing Lightworks effects 1 year, 1 month ago #143763

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
If it helps, here's an edited version of an article that I planned some time back, then abandoned.

How do I create an effect?

There are several resources that can be used to help develop user effects. What got me started are two articles written for Redshark News by khaver. For general information on how Lightworks effects work read Understanding Lightworks VFX, and for an introduction to the Lightworks .fx programming check out How to write video effects for Lightworks. And if you click on the link to my chromakeyer, you'll see how many blunders a newbie can make and still not break the Lightworks effects engine! It's pretty robust.

The first thing to be aware of is that these are not really HLSL effects at all, in that they aren't actually written in that language. They are based on Nvidia's Cg language, and as such, the best place to go for a reference is Nvidia's Cg reference manual. That language is based on a mixture of C and C++, with extra shader-specific commands. If you're familiar with any of the C family you should be able to pick it up reasonably quickly. That's why using HLSL code may not always work for you.

The next thing to do is search out examples on line. Look at Cg, HLSL and GLSL versions. They won't necessarily directly translate into Lightworks effects, but they may give you ideas. Additionally because Lightworks' effects compiler is based on two different libraries there can be compatibility issues cross platform. In the Windows world it's D3D based, but in the Mac/Linux world it's Cg. Repeating, the language used cross-platform is Cg, but the compiler isn't.

As a developer it's up to you to sort cross-platform issues out. In brief, if you ensure that your effect compiles safely under the default Windows ps_2_b profile it should be safely cross-platform. The reverse cannot be guaranteed. To cross-check for yourself, a Linux or Mac user should run Lightworks under Wine or Bootcamp or similar and if the effect compiles you will be safe. Failing that, if you have doubts post it here and ask for feedback. Someone is sure to help.

So without further ado, let's look at some examples, as supplied by Editshare, with additional comments by me.

Single input, Single pass
//--------------------------------------------------------------//
// Header
//
// Lightworks effects have to have a _LwksEffectInfo block
// which defines basic information about the effect (ie. name
// and category). EffectGroup must be "GenericPixelShader".
//--------------------------------------------------------------//

int _LwksEffectInfo                            // Mandatory header declaration
<
   string EffectGroup = "GenericPixelShader";  // Mandatory group declaration
   string Description = "Lift, Gamma, Gain";   // The title displayed
   string Category    = "Colour";              // Category for the effect
   string SubCategory = "Samples";             // Sets the V14+ subcategory
> = 0;                                         // Mandatory return value.

//--------------------------------------------------------------//
// Inputs
//--------------------------------------------------------------//

// For each 'texture' declared here, Lightworks adds a matching
// input to your effect (so for a four input effect, you'd need
// to declare four textures and samplers).  The order in which
// they're declared is important, because that's the order in
// which they'll appear on the effect.  When the effect is used
// the first texture will be connected to the topmost video layer,
// the second to the next, and so on.

texture Input;

//--------------------------------------------------------------//
// Samplers
//--------------------------------------------------------------//

// For each 'texture' declared above, there must be a matching
// 'sampler' declared.  The sampler is the means by which the
// effect accesses the individual video streams.

sampler FgSampler = sampler_state
{
   Texture = <Input>;
};

//--------------------------------------------------------------//
// Define parameters here.
//
// The Lightworks application will automatically generate
// sliders/controls for all parameters which do not start
// with a leading '_' character
//--------------------------------------------------------------//

float MasterLift
<
   string Group       = "Master"; // Causes this parameter to show in the group 'Master'
   string Description = "Lift";   // The text label that will be given on screen
   float MinVal       = -1.00;    // This is a special value, and will display as -100%
   float MaxVal       = 1.00;     // This will display as 100%.
> = 0.0;                          // Default value

float MasterGamma
<
   string Description = "Gamma";
   string Group       = "Master";
   float MinVal       = 0.1;      // A value other than 1.0 will display as is, ie., 0.1
   float MaxVal       = 4.00;
> = 1.0;

float MasterGain
<
   string Description = "Gain";
   string Group       = "Master";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float RedLift
<
   string Description = "Lift";
   string Group       = "Red";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float RedGamma
<
   string Description = "Gamma";
   string Group       = "Red";
   float MinVal       = 0.1;
   float MaxVal       = 4.00;
> = 1.0;

float RedGain
<
   string Description = "Gain";
   string Group       = "Red";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float GreenLift
<
   string Description = "Lift";
   string Group       = "Green";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float GreenGamma
<
   string Description = "Gamma";
   string Group       = "Green";
   float MinVal       = 0.1;
   float MaxVal       = 4.00;
> = 1.0;

float GreenGain
<
   string Description = "Gain";
   string Group       = "Green";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float BlueLift
<
   string Description = "Lift";
   string Group       = "Blue";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float BlueGamma
<
   string Description = "Gamma";
   string Group       = "Blue";
   float MinVal       = 0.1;
   float MaxVal       = 4.00;
> = 1.0;

float BlueGain
<
   string Description = "Gain";
   string Group       = "Blue";
   float MinVal       = -1.00;
   float MaxVal       = 2.00;
> = 0.0;

//--------------------------------------------------------------//
// Definitions and declarations
//
// I have no idea what this pragma does.  I think that it's for
// debugging purpose only, and can be safely omitted.  Well, I
// certainly have in all my recently developed effects - jwrl.
//--------------------------------------------------------------//

#pragma warning ( disable : 3571 )

//--------------------------------------------------------------//
// Pixel Shader
//
// This section defines the code which the GPU will execute
// for every pixel in an output image.
//
// Note that pixels are processed out of order, in parallel.
// When using shader model 2.0, there's a 64 instruction limit.
// Use multple passes if you need more.
//--------------------------------------------------------------//

float4 LiftGammaGain( float2 xy : TEXCOORD1 ) : COLOR
{
   // Read a pixel from the source image at position 'xy'
   // and place it in the variable 'source'
   float4 source = tex2D( FgSampler, xy );

   // Set up compound RGBA variables from the user-specified
   // channel parameters
   float4 gamma = { RedGamma, GreenGamma, BlueGamma , 1.0 };
   float4 lift  = { RedLift,  GreenLift,  BlueLift,   1.0 };
   float4 gain  = { RedGain,  GreenGain,  BlueGain,   1.0 };

   gamma.rgb += MasterGamma - 1;
   lift.rgb  += MasterLift;
   gain.rgb  += MasterGain + 1;

   // Clamp the values.  Would be nice to use clamp()/saturate()
   // here, but the run-time FX compiler in VS2005 will fail if
   // you do.  Nice.

   // That no longer appears to be the case.  I have used both
   // clamp() and saturate() with no apparent ill effects.
   // However an alternative to using conditional statements
   // would be gamma.r = max (gamma.r, 0.1).  That will do exactly
   // the same thing, but faster.  Using gamma = max (gamma, 0.1)
   // would also work, but would apply the same check to gamma.a.
   // In this case that would be safe to do, as gamma.a = 1.0 - jwrl.

   if ( gamma.r < 0.1 ) gamma.r = 0.1;
   if ( gamma.g < 0.1 ) gamma.g = 0.1;
   if ( gamma.b < 0.1 ) gamma.b = 0.1;

   // Perform the correction
   float4 corrected = pow( source, 1 / gamma ) * gain;
   corrected += ( 1 - corrected ) * lift;

   // Honour source alpha
   corrected = lerp( source, corrected, source.a );
   corrected.a = source.a;

   return corrected;
}

//--------------------------------------------------------------//
// Technique
//
// Specifies the order of passes (we only have a single pass
// with this example, so there's not much to do)
//--------------------------------------------------------------//

technique SampleFxTechnique
{
   pass SinglePass
   {
      PixelShader = compile PROFILE LiftGammaGain();
   }
}


Single input, Multi pass
//--------------------------------------------------------------//
// Header
/--------------------------------------------------------------//

int _LwksEffectInfo
<
   string EffectGroup = "GenericPixelShader";
   string Description = "Shear";
   string Category    = "Stylize";
   string SubCategory = "Samples";
> = 0;

//--------------------------------------------------------------//
// Inputs
//--------------------------------------------------------------//

texture Input;

// This is a TWO pass effect, so we need an intermediate texture
// which stores the results from pass 1, and serves as the input
// to pass 2.  This is done by defining a target texture in this
// way.  Because it's a target texture only, it will not appear
// as a user input to the effect.

texture OutputFromPassOne : RenderColorTarget;

//--------------------------------------------------------------//
// Samplers
//--------------------------------------------------------------//

sampler FgSampler = sampler_state
{
   Texture = <Input>;
};

sampler P1OutSampler = sampler_state
{
   Texture = <OutputFromPassOne>;
   AddressU  = Clamp;               // These are redundant, and have been included
   AddressV  = Clamp;               // just to show the settings available when
   MinFilter = Linear;              // declaring a sampler.  In this example they
   MagFilter = Linear;              // serve no useful purpose and need not be
   MipFilter = Linear;              // declared at all.
};

// Additional note:  The above comment about the need to fully
// declare samplers is not always correct cross-platform.
// During debugging it was found that the sampler default
// state could not be relied on.  It is better practice
// for that reason to fully declare samplers, or at the
// very least, fully declare the address modes - jwrl.

//--------------------------------------------------------------//
// Parameters
//--------------------------------------------------------------//

float Horizontal
<
   string Description = "Horizontal";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

float Vertical
<
   string Description = "Vertical";
   float MinVal       = -1.00;
   float MaxVal       = 1.00;
> = 0.0;

//--------------------------------------------------------------//
// Shaders
//--------------------------------------------------------------//

float4 ShearHorizontal( float2 xy : TEXCOORD1 ) : COLOR
{
   // Amend the x position based on the user-specified shear
   // amount
   float2 pos = xy;
   pos.x += ( pos.y - 0.5 ) * Horizontal;

   return tex2D( FgSampler, pos );
}

float4 ShearVertical( float2 xy : TEXCOORD1 ) : COLOR
{
   // Amend the y position based on the user-specified shear
   // amount
   float2 pos = xy;
   pos.y += ( pos.x - 0.5 ) * Vertical;

   return tex2D( P1OutSampler, pos );
}

//--------------------------------------------------------------//
// Techniques
//
// Now that we have more than one pass, this specifies the
// order in which the passes are executed.
//--------------------------------------------------------------//

technique SampleFxTechnique
{
   pass ShearX
   <
      string Script = "RenderColorTarget0 = OutputFromPassOne;";  // Sets the target the
   >                                                              // result is placed in
   {
      PixelShader = compile PROFILE ShearHorizontal();
   }

   pass ShearY
   {
      PixelShader = compile PROFILE ShearVertical();
   }
}


Multi input, Single pass
//--------------------------------------------------------------//
// Header
//--------------------------------------------------------------//

int _LwksEffectInfo
<
   string EffectGroup = "GenericPixelShader";
   string Description = "Channel Combiner";
   string Category    = "Stylize";
   string SubCategory = "Samples";
> = 0;

//--------------------------------------------------------------//
// Inputs
//--------------------------------------------------------------//

texture R;
texture G;
texture B;
texture A;

//--------------------------------------------------------------//
// Samplers
//--------------------------------------------------------------//

sampler RSampler = sampler_state { Texture = <R>; };
sampler GSampler = sampler_state { Texture = <G>; };
sampler BSampler = sampler_state { Texture = <B>; };
sampler ASampler = sampler_state { Texture = <A>; };

//--------------------------------------------------------------//
// Parameters
//--------------------------------------------------------------//

float Opacity
<
   string Description = "Opacity";
   float MinVal       = 0.0;
   float MaxVal       = 1.0;
> = 1.0;

//--------------------------------------------------------------//
// Shaders
//--------------------------------------------------------------//

float4 CombineRGBA( float2 xy : TEXCOORD1 ) : COLOR
{
   return float4( tex2D( RSampler, xy ).r,
                  tex2D( GSampler, xy ).g,
                  tex2D( BSampler, xy ).b,
                  tex2D( ASampler, xy ).a * Opacity );
}

//--------------------------------------------------------------//
// Technique
//--------------------------------------------------------------//

technique SampleFxTechnique
{
   pass SinglePass
   {
      PixelShader = compile PROFILE CombineRGBA();
   }
}


Single input, Multi technique
//--------------------------------------------------------------//
// Header
//--------------------------------------------------------------//

int _LwksEffectInfo
<
   string EffectGroup = "GenericPixelShader";
   string Description = "Channel Extractor";
   string Category    = "Stylize";
   string SubCategory = "Samples";
> = 0;

//--------------------------------------------------------------//
// Inputs
//--------------------------------------------------------------//

texture Input;

//--------------------------------------------------------------//
// Samplers
//--------------------------------------------------------------//

sampler FgSampler = sampler_state
{
   Texture = <Input>;
};

//--------------------------------------------------------------//
// Parameters
//--------------------------------------------------------------//

// If Lightworks encounters a parameter called 'SetTechnique',
// it will be shown on the FX panel like any other parameter,
// but it will also implicitly choose an execution technique
// to match the user-selection (eg. if the user chooses 'Green'
// from the drop-down list, Lightworks will arrange for the
// 'Green' technique (at the bottom of this file) to execute
// when the effect is rendered).

int SetTechnique
<
   string Description = "Channel";
   string Enum = "Red,Green,Blue,Alpha"; // The Enum parameter allows you to use literal
> = 0;                                   // comma-delimited text in your selection menu

//--------------------------------------------------------------//
// Shaders
//--------------------------------------------------------------//

float4 ExtractRed( float2 xy : TEXCOORD1 ) : COLOR
{
   float4 pixel = tex2D( FgSampler, xy );

   // This next is the original Editshare technique used in
   // their example to assign the red channel to all of RGB.
   // There are other ways possible - see ExtractGreen() and
   // ExtractBlue() below this - jwrl.

   return float4( pixel.r, pixel.r, pixel.r, 1 );
}

float4 ExtractGreen( float2 xy : TEXCOORD1 ) : COLOR
{
   float4 pixel = tex2D( FgSampler, xy );

   // This changes the original Editshare technique so that
   // we directly assign the green channel to all of RGB in
   // one hit.  ExtractBlue() below this shows another - jwrl.

   return float4( pixel.ggg, 1 );
}

float4 ExtractBlue( float2 xy : TEXCOORD1 ) : COLOR
{
   // Even more efficiently, it's possible to do everything
   // at once and also pass the alpha value of the input as
   // well - jwrl.

   return tex2D( FgSampler, xy ).bbba;
}

float4 ExtractAlpha( float2 xy : TEXCOORD1 ) : COLOR
{
   float4 pixel = tex2D( FgSampler, xy );
   return float4( pixel.a, pixel.a, pixel.a, 1 );
}

//--------------------------------------------------------------//
// Techniques
//--------------------------------------------------------------//

// The technique names used here are not important: their order
// is.  If you were to move the "Green" technique to the head
// of this list it would execute when the user selected "Red",
// and vice versa.

technique Red
{
   pass SinglePass
   {
      PixelShader = compile PROFILE ExtractRed();
   }
}

technique Green
{
   pass SinglePass
   {
      PixelShader = compile PROFILE ExtractGreen();
   }
}

technique Blue
{
   pass SinglePass
   {
      PixelShader = compile PROFILE ExtractBlue();
   }
}

technique Alpha
{
   pass SinglePass
   {
      PixelShader = compile PROFILE ExtractAlpha();
   }
}

If you want to examine these shader examples in detail, highlight them in the code block and copy them into a plain text editor. I repeat: it must be a plain text editor. Word or other Office style editors will not do. Additionally, the file must be saved in the form MyEffect.fx. MyEffect.fx.txt or MyEffect.fx.doc won't work. Alternatively you can download them from SampleFX.zip.
Last Edit: 4 months, 1 week ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #143793

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
I've now tracked down a series of answers to user questions posted by developers Hammerhead and Great White. Where necessary to make the answer clearer I have added a question before it. I've also occasionally added additional information in italics after the answer from Hammerhead.
_____________________________________________

I cleaned up my effects folder and all my effects went black. Why?

Hammerhead wrote:
Once you've created a new effect tempate from the FX file, the FX file is still in use (and will be compiled each time Lightworks starts) so if the file is removed or modified (such that it no longer compiles) then any applied effects will no longer work (you'll get black).
_____________________________________________

Sometimes my exported effect doesn't match what I set up while I was editing. Why is this?

Hammerhead wrote:
Don't forget that all images are rendered at the project output resolution and then sized for preview or export.
_____________________________________________

Are the Lightworks specialisations (header, runtime variables, etc) documented anywhere?

Hammerhead wrote:
I haven't written a document yet, but the sample .FX files in 'Lightworks\Effect Templates' are commented fairly extensively
...
Lightworks supplies the following runtime variables :

_Progress
= ( currentFrame - segmentStartFrame ) / segmentLength

_OutputWidth
The width of the current output format in pixels

_OutputHeight
The height of the current output format in pixels

_OutputAspectRatio
The aspect-ratio of the current output format

Additional information: there is a problem with the way that Lightworks returns _OutputHeight that means on interlaced projects it returns half the expected value when playback is stopped. To avoid this I use the following definition.

#define Output_Height (_OutputWidth/_OutputAspectRatio)

I then use Output_Height instead of _OutputHeight in my code. If you don't do something like that you can get unexpected results.
Last Edit: 1 year, 1 month ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #143795

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
OK, here are more of Hammerhead's questions and answers.
_____________________________________________

How can I make a file picker like the Image Matte effects?

Hammerhead wrote:
Unfortunately there's no way of creating/binding a file-picker from a shader (the image matte effect is not implemented using a pixel-shader).
...
Bear in mind that some effects have hand-coded panels (rather than shader-generated ones) so it may not be possible to replicate some of the UI elements that are present in some of the native effects.
_____________________________________________

How do I get the mouse movable position tool on the Viewer like the Image Matte effects?

Hammerhead wrote:
You can make any position parameter editable on the viewer by adding a couple of extra annotations to your x/y params, namely "SpecifiesPointX" and "SpecifiesPointY"; Here's how I do it in the radial blur effect :

float CentreX
<
   string Description = "Origin";
   string Flags = "SpecifiesPointX";
   float MinVal = 0.00;
   float MaxVal = 1.00;
> = 0.5;

float CentreY
<
   string Description = "Origin";
   string Flags = "SpecifiesPointY";
   float MinVal = 0.00;
   float MaxVal = 1.00;
> = 0.5;


Additional information: when using "SpecifiesPointY" it may be necessary to invert the sense of the value returned. In the example above float Centre_Y = 1.0 - CentreY will do that. You then use Centre_Y in your code instead of CentreY.

There's also a third parameter in this group, "SpecifiesPointZ". To see that being used look at the position parameters in the 3D DVE effect.
_____________________________________________

How do I get the colour picker and not just a slider?

Hammerhead wrote:
I've attached a copy of the pixel shader that we use for generating colour gradients. It demonstrates how to declare/use colour-based parameters

float4 TLColour
<
   string Description = "Top Left";
   bool SupportsAlpha = true;
> = { 1.0, 0.0, 0.0, 1.0 };


Additional information: You can use either standard brackets in that parameter to give you ( 1.0, 0.0, 0.0, 1.0 ) or curly brackets as shown above. If you use the standard brackets the colour shown will default to white, regardless of any values that you may have set in your code.
_____________________________________________

I need to make a colour wheel.

Hammerhead wrote:
You can make colour params be represented using a colour wheel by adding the annotation "SpecifiesColourOffset"; For example :

float4 MidTintColour
<
   string Description = "Midtones";
   string Group       = "Tonal Ranges";
   string Flags       = "SpecifiesColourOffset";
> = ( 1.0, 1.0, 1.0, 1.0 );


Additional information: the colour wheel doesn't return simple RGB values when you use that switch. The brightness setting ranges from 50% to 159%, but doesn't seem to permit ever reaching white.
_____________________________________________

How do I turn keyframes on automatically?

Hammerhead wrote:
You can make float-based parameters implicitly keyframed by adding two more annotations - KF0 and KF1 - like this :

float Amount
<
   string Description = "Amount";
   float MinVal = 0.0;
   float MaxVal = 1.0;
   float KF0    = 0.0;
   float KF1    = 1.0;
> = 0.5;

Last Edit: 1 year, 1 month ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #143893

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
Now we have some answers from Great White, to do with HLSL/GLSL issues.
_____________________________________________

How are Lightworks shaders implemented in the Linux or Mac versions since they are written in HLSL which is for DirectX? Does Lightworks translate the .fx files to an OpenGL shader before they are compiled?

Great White wrote:
We use nVidia's cg library (which is cross-platform and cross-vendor) - it allows us to compile the .fx files 'as is' so that we don't need to have different OpenGL versions for Linux/Mac. There are some slight incompatibility issues between the cg compiler and the dx compiler (eg. declaring 'const' arrays) but nothing that you can't easily work around.
_____________________________________________

Is there anything that I need to know when working with the Linux/Mac version of the compiler?

Great White wrote:
For reference, the shader compiler on Linux :

  • Does not like variables that are declared as 'const'
  • Prefers 'fmod' instead of '%'


Additional information: the reference to Linux in Great White's answer can also be taken to include OS-X.
Last Edit: 1 year, 1 month ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #143908

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
Hammerhead wrote:
You can make colour params be represented using a colour wheel by adding the annotation "SpecifiesColourOffset"

If you use the "SpecifiesColourOffset" flag the result that you will see in your settings menu will look like this.


This image is hidden for guests. Please log in or register to see it.


How it's possible to sensibly make use of it I've yet to work out. As you drag to the centre it tends to go black, or at the very best, mid grey. I think that for user effects the standard colour wheel without that flag is better.

There is a second switch, "SpecifiesColourRange", that you can use. This gives a drawbar style layout and looks like this.


This image is hidden for guests. Please log in or register to see it.


Because this is a more specialised tool intended mainly for use in keying I will leave it up to the interested user to follow up. You will find an example of its use in the Editshare chromakey sample code.
Last Edit: 1 year, 1 month ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #144268

  • brotenet
  • OFFLINE
  • Fresh Boarder
  • Posts: 2
  • 1 year, 1 month ago
Wow!!

I seriously did not expect such great response!!

Thanks jwrl !!!

Documentation for developing Lightworks effects 1 year, 1 month ago #144329

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
Glad to be able to help. And I have more.

If you go to the "Shaders" folder in your Lightworks program folder you will find a lot of Editshare-supplied examples. They all use "compile ps_2_0 MyShader ()" as the compiler directive which definitely will only work on Windows. In my versions of their examples above I have changed the technique compiler instruction to "compile PROFILE MyShader ()", which is mandatory for cross-platform use.

If you need a specific shader profile to get your effect working on Windows you will need to explicitly declare that profile. The safest way to do this is to add a definition to your code, then supply two versions, one for Windows, the other for Linus/OS-X. This is an example of what I mean, using ps 3.0.

#define PROFILE ps_3_0   // Allows the effect to compile in Windows

// #define PROFILE ps_3_0   Allows the effect to compile in Linux/OS-X

If you put that declaration at the very head of your code and simply comment it out for the non-Windows versions it will compile, but you must supply both versions in zip file form. My preferred method is to put each in separate folders inside the one zip. That way the effect file can have the same name cross platform, thus reducing the risk of user confusion when the effects are referred to.

Also please give some thought to the titles that you give effects. Something descriptive is good, but not if the name becomes something like "Classic analog TV with intermittent loss of vertical lock and ghosting". "Old TV set" would have to be better. The first would probably not get much further than "Classic analog TV with intermi" when displayed anyway, although I don't know the character limit with effect names. I've never been motivated to test it.

When naming the effect file keep it short - that would be better in OldTV.fx than in my My_custom_effect_to_simulate_early_TV.fx. Always attach the effect files to your post zipped, and in your forum post include a description of what it actually does along with a screen grab showing before and after versions. If you feel that it is necessary you can include a grab of the user interface too. I sometimes do, sometimes don't.

Because the forum software does an abysmal job of scaling images I always scale my screen grabs in Photoshop to 480x270 from 1920x1080 originals and save them as PNG files. In my case they are usually genuine screen grabs, but from time to time I export a frame from Lightworks and use that. Either way works, but for me the screen grab method is faster because I have an action in Photoshop that copies the contents of the clipboard into a new image then scales it to 480x270. I just do a Ctrl-Print Screen to get it to the clipboard and and thus don't have to explicitly open a file. I show the before and after as a split image, usually with a divide between them.

If you supply the grabs in that 480 form I will take care of getting them into both user effects forums.
Last Edit: 8 months ago by jwrl.

Documentation for developing Lightworks effects 1 year, 1 month ago #144363

  • jwrl
  • Moderator
    Pro User
  • OFFLINE
  • Moderator
  • Posts: 8878
  • 1 year, 1 month ago
There's one other thing that I do. I have saved a template file for creating effects. It's undergone some modification since I started doing this, but here's the current version.

//--------------------------------------------------------------//
// Lightworks user effect MyEffect.fx
//
// Created by LW user whoever [DATE]
//
//    ***  PLACE THE DESCRIPTION HERE  ***
//--------------------------------------------------------------//

int _LwksEffectInfo
<
   string EffectGroup = "GenericPixelShader";
   string Description = "...";
   string Category    = "...";
   string SubCategory = "...";
> = 0;

//--------------------------------------------------------------//
// Inputs
//--------------------------------------------------------------//

...

//--------------------------------------------------------------//
// Samplers
//--------------------------------------------------------------//

...

//--------------------------------------------------------------//
// Parameters
//--------------------------------------------------------------//

...

//--------------------------------------------------------------//
// Definitions and declarations
//--------------------------------------------------------------//

...

//--------------------------------------------------------------//
// Functions
//--------------------------------------------------------------//

float2 fn_some_func (...)
{

...

}

//--------------------------------------------------------------//
// Shaders
//--------------------------------------------------------------//

float4 ps_main (...) : COLOR
{

...

}

//--------------------------------------------------------------//
// Techniques
//--------------------------------------------------------------//

technique MyEffect
{
   pass pass_one
   {
      PixelShader = compile PROFILE ps_main ();
   }
}

I'm not suggesting for one moment that this should be slavishly copied by anyone writing FX files. It's just what I do.

I also prefix any functions that I use with fn_, and shaders with ps_ so that it's immediately clear what's going on. If I decide to create a variant of fmod() that always returns a positive result there will be no confusion if my function is called fn_fmod(). That's actually a dumb example, but I suspect that you will get what I mean.

On the subject of functions, it will always be more efficient if you can manage to use as few as possible. The overhead of a function call is actually higher than implementing it as a separate compile pass, or better still, inline code.

Also conditional statements aren't particularly efficient. They will always carry out both branches of the condition, then discard the result they don't need. For this reason I will usually try and structure them so that I can force an exit as the sole result of the true condition. In normal programming this is definitely not the best practice, but here it's a good idea if you can do it. It also means that there is no else condition.

Finally loops will always be unrolled at compile time at least in the Windows compiler. I'm unsure about that for the other two. This has implications for just how much you can build into a loop. It also means that you can't define the exit condition as a variable.

Of the two fragments in the code block below the first will work, the second won't necessarily.

   for (int i = 0; i < 20; i++) {

      // this version works

      }

   for (int i = 0; i < Num; i++) {

      // this version won't work in Windows, will in Mac/Linux

      }

There is a workaround which is very bad programming practice. Cg will not let you execute a break from within a loop, but you can force a return. A conditional evaluation of the end state within the loop will work, but is a workaround at best, and definitely should be avoided. For interest only it would look like this.

   for (int i = 0; i < 20; i++) {

      ...

      if (i >= Num) {
      // optionally do something here, but then exit the shader
      }

      ...

   }
Last Edit: 9 months, 3 weeks ago by jwrl.
Time to create page: 1.29 seconds
Scroll To Top