11.3.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

drrraycaster.frag 5.48 KB
Newer Older
1 2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4 5
// 
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7 8 9
//      Chair for Computer Aided Medical Procedures
//      Technische Universität München
//      Boltzmannstr. 3, 85748 Garching b. München, Germany
schultezub's avatar
schultezub committed
10
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
// 
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
// 
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// 
// ================================================================================================

30 31
out vec4 out_Color;         ///< outgoing fragment color

schultezub's avatar
schultezub committed
32
#include "tools/raycasting.frag"
schultezub's avatar
schultezub committed
33 34 35 36 37
#include "tools/texture2d.frag"
#include "tools/texture3d.frag"
#include "tools/transferfunction.frag"

uniform vec2 _viewportSizeRCP;
38
uniform float _jitterStepSizeMultiplier;
schultezub's avatar
schultezub committed
39

40 41 42
// ray entry points
uniform sampler2D _entryPoints;
uniform TextureParameters2D _entryParams;
schultezub's avatar
schultezub committed
43

44 45 46 47 48 49 50 51 52 53 54
// ray exit points
uniform sampler2D _exitPoints;
uniform TextureParameters2D _exitParams;

// DRR volume
uniform sampler3D _volume;
uniform TextureParameters3D _volumeTextureParams;

// Transfer function
uniform sampler1D _transferFunction;
uniform TFParameters1D _transferFunctionParams;
schultezub's avatar
schultezub committed
55 56 57 58 59 60 61 62

uniform float _samplingStepSize;
uniform float _shift;
uniform float _scale;

// TODO: copy+paste from Voreen - eliminate or improve.
const float SAMPLING_BASE_INTERVAL_RCP = 200.0;

schultezub's avatar
schultezub committed
63 64 65 66
/**
 * Computes the DRR by simple raycasting and returns the final fragment color.
 */
vec4 raycastDRR(in vec3 entryPoint, in vec3 exitPoint) {
schultezub's avatar
schultezub committed
67 68 69
    vec4 result = vec4(0.0);

    // calculate ray parameters
schultezub's avatar
schultezub committed
70
    vec3 direction = exitPoint.rgb - entryPoint.rgb;
schultezub's avatar
schultezub committed
71
    float t = 0.0;
schultezub's avatar
schultezub committed
72
    float tend = length(direction);
schultezub's avatar
schultezub committed
73 74
    direction = normalize(direction);

75
    jitterEntryPoint(entryPoint, direction, _samplingStepSize * _jitterStepSizeMultiplier);
schultezub's avatar
schultezub committed
76

schultezub's avatar
schultezub committed
77
    while (t < tend) {
schultezub's avatar
schultezub committed
78
        // compute sample position
schultezub's avatar
schultezub committed
79
        vec3 samplePosition = entryPoint.rgb + t * direction;
schultezub's avatar
schultezub committed
80 81

        // lookup intensity and TF
82
        float intensity = texture(_volume, samplePosition).r;
83
        vec4 color = lookupTF(_transferFunction, _transferFunctionParams, intensity);
schultezub's avatar
schultezub committed
84 85

#ifdef DEPTH_MAPPING
schultezub's avatar
schultezub committed
86 87
        // use Bernstein Polynomials for depth-color mapping
        float depth = t / tend;
schultezub's avatar
schultezub committed
88
            
schultezub's avatar
schultezub committed
89 90 91
        float b02 = (1-depth) * (1-depth);
        float b12 = 2 * depth * (1-depth);
        float b22 = depth * depth;
schultezub's avatar
schultezub committed
92
            
schultezub's avatar
schultezub committed
93
        color = vec4(0.75*b02 + 0.25*b12, b12, 0.25*b12 + 0.75*b22, 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP));
schultezub's avatar
schultezub committed
94
/*            float t_sq = depth * depth;
schultezub's avatar
schultezub committed
95 96 97 98 99 100 101 102
        float inv_t_sq = (1-depth) * (1-depth);
        float b04 = inv_t_sq * inv_t_sq;
        float b24 = 6 * t_sq * inv_t_sq;
        float b44 = t_sq * t_sq;
        color = vec4(0.5*b04 + 0.5*b24, b24, 0.5*b24 + 0.5*b44, 1.0 - pow(1.0 - color.a, samplingStepSize_ * SAMPLING_BASE_INTERVAL_RCP));*/

        result.rgb = result.rgb + (1.0 - result.a) * color.a * color.rgb;
        result.a = result.a + color.a * _scale;
schultezub's avatar
schultezub committed
103
#else
schultezub's avatar
schultezub committed
104 105 106
        // perform compositing (account for differen step size / sampling rate)
        color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP);
        result.a = result.a + color.a * _scale;
schultezub's avatar
schultezub committed
107 108
#endif       

schultezub's avatar
schultezub committed
109
        t += _samplingStepSize;
schultezub's avatar
schultezub committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
    }

#ifdef DEPTH_MAPPING
    result.rgb = result.rgb * vec3(exp(-result.a + _shift));
    //result.rgb = exp(-result.rgb * result.a + shift_);
#else
#ifdef DRR_INVERT
    // apply e-function, as we want the "negative" X-Ray image, we invert the intensity result
    result.rgb = 1 - vec3(exp(-result.a + _shift));
#else
    // apply e-function, the normal way
    result.rgb = vec3(exp(-result.a + _shift));
#endif
#endif
    result.a = 1.0;
    return result;
}

/***
 * The main method.
 ***/
void main() {
    vec2 p = gl_FragCoord.xy * _viewportSizeRCP;
133 134
    vec3 frontPos = texture(_entryPoints, p).rgb;
    vec3 backPos = texture(_exitPoints, p).rgb;
schultezub's avatar
schultezub committed
135 136 137 138 139 140 141

    //determine whether the ray has to be casted
    if (frontPos == backPos) {
        //background need no raycasting
        discard;
    } else {
        //fragCoords are lying inside the boundingbox
142
        out_Color = raycastDRR(frontPos, backPos);
schultezub's avatar
schultezub committed
143 144
    }
}