diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-13 15:09:36 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-18 09:11:30 +0300 |
commit | 169a4d638c6c1b6634ffcfd19c4fe3cb94cf27d5 (patch) | |
tree | 454810f2e9cc418bae9f1c6716c51c3fae38a968 /src/datavisualization/engine/shaders/texture3d.frag | |
parent | be7bdaa8930caf15fcc58a480d223e0c2b8af6ed (diff) |
Implement volume rendering support
New subclass of QCustom3DItem, QCustom3DVolume is provided.
The documentation for the example will be done in a separate commit.
Change-Id: Idb3fdb0654c6bec7606ca012b75852a5a8412397
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
Diffstat (limited to 'src/datavisualization/engine/shaders/texture3d.frag')
-rw-r--r-- | src/datavisualization/engine/shaders/texture3d.frag | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag new file mode 100644 index 00000000..054b59cb --- /dev/null +++ b/src/datavisualization/engine/shaders/texture3d.frag @@ -0,0 +1,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); +} + |