summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2014-08-22 13:19:18 +0300
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2014-08-22 14:47:54 +0300
commitae411d84b9eac08c217bdda3aa5fbc6f39d03d85 (patch)
treeff929c13722fe6f90412f8da473445dc92800fd4 /src
parent8fab0a9cfcbed9deb47f4a9bd101434985c1c611 (diff)
Tweak volume shaders.
Also fix custom object default texture. Change-Id: Iba9ff6afb807d9f7a4e1f58b0e5fb4bca4c9c431 Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/datavisualization/data/customrenderitem.cpp18
-rw-r--r--src/datavisualization/data/qcustom3ditem.cpp2
-rw-r--r--src/datavisualization/engine/shaders/texture3d.frag136
-rw-r--r--src/datavisualization/engine/shaders/texture3dslice.frag27
4 files changed, 102 insertions, 81 deletions
diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp
index b96a4957..3eb68845 100644
--- a/src/datavisualization/data/customrenderitem.cpp
+++ b/src/datavisualization/data/customrenderitem.cpp
@@ -52,13 +52,17 @@ void CustomRenderItem::setMesh(const QString &meshFile)
void CustomRenderItem::setColorTable(const QVector<QRgb> &colors)
{
- m_colorTable.resize(colors.size());
- for (int i = 0; i < m_colorTable.size(); i++) {
- const QRgb &rgb = colors.at(i);
- m_colorTable[i] = QVector4D(float(qRed(rgb)) / 255.0f,
- float(qGreen(rgb)) / 255.0f,
- float(qBlue(rgb)) / 255.0f,
- float(qAlpha(rgb)) / 255.0f);
+ m_colorTable.resize(256);
+ for (int i = 0; i < 256; i++) {
+ if (i < colors.size()) {
+ const QRgb &rgb = colors.at(i);
+ m_colorTable[i] = QVector4D(float(qRed(rgb)) / 255.0f,
+ float(qGreen(rgb)) / 255.0f,
+ float(qBlue(rgb)) / 255.0f,
+ float(qAlpha(rgb)) / 255.0f);
+ } else {
+ m_colorTable[i] = QVector4D(0.0f, 0.0f, 0.0f, 0.0f);
+ }
}
}
diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp
index 1d419cee..cb843b62 100644
--- a/src/datavisualization/data/qcustom3ditem.cpp
+++ b/src/datavisualization/data/qcustom3ditem.cpp
@@ -367,6 +367,7 @@ QString QCustom3DItem::textureFile() const
QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q) :
q_ptr(q),
+ m_textureImage(QImage(1, 1, QImage::Format_ARGB32)),
m_position(QVector3D(0.0f, 0.0f, 0.0f)),
m_positionAbsolute(false),
m_scaling(QVector3D(0.1f, 0.1f, 0.1f)),
@@ -382,6 +383,7 @@ QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q, const QString &mesh
const QVector3D &position, const QVector3D &scaling,
const QQuaternion &rotation) :
q_ptr(q),
+ m_textureImage(QImage(1, 1, QImage::Format_ARGB32)),
m_meshFile(meshFile),
m_position(position),
m_positionAbsolute(false),
diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag
index e56506ff..90876596 100644
--- a/src/datavisualization/engine/shaders/texture3d.frag
+++ b/src/datavisualization/engine/shaders/texture3d.frag
@@ -12,78 +12,90 @@ uniform highp int sampleCount; // This is the maximum sample count
const highp float alphaThreshold = 0.0001;
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;
+ 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 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 ray = rayStop - rayStart;
- highp float fullDist = length(ray);
- highp float rayX = abs(ray.x) * textureDimensions.x;
- highp float rayY = abs(ray.y) * textureDimensions.y;
- highp float rayZ = abs(ray.z) * textureDimensions.z;
-
- highp float maxRayDim = max(rayX, rayY);
- maxRayDim = max(maxRayDim, rayZ);
-
- highp vec3 step = ray / maxRayDim;
- highp float stepSize = abs(fullDist / maxRayDim);
-
- // Offset a fraction of a step so we are not exactly on a texel boundary.
- highp vec3 curPos = rayStart - (0.5 * step);
- // Adjust alpha multiplier according to the step size to get uniform alpha effect
- // regardless of the ray angle.
- highp float alphaMultiplier = stepSize / (1.0 / sampleCount);
+ // 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, t.y);
+ minT = min(minT, t.z);
+ rayStop = rayStart + minT * rayDir;
+ }
- 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)];
+ highp float totalAlpha = 0.0;
- if (curColor.a == 1.0)
- curAlpha = 1.0;
- else
- curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
- 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;
+ if (rayStart != rayStop) {
+ // Convert intersections to texture coords
+ rayStart = 0.5 * (rayStart + 1.0);
+ rayStop = 0.5 * (rayStop + 1.0);
+
+ highp vec3 ray = rayStop - rayStart;
+ highp float fullDist = abs(length(ray));
+ highp float rayX = abs(ray.x) * textureDimensions.x;
+ highp float rayY = abs(ray.y) * textureDimensions.y;
+ highp float rayZ = abs(ray.z) * textureDimensions.z;
+ highp float maxRayDim = max(rayX, rayY);
+ maxRayDim = max(maxRayDim, rayZ);
+ int maxCount = int(floor(maxRayDim));
+
+ highp vec3 step = ray / maxRayDim;
+ highp float stepSize = fullDist / maxRayDim;
+
+ rayStart += (step * 0.001);
+ highp vec3 curPos = rayStart;
+
+ // Adjust alpha multiplier according to the step size to get uniform alpha effect
+ // regardless of the ray angle.
+ highp float alphaMultiplier = stepSize / (1.0 / sampleCount);
+
+ highp vec4 curColor = vec4(0, 0, 0, 0);
+ highp vec3 curRgb = vec3(0, 0, 0);
+ highp float curAlpha = 0.0;
+
+ // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
+ for (int i = 0; i < sampleCount; i++) {
+ curColor = texture3D(textureSampler, curPos);
+ if (color8Bit != 0)
+ curColor = colorIndex[int(curColor.r * 255.0)];
+
+ if (curColor.a == 1.0)
+ curAlpha = 1.0;
+ else
+ curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
+ if (curAlpha > alphaThreshold) {
+ curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += curAlpha;
+ }
+ if (i == maxCount || totalAlpha >= 1.0)
+ break;
+ curPos += step;
}
}
destColor.a = totalAlpha;
gl_FragColor = clamp(destColor, 0.0, 1.0);
}
-
diff --git a/src/datavisualization/engine/shaders/texture3dslice.frag b/src/datavisualization/engine/shaders/texture3dslice.frag
index e095bc5f..409ab41d 100644
--- a/src/datavisualization/engine/shaders/texture3dslice.frag
+++ b/src/datavisualization/engine/shaders/texture3dslice.frag
@@ -15,24 +15,27 @@ const highp vec3 zPlaneNormal = vec3(0, 0, 1.0);
const highp float alphaThreshold = 0.0001;
void main() {
- // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
-
// Find out where ray intersects the slice planes
highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
+ rayDir = 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 vec3 invRayDir = 1.0 / rayDir;
- highp vec3 minCorner = vec3(-1.0);
- highp vec3 maxCorner = vec3(1.0);
- highp vec3 t1 = invRayDir * (minCorner - rayStart);
- highp vec3 t2 = invRayDir * (maxCorner - rayStart);
- 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 float tFar = 2.0f;
+ if (rayDir.x != 0.0 && rayDir.y != 0.0 && rayDir.z != 0.0) {
+ 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;
+ tFar = max(t.x, t.y);
+ tFar = max(tFar, t.z);
+ }
highp vec3 xPoint = vec3(volumeSliceIndices.x, 0, 0);
highp vec3 yPoint = vec3(0, volumeSliceIndices.y, 0);