Sign in to follow this  
jajcek

[HLSL] Generic Blur Shader

Recommended Posts

Hello,

 

I have some blur shader, but honestly it's hardly customizable. I'd like to have it more generic in such way that I set how many neighbours I want to get into calculations. My first attempt was to convert all of the TEXCOORDX into some array, but unfortunately it fails on compile time. What's wrong with it? (of course I have also changed pixel shader in the same way).

 

Vertex shader (before convertion):

 

 

 
cbuffer MatrixBuffer {
    matrix worldMatrix;
    matrix viewMatrix;
    matrix projectionMatrix;
};
 
struct VertexInputType {
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
};
 
struct PixelInputType {
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float2 texCoord1 : TEXCOORD1;
    float2 texCoord2 : TEXCOORD2;
    float2 texCoord3 : TEXCOORD3;
    float2 texCoord4 : TEXCOORD4;
    float2 texCoord5 : TEXCOORD5;
    float2 texCoord6 : TEXCOORD6;
    float2 texCoord7 : TEXCOORD7;
    float2 texCoord8 : TEXCOORD8;
    float2 texCoord9 : TEXCOORD9;
    float2 texCoord10 : TEXCOORD10;
    float2 texCoord11 : TEXCOORD11;
    float2 texCoord12 : TEXCOORD12;
    float2 texCoord13 : TEXCOORD13;
    float2 texCoord14 : TEXCOORD14;
    float2 texCoord15 : TEXCOORD15;
};
 
PixelInputType HorizontalBlurVS( VertexInputType input ) {
    PixelInputType output;
    
    input.position.w = 1.0f;
    output.position = mul( input.position, worldMatrix );
    output.position = mul( output.position, viewMatrix );
    output.position = mul( output.position, projectionMatrix );
    output.tex = input.tex;
    
    float texelSize = 1.0f / 640.0f;
 
    output.texCoord1 = input.tex + float2( texelSize * -7.0f, 0.0f );
    output.texCoord2 = input.tex + float2( texelSize * -6.0f, 0.0f );
    output.texCoord3 = input.tex + float2( texelSize * -5.0f, 0.0f );
    output.texCoord4 = input.tex + float2( texelSize * -4.0f, 0.0f );
    output.texCoord5 = input.tex + float2( texelSize * -3.0f, 0.0f );
    output.texCoord6 = input.tex + float2( texelSize * -2.0f, 0.0f );
    output.texCoord7 = input.tex + float2( texelSize * -1.0f, 0.0f );
    output.texCoord8 = input.tex + float2( 0.0f, 0.0f );
    output.texCoord9 = input.tex + float2( texelSize *  1.0f, 0.0f );
    output.texCoord10 = input.tex + float2( texelSize *  2.0f, 0.0f );
    output.texCoord11 = input.tex + float2( texelSize *  3.0f, 0.0f );
    output.texCoord12 = input.tex + float2( texelSize *  4.0f, 0.0f );
    output.texCoord13 = input.tex + float2( texelSize *  5.0f, 0.0f );
    output.texCoord14 = input.tex + float2( texelSize *  6.0f, 0.0f );
    output.texCoord15 = input.tex + float2( texelSize *  7.0f, 0.0f );
 
    return output;
}

 

Vertex shader (converted):

 

 

 
cbuffer MatrixBuffer {
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
 
struct VertexInputType {
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
};
 
struct PixelInputType {
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float2 texCoord[15] : TEXCOORD1;
};
 
PixelInputType HorizontalBlurVS( VertexInputType input ) {
    PixelInputType output;
 
    input.position.w = 1.0f;
    output.position = mul( input.position, worldMatrix );
    output.position = mul( output.position, viewMatrix );
    output.position = mul( output.position, projectionMatrix );
    output.tex = input.tex;
    
    float texelSize = 1.0f / 640.0f;
 
    output.texCoord[0] = input.tex + float2( texelSize * -7.0f, 0.0f );
    output.texCoord[1] = input.tex + float2( texelSize * -6.0f, 0.0f );
    output.texCoord[2] = input.tex + float2( texelSize * -5.0f, 0.0f );
    output.texCoord[3] = input.tex + float2( texelSize * -4.0f, 0.0f );
    output.texCoord[4] = input.tex + float2( texelSize * -3.0f, 0.0f );
    output.texCoord[5] = input.tex + float2( texelSize * -2.0f, 0.0f );
    output.texCoord[6] = input.tex + float2( texelSize * -1.0f, 0.0f );
    output.texCoord[7] = input.tex + float2( 0.0f, 0.0f );
    output.texCoord[8] = input.tex + float2( texelSize *  1.0f, 0.0f );
    output.texCoord[9] = input.tex + float2( texelSize *  2.0f, 0.0f );
    output.texCoord[10] = input.tex + float2( texelSize *  3.0f, 0.0f );
    output.texCoord[11] = input.tex + float2( texelSize *  4.0f, 0.0f );
    output.texCoord[12] = input.tex + float2( texelSize *  5.0f, 0.0f );
    output.texCoord[13] = input.tex + float2( texelSize *  6.0f, 0.0f );
    output.texCoord[14] = input.tex + float2( texelSize *  7.0f, 0.0f );
 
    return output;
}

Share this post


Link to post
Share on other sites

Don't pass all the offsets as interpolants from the vertex to the pixel shader, but calculate them on the cpu-side and upload them into a constant buffer:

 

 

cbuffer Filter{

   float2 offsets[OFFSETS_COUNT_MAX];
   unit   offsetsCount;
};

PS: for(uint i = 0; i < offsetsCount; ++i) ...

Share this post


Link to post
Share on other sites

I'm sorry but I don't understand it completely. How can I calculate offsets on cpu? The code requires the:

 

input.tex

 

to send the data later to the pixel shader, so where can I get the value with cpu? Sorry if this is stupid question.

 

// ---

 

Is there any other way (without constant buffer)?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this