/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2021 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #version __CONTEXT__ #include "resolveconstants.glsl" #include "abufferfragment.glsl" #include "abufferresources.glsl" #include "fragment.glsl" #include "floatoperations.glsl" #include "blending.glsl" #include "rand.glsl" layout (location = 0) out vec4 finalColor; uniform float blackoutFactor; uniform sampler2DMS mainColorTexture; uniform sampler2DMS mainDepthTexture; uniform float gamma = 1.0; #include "resolvehelpers.glsl" void main() { // TODO: disable multisampling for main fbo. float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); // RGB color values, premultiplied with alpha channels. vec3 accumulatedColor = vec3(0.0); // One alpha channel per color channel to allow for // absorption of different wavelengths. // Always within the interval [0, 1] vec3 accumulatedAlpha = vec3(0.0); uint nOriginalFrags = loadFragments(); uint raycasterMask = 0; uint nFilteredFrags = nOriginalFrags; // discard all fragments in abuffer with higher depth value than the fbo nFilteredFrags = depthFilterFragments(nOriginalFrags, fboDepth); // sort remaining fragments from front to back sortFragments(nFilteredFrags); // merge fragments whose sample masks don't igntersect // to get the correct alpha for fragments on borders between triangles uint nFrags = mergeFragments(nFilteredFrags); #if STORE_SORTED //storeFragments(nFrags); #endif #if RAYCASTING_ENABLED retrieveRaycasterData(nFrags); #if RAYCASTING_ENABLED bool insideAnyRaycaster = initRaycasterMask(raycasterMask); #endif //debugColor = vec4(raycasterData[0].direction, 1.0); if (insideAnyRaycaster) { //raycast to the first fragment // discard; float startDepth = 0; float endDepth = min(_depth_(fragments[0]), fboDepth); raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); //accumulatedColor = vec3(1.0); } #endif for (uint i = 0; i < nFrags; i++) { ABufferFragment frag = fragments[i]; int type = _type_(frag); uint blend = _blend_(frag); if (type == 0) { // geometry fragment vec4 color = _color_(frag); color.rgb = pow(color.rgb, vec3(gamma)); if (blend == BLEND_MODE_NORMAL) { accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; accumulatedAlpha += (1 - accumulatedAlpha) * color.aaa; //normalBlend(finalColor, color); } else if (blend == BLEND_MODE_ADDITIVE) { accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; //additiveBlend(finalColor, color); } } #if RAYCASTING_ENABLED else if (type > 0) { // enter volume int raycasterId = type - 1; //accumulatedColor += (1 - accumulatedAlpha) * _position_(frag); // only enter volume if a valid scale was detected if (raycasterData[raycasterId].scale > 0) { raycasterMask |= (1 << (raycasterId)); } } else { // exit volume int raycasterId = -type - 1; raycasterMask &= INT_MAX - (1 << (raycasterId)); //accumulatedColor = vec3(1.0); //accumulatedColor += (1 - accumulatedAlpha) * _position_(frag); } // Ray cast to next fragment if (i + 1 < nFrags && raycasterMask != 0) { float startDepth = _depth_(fragments[i]); float endDepth = min(_depth_(fragments[i + 1]), fboDepth); if (endDepth < startDepth) { break; } raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); } #endif } accumulatedAlpha = clamp(accumulatedAlpha, 0.0, 1.0); //maccumulatedAlpha = vec3(0.0); accumulatedColor += (1 - accumulatedAlpha) * pow(fboRgba.rgb, vec3(gamma)); finalColor = vec4(accumulatedColor.rgb, 1.0); // Gamma correction. finalColor.rgb = pow(finalColor.rgb, vec3(1.0 / gamma)); // Black out factor. finalColor = vec4(finalColor.rgb * blackoutFactor, 1.0); //finalColor = vec4(vec3(fboRgba.a), 1.0); //finalColor = fboRgba; //finalColor = vec4(0.0); //finalColor = vec4(0.0, acc/1000.0, acc/1000.0, 1.0); //finalColor = vec4(acc/1000.0, 0.0, 0.0, 01.0); //finalColor = vec4(vec3(float(nFrags) / 10), 1.0); //finalColor = vec4(vec3(float(_depth_(fragments[0])) / 10), 1.0); //finalColor = vec4(vec3(nFilteredFrags - nFrags) * 0.2, 1.0); //finalColor = vec4(vec3(nFilteredFrags) * 0.2, 1.0); //finalColor = vec4(vec3(nFrags) * 0.05, 1.0); //finalColor = vec4(raycasterData[0].position, 1.0); //finalColor = debugColor; //finalColor = vec4(gamma * 0.5); //finalColor = vec4(fboRgba); }