diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-18 14:05:47 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-08-19 08:12:06 +0300 |
commit | cf95478ea842cd42a8888b0b74de3d0d0d0233ea (patch) | |
tree | 689e38c48cf39ab3907ef46015f8bf26c4040d16 | |
parent | 169a4d638c6c1b6634ffcfd19c4fe3cb94cf27d5 (diff) |
Make volume shading sample once per texture layer.
Change-Id: Ia3a13e2cb8d7dcf744a55dcb827f5cb436a043c4
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
-rw-r--r-- | examples/datavisualization/volumetric/volumetric.cpp | 6 | ||||
-rw-r--r-- | src/datavisualization/engine/abstract3drenderer.cpp | 12 | ||||
-rw-r--r-- | src/datavisualization/engine/shaders/texture3d.frag | 24 | ||||
-rw-r--r-- | src/datavisualization/utils/shaderhelper.cpp | 32 | ||||
-rw-r--r-- | src/datavisualization/utils/shaderhelper_p.h | 12 |
5 files changed, 65 insertions, 21 deletions
diff --git a/examples/datavisualization/volumetric/volumetric.cpp b/examples/datavisualization/volumetric/volumetric.cpp index a9233cab..8e61ecf2 100644 --- a/examples/datavisualization/volumetric/volumetric.cpp +++ b/examples/datavisualization/volumetric/volumetric.cpp @@ -102,8 +102,8 @@ void VolumetricModifier::adjustSliceZ(int value) void VolumetricModifier::handleZoomLevelChange() { // Zooming inside volumetric object causes ugly clipping issues, so restrict zoom level a bit - if (m_graph->scene()->activeCamera()->zoomLevel() > 220) - m_graph->scene()->activeCamera()->setZoomLevel(220); + if (m_graph->scene()->activeCamera()->zoomLevel() > 200) + m_graph->scene()->activeCamera()->setZoomLevel(200); } void VolumetricModifier::handleFpsChange(qreal fps) @@ -161,7 +161,7 @@ void VolumetricModifier::createVolume() // Take a slice out of the ellipsoid if (i >= textureSize / 2 || j >= textureSize / 4 || k >= textureSize / 2) { QVector3D distVec = QVector3D(float(k), float(j * 2), float(i)) - midPoint; - float adjLen = qMin(255.0f, (distVec.length() * float(textureSize / 128))); + float adjLen = qMin(255.0f, (distVec.length() * 512.0f / float(textureSize))); if (adjLen < 230) colorIndex = 255 - int(adjLen); else diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index cbb90af0..8eb1d2ce 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -1300,6 +1300,18 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state, (float(item->sliceIndexZ()) + 0.5f) / float(item->textureDepth()) * 2.0 - 1.0); shader->setUniformValue(shader->volumeSliceIndices(), slices); + } else { + // Precalculate texture dimensions so we can optimize + // ray stepping to hit every texture layer. + QVector3D textureDimensions(float(item->textureWidth()), + float(item->textureHeight()), + float(item->textureDepth())); + shader->setUniformValue(shader->textureDimensions(), textureDimensions); + + int sampleCount = qMax(item->textureWidth(), item->textureHeight()); + sampleCount = qMax(sampleCount, item->textureDepth()); + shader->setUniformValue(shader->sampleCount(), sampleCount); + } m_drawer->drawObject(shader, item->mesh(), 0, 0, item->texture()); } else diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag index 054b59cb..b9d87fcc 100644 --- a/src/datavisualization/engine/shaders/texture3d.frag +++ b/src/datavisualization/engine/shaders/texture3d.frag @@ -6,10 +6,11 @@ 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 -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 @@ -35,10 +36,21 @@ void main() { 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 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); + highp float totalDist = 0.0; highp float totalAlpha = 0.0; highp vec4 destColor = vec4(0, 0, 0, 0); diff --git a/src/datavisualization/utils/shaderhelper.cpp b/src/datavisualization/utils/shaderhelper.cpp index 3c3d93ac..3361638a 100644 --- a/src/datavisualization/utils/shaderhelper.cpp +++ b/src/datavisualization/utils/shaderhelper.cpp @@ -93,10 +93,12 @@ void ShaderHelper::initialize() m_gradientMinUniform = m_program->uniformLocation("gradMin"); m_gradientHeightUniform = m_program->uniformLocation("gradHeight"); m_lightColorUniform = m_program->uniformLocation("lightColor"); - m_volumeSliceIndices = m_program->uniformLocation("volumeSliceIndices"); - m_colorIndex = m_program->uniformLocation("colorIndex"); - m_cameraPositionRelativeToModel = m_program->uniformLocation("cameraPositionRelativeToModel"); - m_color8Bit = m_program->uniformLocation("color8Bit"); + m_volumeSliceIndicesUniform = m_program->uniformLocation("volumeSliceIndices"); + m_colorIndexUniform = m_program->uniformLocation("colorIndex"); + m_cameraPositionRelativeToModelUniform = m_program->uniformLocation("cameraPositionRelativeToModel"); + m_color8BitUniform = m_program->uniformLocation("color8Bit"); + m_textureDimensionsUniform = m_program->uniformLocation("textureDimensions"); + m_sampleCountUniform = m_program->uniformLocation("sampleCount"); m_initialized = true; } @@ -268,28 +270,42 @@ GLuint ShaderHelper::volumeSliceIndices() { if (!m_initialized) qFatal("Shader not initialized"); - return m_volumeSliceIndices; + return m_volumeSliceIndicesUniform; } GLuint ShaderHelper::colorIndex() { if (!m_initialized) qFatal("Shader not initialized"); - return m_colorIndex; + return m_colorIndexUniform; } GLuint ShaderHelper::cameraPositionRelativeToModel() { if (!m_initialized) qFatal("Shader not initialized"); - return m_cameraPositionRelativeToModel; + return m_cameraPositionRelativeToModelUniform; } GLuint ShaderHelper::color8Bit() { if (!m_initialized) qFatal("Shader not initialized"); - return m_color8Bit; + return m_color8BitUniform; +} + +GLuint ShaderHelper::textureDimensions() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_textureDimensionsUniform; +} + +GLuint ShaderHelper::sampleCount() +{ + if (!m_initialized) + qFatal("Shader not initialized"); + return m_sampleCountUniform; } GLuint ShaderHelper::posAtt() diff --git a/src/datavisualization/utils/shaderhelper_p.h b/src/datavisualization/utils/shaderhelper_p.h index 67e8a2f3..bc7609bb 100644 --- a/src/datavisualization/utils/shaderhelper_p.h +++ b/src/datavisualization/utils/shaderhelper_p.h @@ -78,6 +78,8 @@ class ShaderHelper GLuint colorIndex(); GLuint cameraPositionRelativeToModel(); GLuint color8Bit(); + GLuint textureDimensions(); + GLuint sampleCount(); GLuint posAtt(); GLuint uvAtt(); @@ -112,10 +114,12 @@ class ShaderHelper GLuint m_gradientMinUniform; GLuint m_gradientHeightUniform; GLuint m_lightColorUniform; - GLuint m_volumeSliceIndices; - GLuint m_colorIndex; - GLuint m_cameraPositionRelativeToModel; - GLuint m_color8Bit; + GLuint m_volumeSliceIndicesUniform; + GLuint m_colorIndexUniform; + GLuint m_cameraPositionRelativeToModelUniform; + GLuint m_color8BitUniform; + GLuint m_textureDimensionsUniform; + GLuint m_sampleCountUniform; GLboolean m_initialized; }; |