This is my first time testing "Soft Particles" so i might be wrong somewhere, but for now it looks good:
OFF
ON
relevant shader parts:
float4 ScreenParams;
...
struct FS_VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
float4 TexCoord1 : TEXCOORD1;
float3 PosWV : TEXCOORD2;
};
struct FS_PS_OUTPUT
{
float4 Color : COLOR0;
};
void VertexProgram(in FS_VERTEX IN, out FS_VS_OUTPUT OUT)
{
float4 oPosition = mul(float4(IN.Position, 1.0f), WorldViewProjection);
OUT.Position = oPosition;
oPosition.x = ((oPosition.x + oPosition.w) * ScreenParams.x + oPosition.w) * ScreenParams.z;
oPosition.y = ((oPosition.w - oPosition.y) * ScreenParams.y + oPosition.w) * ScreenParams.w;
OUT.TexCoord0 = IN.TexCoord0;
OUT.TexCoord1 = oPosition;
OUT.PosWV = mul(float4(IN.Position, 1.0f), WorldView).xyz;
}
// function from NVIDIA sample
float Contrast(float Input, float ContrastPower)
{
#if 1
//piecewise contrast function
bool IsAboveHalf = Input > 0.5 ;
float ToRaise = saturate(2*(IsAboveHalf ? 1-Input : Input));
float Output = 0.5*pow(ToRaise, ContrastPower);
Output = IsAboveHalf ? 1-Output : Output;
return Output;
#else
// another solution to create a kind of contrast function
return 1.0 - exp2(-2*pow(2.0*saturate(Input), ContrastPower));
#endif
}
void PixelProgram(in FS_VS_OUTPUT IN, out FS_PS_OUTPUT OUT)
{
float scene_z = tex2Dproj(DepthSamp, IN.TexCoord1).z;
float particle_z = IN.PosWV.z;
float depthDiff = (scene_z - particle_z);
float fade = Contrast(depthDiff * 0.82f, 2.0f);
float4 color = tex2D(ColorSamp, IN.TexCoord0);
color.a *= fade;
OUT.Color = color;
}
technique tTech2
{
pass p0
{
VertexShader = compile vs_3_0 VertexProgram();
PixelShader = compile ps_3_0 PixelProgram();
ALPHABLENDENABLE = TRUE;
SRCBLEND = SRCALPHA;
DESTBLEND = INVSRCALPHA;
ZWRITEENABLE = FALSE;
}
}
Where ScreenParams is:
D3DXVECTOR4 screenParams((float)WIN_DIM.cx, (float)WIN_DIM.cy, 1.0f / (2.0f * (float)WIN_DIM.cx), 1.0f / (2.0f * (float)WIN_DIM.cy));