Postprocessing shaders using FX Composer

If you are reading this, I suppose you already know something about writing Post Processing shaders, but if you don’t, a very good place to start is this page:

Actually, that’s the page from where I learned what I’m showing here. Now, if you know nothing about shaders and you have curiosity, one of the best explained intros to the shader world is here:

Here, I’m basically just pasting some screen caps of my first achievements in PP shaders. I’m still learning how to do this so the stuff is very basic.

Note: The toroid has applied a “normals” shader I am trying, and I skipped the background in all captures but the last one.

Normal Scene


Grayscale with average values
Color value Diagonal
Half Invert, half Blur

To get to this I had some problems to find how exactly set FX Composer to treat the shader as a fullscreen effect, mainly for my reluctance to read the manual, because FX Composer is so intuitive that, why bother reading?

Anyway, here it is:

How to test Fullscreen (postprocessing) shaders in FX Composer.

First, to allow your shader to be droppable into the scene, instead of on an object, add this code:

float Script : STANDARDSGLOBAL <
    string UIWidget = "none";
    string ScriptClass = "scene";
    string ScriptOrder = "postprocess"; //This line sets the shader as PP
    string ScriptOutput = "color";
    string Script = "Technique=Glow2?NAME;"; //This just makes the technique "Name" visible in the assets window.
> = 0.8;

Next, since we need to simulate the scene rendered to a texture coming from the engine, we need to add two textures, binded with some special semantics:

texture2D ScnMap : RENDERCOLORTARGET < //This one should be set by your engine with the result of the first RenderToTexture 
 float2 ViewPortRatio = {1.0,1.0};
 int MipLevels = 1;
 string Format = "X8R8G8B8" ;
 string UIWidget = "None";
sampler2D ScnSamp = sampler_state {
 texture = <ScnMap>;
 AddressU  = CLAMP;
 AddressV = CLAMP;
 float2 ViewPortRatio = {1.0,1.0};
 string Format = "D24S8";
 string UIWidget = "None";

Right below that, some color variables used to clear the viewport:

float4 ClearColor <
    string UIWidget = "color";
    string UIName = "Clear (Bg) Color";
> = {0,0,0,1.0};

float ClearDepth <
    string UIWidget = "None";
> = 1.0;

Finally, on the Techniques section:

technique NAME
      string Script =
    "RenderColorTarget0=ScnMap;" //This sets the "ScnMap" texture as first render target for the FX Composer scene
    "RenderDepthStencilTarget=DepthBuffer;" //This enables "DepthBuffer" texture and is needed except in the final pass
    "Pass=p0;" //A pass of the technique. Another passes should be added in new lines.
      Pass p0
           string Script= "RenderColorTarget0=;" //Since this is the last pass, we are setting the screen (framebuffer) as target.

      VertexShader = compile vs_2_0 VERTEXSHADER(); 
    cullmode = none;
    ZEnable = false;
    ZWriteEnable = false;
    AlphaBlendEnable = false;
      PixelShader = compile ps_2_0 PIXELSHADER(ScnSamp); 

After that,  you can start writing the pixel shader itself. Some pages go directly to the pixel shader, without a vertex shader, but I get errors without it, so I included it.

That’s all for now, but I will keep learning because I want to implement soft shadows and Ambient occlusion in DX Studio. Precisely for that, the next step from here is: Test this shaders in DX Studio, which I’ll try soon and come back with the results.


It works! You can test it HERE (Webplayer).

fxtest webplayer


  • Move: W,A,S,D
  • Camera rotation: Click and hold right mouse button.
  • Move the sliders to change the shader’s effects width and height:

First half: Invert.

Second half top: Normal color with blur.

Second half bottom: No blur, darker color.