uniform sampler2DArray ColorLayers; uniform sampler2DArray DepthLayers; void main() { const int layerCount = 6; vec4 vColor[layerCount]; float vDepth[layerCount]; int vSurfOrder[layerCount]; int i = 0; // Calculate un-normalized texture coordinates vec2 tmp = floor(textureSize(DepthLayers, 0).xy * gl_TexCoord[0].st); // First, get sample data and init the surface order for (i = 0; i < layerCount; i++) { vSurfOrder[i] = i; vColor[i] = texelFetch(ColorLayers, ivec3(tmp, i), 0); vDepth[i] = texelFetch(DepthLayers, ivec3(tmp, i), 0).r; } // Sort depth values, largest to front and smallest to back // Must run through array (size^2-size) times, or early-exit // if any pass shows all samples to be in order for (int j = 0; j < layerCount; j++) { bool bFinished = true; for (i = 0; i < (layerCount-1); i++) { float temp1 = vDepth[vSurfOrder[i]]; float temp2 = vDepth[vSurfOrder[i+1]]; if (temp2 < temp1) { // swap values int tempIndex = vSurfOrder[i]; vSurfOrder[i] = vSurfOrder[i+1]; vSurfOrder[i+1] = tempIndex; bFinished = false; } } if (bFinished) j = layerCount; } // Now, sum all colors in order from front to back. Apply alpha. bool bFoundFirstColor = false; vec4 summedColor = vec4(0.0, 0.0, 0.0, 0.0); for (i = (layerCount-1); i >= 0; i--) { int surfIndex = vSurfOrder[i]; if(vColor[surfIndex].a > 0.001) { if (bFoundFirstColor == false) { // apply 100% of the first color summedColor = vColor[surfIndex]; bFoundFirstColor = true; } else { // apply color with alpha summedColor.rgb = (summedColor.rgb * (1.0 - vColor[surfIndex].a)) + (vColor[surfIndex].rgb * vColor[surfIndex].a); } } } gl_FragColor = vec4(summedColor.rgb, 1.0); }