uniform float near; uniform float far; uniform sampler2D opaqueDepthTex; uniform vec2 screenRes; uniform float particleSize; float viewDepth(float depth) { #if @reverseZ depth = 1.0 - depth; #endif return (near * far) / ((far - near) * depth - far); } float calcSoftParticleFade() { const float falloffMultiplier = 0.33; const float contrast = 1.30; vec2 screenCoords = gl_FragCoord.xy / screenRes; float sceneDepth = viewDepth(texture2D(opaqueDepthTex, screenCoords).x); float particleDepth = viewDepth(gl_FragCoord.z); float falloff = particleSize * falloffMultiplier; float delta = particleDepth - sceneDepth; if (delta < 0.0) discard; const float shift = 0.845; return shift * pow(clamp(delta/falloff, 0.0, 1.0), contrast); }