/** * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Gianluca Tomasello */ export const dpoit_write = ` #if defined(dRenderVariant_colorDpoit) if (uRenderMask == MaskOpaque) { if (preFogAlpha < 1.0) { discard; } } else if (uRenderMask == MaskTransparent) { // the 'fragmentDepth > 0.99' check is to handle precision issues with packed depth vec2 coords = gl_FragCoord.xy / uDrawingBufferSize; if (preFogAlpha != 1.0 && (fragmentDepth < getDepth(coords) || fragmentDepth > 0.99)) { #ifdef dTransparentBackfaces_off if (interior) discard; #endif // adapted from https://github.com/tsherif/webgl2examples // The MIT License, Copyright 2017 Tarek Sherif, Shuai Shao vec2 lastDepth = texture2D(tDpoitDepth, coords).rg; vec4 lastFrontColor = texture2D(tDpoitFrontColor, coords); vec4 fragColor = gl_FragColor; // depth value always increases // so we can use MAX blend equation gl_FragData[2].rg = vec2(-MAX_DPOIT_DEPTH); // front color always increases // so we can use MAX blend equation gl_FragColor = lastFrontColor; // back color is separately blend afterwards each pass gl_FragData[1] = vec4(0.0); float nearestDepth = - lastDepth.x; float furthestDepth = lastDepth.y; float alphaMultiplier = 1.0 - lastFrontColor.a; if (fragmentDepth < nearestDepth || fragmentDepth > furthestDepth) { // Skip this depth since it's been peeled. return; } if (fragmentDepth > nearestDepth && fragmentDepth < furthestDepth) { // This needs to be peeled. // The ones remaining after MAX blended for // all need-to-peel will be peeled next pass. gl_FragData[2].rg = vec2(-fragmentDepth, fragmentDepth); return; } // write to back and front color buffer if (fragmentDepth == nearestDepth) { gl_FragColor.rgb += fragColor.rgb * fragColor.a * alphaMultiplier; gl_FragColor.a = 1.0 - alphaMultiplier * (1.0 - fragColor.a); } else { gl_FragData[1] += fragColor; } } else { discard; } } #endif `;