I would like to implement dual depth peeling in my engine. I read the original paper and examined the corresponding source code. I understand the algorithm, except how the blending works, especially in the front-to-back part. I'm so confused now, I'm not sure anything about alpha blending.
So let's start with the basics. I think there are two options: either we compute the pixel's color and it's transparency and store them separately (straight), or we multiply them and then we don't use the alpha channel's value (premultiplied alpha). The second option is what we usually do when we set glBlendFunc's parameters to GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. When we blend two pixels, the GPU multiplies the source color with the source alpha and it multiplies the destination color with (1 - source alpha). We don't multiply the destination color with the destination alpha because basically it's already multiplied with it. So we assume the destination alpha is 1 (and also the destination alpha is not correct, because of the GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA parameters, so we can't use it anyways). Am I right so far?
At this point the back-to-front part of the dual depth peeling makes sense to me. In dual_peeling_peel_fragment.glsl we just store the color with the alpha (we can't blend it yet because we have to use max blending in this shader).
void main(void) { ... gl_FragData[2] = vec4(0.0); ... if (fragDepth == nearestDepth) { ... } else { gl_FragData[2] += color; } } Then in the dual_peeling_blend_fragment.glsl shader we just blend it with the background.
void main(void) { gl_FragColor = textureRect(TempTex, gl_FragCoord.xy); ... } Here we use additive blending with the already mentioned parameters which makes sense to me.
But when we compute the front-to-back part in dual_peeling_peel_fragment.glsl, I don't understand the code.
void main(void) { ... vec4 forwardTemp = textureRect(FrontBlenderTex, gl_FragCoord.xy); ... gl_FragData[1] = forwardTemp; ... float alphaMultiplier = 1.0 - forwardTemp.w; ... vec4 color = ShadeFragment(); ... if (fragDepth == nearestDepth) { gl_FragData[1].xyz += color.rgb * color.a * alphaMultiplier; gl_FragData[1].w = 1.0 - alphaMultiplier * (1.0 - color.a); } else { ... } } Here we compute the color value and multiply it with some alpha values and we also compute the alpha. I don't see where these equations come from. We don't modify the destination color (which is the nearer), but we multiply the source color with the source alpha and with (1 - destination alpha). And then we also compute the alpha value. So this not straight neither premultiplied. Also in the paper they use slightly different equations in page 6. 
Where the paper multiplies with destination alpha the source code multiplies with (1 - destination alpha). I found a blog post where the author is also confused about that.
And then, at the end in dual_peeling_final_fragment.glsl we blend together the back-to-front part with the front-to-back part.
void main(void) { vec4 frontColor = textureRect(FrontBlenderTex, gl_FragCoord.xy); vec3 backColor = textureRect(BackBlenderTex, gl_FragCoord.xy).rgb; float alphaMultiplier = 1.0 - frontColor.w; gl_FragColor.rgb = frontColor + backColor * alphaMultiplier; } But I don't understand why we only multiply the back part with (1 - front part alpha). In this part we use additive blending.