I found a solution (and modification of the engine is not required)
CoreData\RenderPaths\ForwardHWDepth_SoftParticles.xml (based on ForwardHWDepth)
<renderpath>
<rendertarget name="depth" sizedivisor="1 1" format="readabledepth" />
<command type="clear" depth="1.0" output="depth" />
<command type="scenepass" pass="shadow" output="depth" />
<command type="clear" color="fog" depthstencil="depth" />
<command type="scenepass" pass="base" vertexlights="true" metadata="base" depthstencil="depth" />
<command type="forwardlights" pass="light" depthstencil="depth" />
<command type="scenepass" pass="postopaque" depthstencil="depth" />
<command type="scenepass" pass="refract" depthstencil="depth">
<texture unit="environment" name="viewport" />
</command>
<command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" depthstencil="depth" />
<command type="scenepass" pass="postalpha" sort="backtofront" depthstencil="depth" />
<!-- Render SoftParticles -->
<command type="scenepass" pass="softparticles" vertexlights="true" sort="backtofront" metadata="alpha" blend="replace" output="viewport">
<texture unit="depth" name="depth" />
</command>
</renderpath>
CoreData\Shaders\GLSL\UnlitSP.glsl (based on unlit)
#include "Uniforms.glsl"
#include "Samplers.glsl"
#include "Transform.glsl"
#include "ScreenPos.glsl"
#include "Fog.glsl"
varying vec2 vTexCoord;
varying vec4 vWorldPos;
varying vec4 vScreenPos;
#ifdef VERTEXCOLOR
varying vec4 vColor;
#endif
void VS()
{
mat4 modelMatrix = iModelMatrix;
vec3 worldPos = GetWorldPos(modelMatrix);
gl_Position = GetClipPos(worldPos);
vTexCoord = GetTexCoord(iTexCoord);
vWorldPos = vec4(worldPos, GetDepth(gl_Position));
vScreenPos = GetScreenPos(gl_Position);
#ifdef VERTEXCOLOR
vColor = iColor;
#endif
}
void PS()
{
// Get material diffuse albedo
#ifdef DIFFMAP
vec4 diffColor = cMatDiffColor * texture2D(sDiffMap, vTexCoord);
#ifdef ALPHAMASK
if (diffColor.a < 0.5)
discard;
#endif
#else
vec4 diffColor = cMatDiffColor;
#endif
#ifdef VERTEXCOLOR
diffColor *= vColor;
#endif
// Get fog factor
#ifdef HEIGHTFOG
float fogFactor = GetHeightFogFactor(vWorldPos.w, vWorldPos.y);
#else
float fogFactor = GetFogFactor(vWorldPos.w);
#endif
#if defined(PREPASS)
// Fill light pre-pass G-Buffer
gl_FragData[0] = vec4(0.5, 0.5, 0.5, 1.0);
gl_FragData[1] = vec4(EncodeDepth(vWorldPos.w), 0.0);
#elif defined(DEFERRED)
gl_FragData[0] = vec4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
gl_FragData[1] = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragData[2] = vec4(0.5, 0.5, 0.5, 1.0);
gl_FragData[3] = vec4(EncodeDepth(vWorldPos.w), 0.0);
#else
float particleDepth = vWorldPos.w;
float solidGeometrydepth = ReconstructDepth(texture2DProj(sDepthBuffer, vScreenPos).r); // use ReconstructDepth when HWDEPTH
if (solidGeometrydepth <= particleDepth)
{
float deltaDepth = (particleDepth - solidGeometrydepth) * 1000;
diffColor.a -= deltaDepth;
}
gl_FragColor = vec4(GetFog(diffColor.rgb, fogFactor), diffColor.a);
#endif
}
CoreData\Techniques\DiffVColUnlitAlphaSP.xml (based on DiffVColUnlitAlpha)
<technique vs="UnlitSP" ps="UnlitSP" vsdefines="VERTEXCOLOR SP" psdefines="DIFFMAP VERTEXCOLOR SP">
<pass name="softparticles" depthtest="always" depthwrite="false" blend="alpha" />
</technique>
Data\Materials\SmokeSoftParticle.xml (based on Smoke)
<material>
<technique name="Techniques/DiffVColUnlitAlphaSP.xml" />
<texture unit="diffuse" name="Textures/Smoke.dds" />
</material>
Data\Particle\SmokeStackSoftParticle.xml (based on Smoke)
<?xml version="1.0"?>
<particleeffect>
<material name="Materials/SmokeSoftParticle.xml" />
<numparticles value="1000" />
<updateinvisible enable="true" />
<relative enable="false" />
<scaled enable="true" />
<sorted enable="true" />
<animlodbias value="0" />
<emittertype value="Box" />
<emittersize value="1 1 1" />
<direction min="-0.15 1 -0.15" max="0.15 1 0.15" />
<constantforce value="0 2 0" />
<dampingforce value="2" />
<activetime value="0" />
<inactivetime value="0" />
<emissionrate min="100" max="200" />
<particlesize min="0.1 0.2" max="0.6 0.7" />
<timetolive min="4" max="4" />
<velocity min="0.5" max="3" />
<rotation min="0" max="0" />
<rotationspeed min="60" max="60" />
<sizedelta add="0" mul="1.3" />
<colorfade color="1 1 1 0" time="0" />
<colorfade color="0.69 0.33 0.2 0.5" time="0.64" />
<colorfade color="0 0 0 0" time="1.98" />
<colorfade color="0 0 0 0" time="4" />
</particleeffect>
Old:
New: