TL;DR-version:
- having two techniques: 1st: Horizontal blur of original image; 2nd: Vertical blur of 1st-technique's result => Box Blur
- now I want to add the resulting box blurred image to the original screen. Problem: return origcolor+result*0.3 won't work because origcolor contains the result of pass 1 instead of the original image
-> question: How to sample the original, unmodified pixel when being in a second/third/fourth/... pass? Big thanks in advance and best regards,
Euda
I'm currently trying to acquire some simple skills in writing effect-files for (mainly GTA San Andreas 0.076+) ENBSeries. So I wanted to create a simple bloom effect, based on a box blur added to the original image. Wrote it as a single technique and visually it worked fine whereas the framerate dropped by a vast amount when exceeding ~20px of sampling-radius for the blur (AMD R9 290X).
Here's a screenshot of the result (notice the framerate, sample radius was 64px):
http://image-share.de/images/fd5ce071e8 ... bf344c.png
__
Today - after arriving from a short vacation - I split my code into two passes. The first pass blurs the original image horizontally, the second one blurs the result of pass 1 vertically.
After saving in Notepad++ and alt-tabbing into the game, I recognized a huge fps-gain over my previous method:
http://image-share.de/images/1201d246b3 ... b38cce.png
respectively (+MRTRendering, -UseWater): http://image-share.de/images/a3fb997754 ... 19f7de.png
__
Subsequently, to "transform" that method from a blur-shader into a bloom-shader, I'd be required to add the blurred result to the original, pre-postprocessing-image - which is when my problem kicked in
I'm lacking any idea on how to sample a pixel of the original image in my second pass.
To simply add the blur by a low percentage instead of completely returning it to the screen, I'd have to output the original image in my second pass + the blur-result * 0.3 for example. Tried this, but it literally sampled a pixel of the horizontally blurred image instead of one of the original image without any blur.
Here are the two effect-files (San Andreas ENBSeries 0.076), single- and multipass:
Code: Select all
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ENBSeries effect file
// http://enbdev.com
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//THIS IS HLSL FILE FORMAT FOR EXECUTING ADDITIONAL
//POST PROCESSING EFFECTS. MAKE THE COPY BEFORE CHANGING IT!
//WARNING! This is new standart file, compatible with ENBSeries 0.101 or better
//+++++++++++++++++++++++++++++
//external parameters, do not modify
//+++++++++++++++++++++++++++++
//keyboard controlled temporary variables (in some versions exists in the config file). Press and hold key 1,2,3...8 together with PageUp or PageDown to modify. By default all set to 1.0
float4 tempF1; //0,1,2,3
float4 tempF2; //5,6,7,8
float4 tempF3; //9,0
//x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4 Timer;
//x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
float4 ScreenSize;
texture2D texColor;
texture2D texDepth;
texture2D texNoise;
sampler2D SamplerColor = sampler_state
{
Texture = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerDepth = sampler_state
{
Texture = <texDepth>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerNoise = sampler_state
{
Texture = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;
AddressU = Wrap;
AddressV = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
struct VS_OUTPUT_POST
{
float4 vpos : POSITION;
float2 txcoord : TEXCOORD0;
};
struct VS_INPUT_POST
{
float3 pos : POSITION;
float2 txcoord : TEXCOORD0;
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Vertex-Shader
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
VS_OUTPUT_POST OUT;
float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);
OUT.vpos=pos;
OUT.txcoord.xy=IN.txcoord.xy;
return OUT;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pixel-Shader
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float4 PS_Process(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res; // result
float4 origcolor = tex2D(SamplerColor, IN.txcoord.xy);
res.xyz = origcolor.xyz;
res.w = 1.0;
float2 actPos = IN.txcoord.xy;
float2 posi = actPos;
float3 samples;
float multip = 1; // skipped samples per loop-cycle
int sc = 64; // sample count => quality
for (float m=1; m<sc; m++)
{
for (float j=1; j<sc; j++)
{
posi=actPos;
posi.y += multip * m * ScreenSize.y;
posi.x += multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
posi=actPos;
posi.y += multip * m * ScreenSize.y;
posi.x -= multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
posi=actPos;
posi.y -= multip * m * ScreenSize.y;
posi.x += multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
posi=actPos;
posi.y -= multip * m * ScreenSize.y;
posi.x -= multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
}
}
samples.xyz /= sc*sc*2;
res.xyz = samples.xyz;
return res;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
technique PostProcess
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_Process();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
Code: Select all
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ENBSeries effect file
// http://enbdev.com
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//WARNING! This is new standart file, compatible with ENBSeries 0.101 or better
//+++++++++++++++++++++++++++++
//external parameters, do not modify
//+++++++++++++++++++++++++++++
//keyboard controlled temporary variables (in some versions exists in the config file). Press and hold key 1,2,3...8 together with PageUp or PageDown to modify. By default all set to 1.0
float4 tempF1; //0,1,2,3
float4 tempF2; //5,6,7,8
float4 tempF3; //9,0
//x=generic timer in range 0..1, period of 16777216 ms (4.6 hours), w=frame time elapsed (in seconds)
float4 Timer;
//x=Width, y=1/Width, z=ScreenScaleY, w=1/ScreenScaleY
float4 ScreenSize;
texture2D texColor;
texture2D texDepth;
texture2D texNoise;
sampler2D SamplerColor = sampler_state
{
Texture = <texColor>;
MinFilter = LINEAR;
MagFilter = LINEAR;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerDepth = sampler_state
{
Texture = <texDepth>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;
AddressU = Clamp;
AddressV = Clamp;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
sampler2D SamplerNoise = sampler_state
{
Texture = <texNoise>;
MinFilter = POINT;
MagFilter = POINT;
MipFilter = NONE;
AddressU = Wrap;
AddressV = Wrap;
SRGBTexture=FALSE;
MaxMipLevel=0;
MipMapLodBias=0;
};
struct VS_OUTPUT_POST
{
float4 vpos : POSITION;
float2 txcoord : TEXCOORD0;
};
struct VS_INPUT_POST
{
float3 pos : POSITION;
float2 txcoord : TEXCOORD0;
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Vertex-Shader
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
VS_OUTPUT_POST OUT;
float4 pos=float4(IN.pos.x,IN.pos.y,IN.pos.z,1.0);
OUT.vpos=pos;
OUT.txcoord.xy=IN.txcoord.xy;
return OUT;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pixel-Shader || Horizontal Blur
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float4 PS_Process(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res; // result
float4 origcolor = tex2D(SamplerColor, IN.txcoord.xy);
res.w = 1.0;
float2 actPos = IN.txcoord.xy;
float2 posi = actPos;
float3 samples;
float multip = 1; // skipped samples per loop-cycle
int sc = 64; // sample amount => quality
for (float j=1; j<sc; j++)
{
posi=actPos;
posi.x += multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
posi=actPos;
posi.x -= multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
}
samples.xyz /= sc;
res.xyz = samples.xyz;
// todo: VIBRANCE!
int compareMode = 0; // splitscreen comparison
if (compareMode == 1)
{
if (actPos.x < 0.5) return origcolor;
else return res;
}
else return res;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Pixel-Shader || Vertical Blur
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
float4 PS_Passb(VS_OUTPUT_POST IN, float2 vPos : VPOS) : COLOR
{
float4 res; // result
float4 origcolor = tex2D(SamplerColor, IN.txcoord.xy);
res.w = 1.0;
float2 actPos = IN.txcoord.xy;
float2 posi = actPos;
float3 samples;
float multip = 1; // skipped samples per loop-cycle
int sc = 64; // sample count => quality
for (float j=1; j<sc; j++)
{
posi=actPos;
posi.y += multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
posi=actPos;
posi.y -= multip * j * ScreenSize.y;
samples.xyz+=tex2D(SamplerColor, posi.xy);
}
samples.xyz /= sc*2;
res.xyz = samples.xyz;
int compareMode = 0; // splitscreen comparison
if (compareMode == 1)
{
if (actPos.x < 0.5) return origcolor;
else return res;
}
else return res;
[b]// else return origcolor+res*0.3 --> That's my problem - origcolor would have to be a sample of the original pixel, rather than a sample of PS_Process' result: A horizontal blurred pixel. :/[/b]
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Techniques
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
technique PostProcess
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_Process();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
technique PostProcess2
{
pass P0
{
VertexShader = compile vs_3_0 VS_PostProcess();
PixelShader = compile ps_3_0 PS_Passb();
DitherEnable=FALSE;
ZEnable=FALSE;
CullMode=NONE;
ALPHATESTENABLE=FALSE;
SEPARATEALPHABLENDENABLE=FALSE;
AlphaBlendEnable=FALSE;
StencilEnable=FALSE;
FogEnable=FALSE;
SRGBWRITEENABLE=FALSE;
}
}
Finally, I hope that I've provided you guys with enough information and described my issue as precise as possible, I'm thankful for any help and currently idealess after 2 hours of testing and combining different ways to fix my problem.
Thanks in advance,
Euda