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
    }
}