summaryrefslogtreecommitdiffstats
path: root/src/datavisualization/engine/shaders
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-09 11:30:15 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-09-10 12:30:54 +0300
commitddb9be979d93b7e17f1067dc6056de54d9828b29 (patch)
treedf612c56e4a804481297ae55b29f0ee379c5f8ab /src/datavisualization/engine/shaders
parentbb30ea555c71604de9a2bc5096fa35c9532b26bd (diff)
Limit volume to axis ranges
The volume object that would go partially outside axis ranges is scale and repositioned so that it only renders the portion that is inside the axis ranges. Change-Id: I792494e437998ba6276f58fab645767276c1476d Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src/datavisualization/engine/shaders')
-rw-r--r--src/datavisualization/engine/shaders/texture3d.frag64
-rw-r--r--src/datavisualization/engine/shaders/texture3d.vert26
-rw-r--r--src/datavisualization/engine/shaders/texture3dlowdef.frag64
-rw-r--r--src/datavisualization/engine/shaders/texture3dslice.frag97
4 files changed, 135 insertions, 116 deletions
diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag
index 460cbcc6..3f9c42ff 100644
--- a/src/datavisualization/engine/shaders/texture3d.frag
+++ b/src/datavisualization/engine/shaders/texture3d.frag
@@ -1,15 +1,17 @@
#version 120
varying highp vec3 pos;
+varying highp vec3 rayDir;
uniform highp sampler3D textureSampler;
-uniform highp vec3 cameraPositionRelativeToModel;
uniform highp vec4 colorIndex[256];
uniform highp int color8Bit;
uniform highp vec3 textureDimensions;
uniform highp int sampleCount; // This is the maximum sample count
uniform highp float alphaMultiplier;
uniform highp int preserveOpacity;
+uniform highp vec3 minBounds;
+uniform highp vec3 maxBounds;
// Ray traveling straight through a single 'alpha thickness' applies 100% of the encountered alpha.
// Rays traveling shorter distances apply a fraction. This is used to normalize the alpha over
@@ -17,51 +19,38 @@ uniform highp int preserveOpacity;
const highp float alphaThicknesses = 32.0;
void main() {
- highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
vec3 rayStart = pos;
- // Flip Y and Z so QImage bits work directly for texture and first image is in the front
- rayDir.yz = -rayDir.yz;
- rayStart.yz = -rayStart.yz;
- // Calculate ray intersection endpoint
- vec3 rayStop;
- if (rayDir.x == 0.0) {
- rayStop.yz = rayStart.yz;
- rayStop.x = -rayStart.x;
- } else if (rayDir.y == 0.0) {
- rayStop.xz = rayStart.xz;
- rayStop.y = -rayStart.y;
- } else if (rayDir.z == 0.0) {
- rayStop.xy = rayStart.xy;
- rayStop.z = -rayStart.z;
- } else {
- highp vec3 boxBounds = vec3(1.0, 1.0, 1.0);
- highp vec3 invRayDir = 1.0 / rayDir;
- if (rayDir.x < 0)
- boxBounds.x = -1.0;
- if (rayDir.y < 0)
- boxBounds.y = -1.0;
- if (rayDir.z < 0)
- boxBounds.z = -1.0;
- highp vec3 t = (boxBounds - rayStart) * invRayDir;
- highp float minT = min(t.x, min(t.y, t.z));
- rayStop = rayStart + minT * rayDir;
+ highp vec3 startBounds = minBounds;
+ highp vec3 endBounds = maxBounds;
+ if (rayDir.x < 0.0) {
+ startBounds.x = maxBounds.x;
+ endBounds.x = minBounds.x;
+ }
+ if (rayDir.y > 0.0) {
+ startBounds.y = maxBounds.y;
+ endBounds.y = minBounds.y;
+ }
+ if (rayDir.z > 0.0) {
+ startBounds.z = maxBounds.z;
+ endBounds.z = minBounds.z;
}
+ // Calculate ray intersection endpoint
+ highp vec3 rayStop;
+ highp vec3 invRayDir = 1.0 / rayDir;
+ highp vec3 t = (endBounds - rayStart) * invRayDir;
+ highp float endT = min(t.x, min(t.y, t.z));
+ rayStop = rayStart + endT * rayDir;
+ if (endT <= 0.0)
+ discard;
+
// Convert intersections to texture coords
rayStart = 0.5 * (rayStart + 1.0);
rayStop = 0.5 * (rayStop + 1.0);
highp vec3 ray = rayStop - rayStart;
- // Avoid artifacts from divisions by zero
- if (ray.x == 0)
- ray.x = 0.000000001;
- if (ray.y == 0)
- ray.y = 0.000000001;
- if (ray.z == 0)
- ray.z = 0.000000001;
-
highp vec3 absRay = abs(ray);
highp vec3 invAbsRay = 1.0 / absRay;
highp float fullDist = length(ray);
@@ -154,6 +143,9 @@ void main() {
break;
}
+ if (totalOpacity == 1.0)
+ discard;
+
// Brighten up the final color if there is some transparency left
if (totalOpacity >= 0.0 && totalOpacity < 1.0)
destColor *= (1.0 - (totalOpacity * 0.5)) / (1.0 - totalOpacity);
diff --git a/src/datavisualization/engine/shaders/texture3d.vert b/src/datavisualization/engine/shaders/texture3d.vert
index cad1ce06..ef3f1b25 100644
--- a/src/datavisualization/engine/shaders/texture3d.vert
+++ b/src/datavisualization/engine/shaders/texture3d.vert
@@ -1,12 +1,36 @@
uniform highp mat4 MVP;
+uniform highp vec3 minBounds;
+uniform highp vec3 maxBounds;
+uniform highp vec3 cameraPositionRelativeToModel;
attribute highp vec3 vertexPosition_mdl;
attribute highp vec2 vertexUV;
attribute highp vec3 vertexNormal_mdl;
varying highp vec3 pos;
+varying highp vec3 rayDir;
void main() {
gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
- pos = vertexPosition_mdl;
+
+ highp vec3 minBoundsNorm = minBounds;
+ highp vec3 maxBoundsNorm = maxBounds;
+
+ // Y and Z are flipped in bounds to be directly usable in texture calculations,
+ // so flip them back to normal for position calculations
+ minBoundsNorm.yz = -minBoundsNorm.yz;
+ maxBoundsNorm.yz = -maxBoundsNorm.yz;
+
+ minBoundsNorm = 0.5 * (minBoundsNorm + 1.0);
+ maxBoundsNorm = 0.5 * (maxBoundsNorm + 1.0);
+
+ pos = vertexPosition_mdl
+ + ((1.0 - vertexPosition_mdl) * minBoundsNorm)
+ - ((1.0 + vertexPosition_mdl) * (1.0 - maxBoundsNorm));
+
+ rayDir = -(cameraPositionRelativeToModel - pos);
+
+ // Flip Y and Z so QImage bits work directly for texture and first image is in the front
+ rayDir.yz = -rayDir.yz;
+ pos.yz = -pos.yz;
}
diff --git a/src/datavisualization/engine/shaders/texture3dlowdef.frag b/src/datavisualization/engine/shaders/texture3dlowdef.frag
index 72b959fc..ed0d41ce 100644
--- a/src/datavisualization/engine/shaders/texture3dlowdef.frag
+++ b/src/datavisualization/engine/shaders/texture3dlowdef.frag
@@ -1,15 +1,17 @@
#version 120
varying highp vec3 pos;
+varying highp vec3 rayDir;
uniform highp sampler3D textureSampler;
-uniform highp vec3 cameraPositionRelativeToModel;
uniform highp vec4 colorIndex[256];
uniform highp int color8Bit;
uniform highp vec3 textureDimensions;
uniform highp int sampleCount; // This is the maximum sample count
uniform highp float alphaMultiplier;
uniform highp int preserveOpacity;
+uniform highp vec3 minBounds;
+uniform highp vec3 maxBounds;
// Ray traveling straight through a single 'alpha thickness' applies 100% of the encountered alpha.
// Rays traveling shorter distances apply a fraction. This is used to normalize the alpha over
@@ -18,36 +20,30 @@ const highp float alphaThicknesses = 32.0;
const highp float SQRT3 = 1.73205081;
void main() {
- highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
vec3 rayStart = pos;
- // Flip Y and Z so QImage bits work directly for texture and first image is in the front
- rayDir.yz = -rayDir.yz;
- rayStart.yz = -rayStart.yz;
+ highp vec3 startBounds = minBounds;
+ highp vec3 endBounds = maxBounds;
+ if (rayDir.x < 0.0) {
+ startBounds.x = maxBounds.x;
+ endBounds.x = minBounds.x;
+ }
+ if (rayDir.y > 0.0) {
+ startBounds.y = maxBounds.y;
+ endBounds.y = minBounds.y;
+ }
+ if (rayDir.z > 0.0) {
+ startBounds.z = maxBounds.z;
+ endBounds.z = minBounds.z;
+ }
// Calculate ray intersection endpoint
- vec3 rayStop;
- if (rayDir.x == 0.0) {
- rayStop.yz = rayStart.yz;
- rayStop.x = -rayStart.x;
- } else if (rayDir.y == 0.0) {
- rayStop.xz = rayStart.xz;
- rayStop.y = -rayStart.y;
- } else if (rayDir.z == 0.0) {
- rayStop.xy = rayStart.xy;
- rayStop.z = -rayStart.z;
- } else {
- highp vec3 boxBounds = vec3(1.0, 1.0, 1.0);
- highp vec3 invRayDir = 1.0 / rayDir;
- if (rayDir.x < 0)
- boxBounds.x = -1.0;
- if (rayDir.y < 0)
- boxBounds.y = -1.0;
- if (rayDir.z < 0)
- boxBounds.z = -1.0;
- highp vec3 t = (boxBounds - rayStart) * invRayDir;
- highp float minT = min(t.x, min(t.y, t.z));
- rayStop = rayStart + minT * rayDir;
- }
+ highp vec3 rayStop;
+ highp vec3 invRayDir = 1.0 / rayDir;
+ highp vec3 t = (endBounds - rayStart) * invRayDir;
+ highp float endT = min(t.x, min(t.y, t.z));
+ if (endT <= 0.0)
+ discard;
+ rayStop = rayStart + endT * rayDir;
// Convert intersections to texture coords
rayStart = 0.5 * (rayStart + 1.0);
@@ -55,15 +51,6 @@ void main() {
highp vec3 ray = rayStop - rayStart;
- // Avoid artifacts from divisions by zero
- if (ray.x == 0)
- ray.x = 0.000000001;
- if (ray.y == 0)
- ray.y = 0.000000001;
- if (ray.z == 0)
- ray.z = 0.000000001;
-
-
highp float fullDist = length(ray);
highp float stepSize = SQRT3 / sampleCount;
highp vec3 step = (SQRT3 * normalize(ray)) / sampleCount;
@@ -110,6 +97,9 @@ void main() {
break;
}
+ if (totalOpacity == 1.0)
+ discard;
+
// Brighten up the final color if there is some transparency left
if (totalOpacity >= 0.0 && totalOpacity < 1.0)
destColor *= (1.0 - (totalOpacity * 0.5)) / (1.0 - totalOpacity);
diff --git a/src/datavisualization/engine/shaders/texture3dslice.frag b/src/datavisualization/engine/shaders/texture3dslice.frag
index 00584744..c555af98 100644
--- a/src/datavisualization/engine/shaders/texture3dslice.frag
+++ b/src/datavisualization/engine/shaders/texture3dslice.frag
@@ -1,14 +1,16 @@
#version 120
varying highp vec3 pos;
+varying highp vec3 rayDir;
uniform highp sampler3D textureSampler;
-uniform highp vec3 cameraPositionRelativeToModel;
uniform highp vec3 volumeSliceIndices;
uniform highp vec4 colorIndex[256];
uniform highp int color8Bit;
uniform highp float alphaMultiplier;
uniform highp int preserveOpacity;
+uniform highp vec3 minBounds;
+uniform highp vec3 maxBounds;
const highp vec3 xPlaneNormal = vec3(1.0, 0, 0);
const highp vec3 yPlaneNormal = vec3(0, 1.0, 0);
@@ -16,21 +18,17 @@ const highp vec3 zPlaneNormal = vec3(0, 0, 1.0);
void main() {
// Find out where ray intersects the slice planes
- highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
- rayDir = normalize(rayDir);
+ vec3 normRayDir = normalize(rayDir);
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;
- rayDir.yz = -rayDir.yz;
highp float minT = 2.0f;
- if (rayDir.x != 0.0 && rayDir.y != 0.0 && rayDir.z != 0.0) {
+ if (normRayDir.x != 0.0 && normRayDir.y != 0.0 && normRayDir.z != 0.0) {
highp vec3 boxBounds = vec3(1.0, 1.0, 1.0);
- highp vec3 invRayDir = 1.0 / rayDir;
- if (rayDir.x < 0)
+ highp vec3 invRayDir = 1.0 / normRayDir;
+ if (normRayDir.x < 0)
boxBounds.x = -1.0;
- if (rayDir.y < 0)
+ if (normRayDir.y < 0)
boxBounds.y = -1.0;
- if (rayDir.z < 0)
+ if (normRayDir.z < 0)
boxBounds.z = -1.0;
highp vec3 t = (boxBounds - rayStart) * invRayDir;
minT = min(t.x, min(t.y, t.z));
@@ -43,12 +41,12 @@ void main() {
highp float secondD = firstD;
highp float thirdD = firstD;
if (volumeSliceIndices.x >= -1.0) {
- highp float dx = dot(xPoint - rayStart, xPlaneNormal) / dot(rayDir, xPlaneNormal);
+ highp float dx = dot(xPoint - rayStart, xPlaneNormal) / dot(normRayDir, xPlaneNormal);
if (dx >= 0.0 && dx <= minT)
firstD = min(dx, firstD);
}
if (volumeSliceIndices.y >= -1.0) {
- highp float dy = dot(yPoint - rayStart, yPlaneNormal) / dot(rayDir, yPlaneNormal);
+ highp float dy = dot(yPoint - rayStart, yPlaneNormal) / dot(normRayDir, yPlaneNormal);
if (dy >= 0.0 && dy <= minT) {
if (dy < firstD) {
secondD = firstD;
@@ -59,7 +57,7 @@ void main() {
}
}
if (volumeSliceIndices.z >= -1.0) {
- highp float dz = dot(zPoint - rayStart, zPlaneNormal) / dot(rayDir, zPlaneNormal);
+ highp float dz = dot(zPoint - rayStart, zPlaneNormal) / dot(normRayDir, zPlaneNormal);
if (dz >= 0.0) {
if (dz < firstD && dz <= minT) {
thirdD = secondD;
@@ -83,43 +81,35 @@ void main() {
// Convert intersection to texture coords
if (firstD <= minT) {
- highp vec3 firstTex = rayStart + rayDir * firstD;
- firstTex = 0.5 * (firstTex + 1.0);
- curColor = texture3D(textureSampler, firstTex);
- if (color8Bit != 0)
- curColor = colorIndex[int(curColor.r * 255.0)];
-
- if (curColor.a > 0.0) {
- curAlpha = curColor.a;
- if (curColor.a == 1.0 && preserveOpacity != 0)
- curAlpha = 1.0;
- else
- curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
- destColor.rgb = curColor.rgb * curAlpha;
- totalAlpha = curAlpha;
- }
- if (secondD <= minT && totalAlpha < 1.0) {
- highp vec3 secondTex = rayStart + rayDir * secondD;
- secondTex = 0.5 * (secondTex + 1.0);
- curColor = texture3D(textureSampler, secondTex);
+ highp vec3 texelVec = rayStart + normRayDir * firstD;
+ if (clamp(texelVec.x, minBounds.x, maxBounds.x) == texelVec.x
+ && clamp(texelVec.y, maxBounds.y, minBounds.y) == texelVec.y
+ && clamp(texelVec.z, maxBounds.z, minBounds.z) == texelVec.z) {
+ texelVec = 0.5 * (texelVec + 1.0);
+ curColor = texture3D(textureSampler, texelVec);
if (color8Bit != 0)
curColor = colorIndex[int(curColor.r * 255.0)];
+
if (curColor.a > 0.0) {
+ curAlpha = curColor.a;
if (curColor.a == 1.0 && preserveOpacity != 0)
curAlpha = 1.0;
else
curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
- curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
- destColor.rgb += curRgb;
- totalAlpha += curAlpha;
+ destColor.rgb = curColor.rgb * curAlpha;
+ totalAlpha = curAlpha;
}
- if (thirdD <= minT && totalAlpha < 1.0) {
- highp vec3 thirdTex = rayStart + rayDir * thirdD;
- thirdTex = 0.5 * (thirdTex + 1.0);
- curColor = texture3D(textureSampler, thirdTex);
+ }
+ if (secondD <= minT && totalAlpha < 1.0) {
+ texelVec = rayStart + normRayDir * secondD;
+ if (clamp(texelVec.x, minBounds.x, maxBounds.x) == texelVec.x
+ && clamp(texelVec.y, maxBounds.y, minBounds.y) == texelVec.y
+ && clamp(texelVec.z, maxBounds.z, minBounds.z) == texelVec.z) {
+ texelVec = 0.5 * (texelVec + 1.0);
+ curColor = texture3D(textureSampler, texelVec);
+ if (color8Bit != 0)
+ curColor = colorIndex[int(curColor.r * 255.0)];
if (curColor.a > 0.0) {
- if (color8Bit != 0)
- curColor = colorIndex[int(curColor.r * 255.0)];
if (curColor.a == 1.0 && preserveOpacity != 0)
curAlpha = 1.0;
else
@@ -129,9 +119,32 @@ void main() {
totalAlpha += curAlpha;
}
}
+ if (thirdD <= minT && totalAlpha < 1.0) {
+ texelVec = rayStart + normRayDir * thirdD;
+ if (clamp(texelVec.x, minBounds.x, maxBounds.x) == texelVec.x
+ && clamp(texelVec.y, maxBounds.y, minBounds.y) == texelVec.y
+ && clamp(texelVec.z, maxBounds.z, minBounds.z) == texelVec.z) {
+ texelVec = 0.5 * (texelVec + 1.0);
+ curColor = texture3D(textureSampler, texelVec);
+ if (curColor.a > 0.0) {
+ if (color8Bit != 0)
+ curColor = colorIndex[int(curColor.r * 255.0)];
+ if (curColor.a == 1.0 && preserveOpacity != 0)
+ curAlpha = 1.0;
+ else
+ curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
+ curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += curAlpha;
+ }
+ }
+ }
}
}
+ if (totalAlpha == 0.0)
+ discard;
+
// Brighten up the final color if there is some transparency left
if (totalAlpha > 0.0 && totalAlpha < 1.0)
destColor *= 1.0 / totalAlpha;