summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/shaders/texture3d.frag
blob: 054b59cb5ba1292c5926359aadb8ae8a71081120 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#version 120

varying highp vec3 pos;

uniform highp sampler3D textureSampler;
uniform highp vec3 cameraPositionRelativeToModel;
uniform highp vec4 colorIndex[256];
uniform highp int color8Bit;

const float maxDist = sqrt(2.0);
const int sampleCount = 1024;
const float alphaThreshold = 0.001;
void main() {
    // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1

    // Find out where ray intersects the object
    highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
    highp vec3 invRayDir = 1.0 / rayDir;
    highp vec3 minCorner = vec3(-1.0);
    highp vec3 maxCorner = vec3(1.0);
    highp vec3 t1 = invRayDir * (minCorner - pos);
    highp vec3 t2 = invRayDir * (maxCorner - pos);
    highp vec3 tmin = min(t1, t2);
    highp vec3 tmax = max(t1, t2);
    highp vec2 t = max(tmin.xx, tmin.yz);
    t = min(tmax.xx, tmax.yz);
    float tFar = min(t.x, t.y);
    highp vec3 rayStart = pos;
    // Flip Y and Z so QImage bits work directly for texture and first image is in the front
    rayStart.yz = -rayStart.yz;
    highp vec3 rayStop = pos + rayDir * tFar;
    rayStop.yz = -rayStop.yz;

    // Convert intersections to texture coords
    rayStart = 0.5 * (rayStart + 1.0);
    rayStop = 0.5 * (rayStop + 1.0);

    highp vec3 curPos = rayStart;
    highp float fullDist = distance(rayStop, rayStart);
    highp float stepSize = maxDist / float(sampleCount); // TODO: Stepsize needs to be improved
    highp vec3 step = normalize(rayStop - rayStart) * stepSize;
    highp float totalDist = 0.0;
    highp float totalAlpha = 0.0;
    highp vec4 destColor = vec4(0, 0, 0, 0);
    highp vec4 curColor = vec4(0, 0, 0, 0);
    highp vec3 curRgb = vec3(0, 0, 0);
    highp float curAlpha = 0.0;

    for (int i = 0; i < sampleCount; i++) {
        curColor = texture3D(textureSampler, curPos);
        if (color8Bit != 0)
            curColor = colorIndex[int(curColor.r * 255.0)];

        curAlpha = curColor.a;
        if (curAlpha > alphaThreshold) {
            curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
            destColor.rgb += curRgb;
            totalAlpha += curAlpha;
        }
        curPos += step;
        totalDist += stepSize;
        if (totalDist > fullDist || totalAlpha >= 1.0) {
            break;
        }
    }

    destColor.a = totalAlpha;
    gl_FragColor = clamp(destColor, 0.0, 1.0);
}