Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

Commit 148ab63c authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Further work on OptimizedRaycaster:

 * Finished implementation of empty space skipping
 * Renamed Adaptive Step Size to Intersection Refinement (which is more precise in terms of what it's doing)
parent c38abe1a
......@@ -32,6 +32,10 @@ namespace campvis {
*/
size_t getNumBrickIndices() const;
/**
* Gets the number of voxels a brick is covering in each dimension.
* \return _brickSize
*/
size_t getBrickSize() const;
......
......@@ -73,7 +73,7 @@ uniform vec3 _cameraPosition;
uniform float _samplingStepSize;
#ifdef ENABLE_ADAPTIVE_STEPSIZE
#ifdef INTERSECTION_REFINEMENT
bool _inVoid = false;
#endif
......@@ -101,15 +101,21 @@ bool lookupInBbv(in vec3 samplePosition) {
return (texel & (1U << bit)) != 0U;
}
float rayBoxIntersection(in vec3 rayOrigin, in vec3 rayDirection, in vec3 box[2], in float t) {
vec3 rayInverseDirection = 1.f / rayDirection;
ivec3 raySign = ivec3(lessThan(rayDirection, vec3(0.0, 0.0, 0.0));
float rayBoxIntersection(in vec3 rayOrigin, in vec3 rayDirection, in vec3 boxLlf, in vec3 boxUrb, in float t) {
vec3 tMin = (boxLlf - rayOrigin) / rayDirection;
vec3 tMax = (boxUrb - rayOrigin) / rayDirection;
vec3 tMin = (box[raySign] - rayOrigin) / rayInverseDirection;
vec3 tMax = (box[1 - raySign] - rayOrigin) / rayInverseDirection;
// TODO: these many ifs are expensive - the lessThan bvec solution below should be faster but does not work for some reason...
if (tMin.x < t) tMin.x = positiveInfinity;
if (tMin.y < t) tMin.y = positiveInfinity;
if (tMin.z < t) tMin.z = positiveInfinity;
tMin *= vec3(lessThan(tMin, vec3(t, t, t)) * positiveInfinity;
tMax *= vec3(lessThan(tMax, vec3(t, t, t)) * positiveInfinity;
if (tMax.x < t) tMax.x = positiveInfinity;
if (tMax.y < t) tMax.y = positiveInfinity;
if (tMax.z < t) tMax.z = positiveInfinity;
//tMin += vec3(lessThan(tMin, vec3(t, t, t))) * positiveInfinity;
//tMax += vec3(lessThan(tMax, vec3(t, t, t))) * positiveInfinity;
return min(min(tMin.x, min(tMin.y, tMin.z)) , min(tMax.x, min(tMax.y, tMax.z)));
}
......@@ -120,9 +126,6 @@ float rayBoxIntersection(in vec3 rayOrigin, in vec3 rayDirection, in vec3 box[2]
vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords) {
vec4 result = vec4(0.0);
float firstHitT = -1.0;
#ifdef ENABLE_ADAPTIVE_STEPSIZE
float samplingRateCompensationMultiplier = 1.0;
#endif
// calculate ray parameters
vec3 direction = exitPoint.rgb - entryPoint.rgb;
......@@ -136,17 +139,15 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
// compute sample position
vec3 samplePosition = entryPoint.rgb + t * direction;
// check whether we have a lookup volume for empty space skipping
if (_hasBbv) {
if (! lookupInBbv(samplePosition)) {
// advance the ray to the intersection point with the current brick
vec3 brickVoxel = floor((samplePosition * _volumeTextureParams._size) / _bbvBrickSize) * _bbvBrickSize;
vec3 boxLlf = brickVoxel * _volumeTextureParams._sizeRCP;
vec3 boxUrb = boxLlf + (_volumeTextureParams._sizeRCP * _bbvBrickSize);
// advance to the next evaluation point along the ray
t += 4.0*_samplingStepSize;
#ifdef ENABLE_ADAPTIVE_STEPSIZE
samplingRateCompensationMultiplier = 1.0;
#endif
continue;
t = rayBoxIntersection(entryPoint, direction, boxLlf, boxUrb, t);
}
}
......@@ -154,7 +155,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
float intensity = getElement3DNormalized(_volume, _volumeTextureParams, samplePosition).a;
vec4 color = lookupTF(_transferFunction, _transferFunctionParams, intensity);
#ifdef ENABLE_ADAPTIVE_STEPSIZE
#ifdef INTERSECTION_REFINEMENT
if (color.a <= 0.0) {
// we're within void, make the steps bigger
_inVoid = true;
......@@ -189,32 +190,6 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
}
#endif
#ifdef ENABLE_SHADOWING
// simple and expensive implementation of hard shadows
if (color.a > 0.1) {
// compute direction from sample to light
vec3 L = normalize(_lightSource._position - textureToWorld(_volumeTextureParams, samplePosition).xyz) * _samplingStepSize;
bool finished = false;
vec3 position = samplePosition + L;
float shadowFactor = 0.0;
// traverse ray from sample to light
while (! finished) {
// grab intensity and TF opacity
intensity = getElement3DNormalized(_volume, _volumeTextureParams, position).a;
shadowFactor += lookupTF(_transferFunction, _transferFunctionParams, intensity).a;
position += L;
finished = (shadowFactor > 0.95)
|| any(lessThan(position, vec3(0.0, 0.0, 0.0)))
|| any(greaterThan(position, vec3(1.0, 1.0, 1.0)));
}
// apply shadow to color
color.rgb *= (1.0 - shadowFactor * _shadowIntensity);
}
#endif
// perform compositing
if (color.a > 0.0) {
#ifdef ENABLE_SHADING
......@@ -224,11 +199,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
#endif
// accomodate for variable sampling rates
#ifdef ENABLE_ADAPTIVE_STEPSIZE
color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * samplingRateCompensationMultiplier * SAMPLING_BASE_INTERVAL_RCP);
#else
color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP);
#endif
result.rgb = mix(color.rgb, result.rgb, result.a);
result.a = result.a + (1.0 -result.a) * color.a;
}
......@@ -247,13 +218,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
}
// advance to the next evaluation point along the ray
#ifdef ENABLE_ADAPTIVE_STEPSIZE
samplingRateCompensationMultiplier = (_inVoid ? 1.0 : 0.25);
t += _samplingStepSize * (_inVoid ? 1.0 : 0.125);
#else
t += _samplingStepSize;
#endif
}
// calculate depth value from ray parameter
......@@ -263,6 +228,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
float depthExit = getElement2DNormalized(_exitPointsDepth, _exitParams, texCoords).z;
gl_FragDepth = calculateDepthValue(firstHitT/tend, depthEntry, depthExit);
}
return result;
}
......
......@@ -43,15 +43,15 @@ namespace campvis {
, p_targetImageID("targetImageID", "Output Image", "", DataNameProperty::WRITE)
, p_enableShadowing("EnableShadowing", "Enable Hard Shadows (Expensive!)", false, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_PROPERTIES)
, p_shadowIntensity("ShadowIntensity", "Shadow Intensity", .5f, .0f, 1.f)
, p_enableAdaptiveStepsize("EnableAdaptiveStepSize", "Enable Adaptive Step Size", true, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER)
, p_useEmptySpaceSkipping("EnableEmptySpaceSkipping", "Enable Empty Space Skipping", false, AbstractProcessor::INVALID_RESULT | INVALID_BBV)
, p_enableIntersectionRefinement("EnableIntersectionRefinement", "Enable Intersection Refinement", false, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_SHADER)
, p_useEmptySpaceSkipping("EnableEmptySpaceSkipping", "Enable Empty Space Skipping", true, AbstractProcessor::INVALID_RESULT | INVALID_BBV)
, _bbv(0)
, _t(0)
{
addDecorator(new ProcessorDecoratorShading());
addProperty(&p_targetImageID);
addProperty(&p_enableAdaptiveStepsize);
addProperty(&p_enableIntersectionRefinement);
addProperty(&p_useEmptySpaceSkipping);
addProperty(&p_enableShadowing);
......@@ -69,6 +69,8 @@ namespace campvis {
void OptimizedRaycaster::init() {
RaycastingProcessor::init();
invalidate(INVALID_BBV);
}
void OptimizedRaycaster::deinit() {
......@@ -112,12 +114,12 @@ namespace campvis {
FramebufferActivationGuard fag(this);
createAndAttachTexture(GL_RGBA8);
// createAndAttachTexture(GL_RGBA32F);
// createAndAttachTexture(GL_RGBA32F);
createAndAttachTexture(GL_RGBA32F);
createAndAttachTexture(GL_RGBA32F);
createAndAttachDepthTexture();
// static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 };
// glDrawBuffers(3, buffers);
static const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, buffers);
if (p_enableShadowing.getValue())
_shader->setUniform("_shadowIntensity", p_shadowIntensity.getValue());
......@@ -125,6 +127,8 @@ namespace campvis {
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QuadRdr.renderQuad();
glDrawBuffers(1, buffers);
glDisable(GL_DEPTH_TEST);
LGL_ERROR;
......@@ -135,8 +139,8 @@ namespace campvis {
std::string toReturn = RaycastingProcessor::generateHeader();
if (p_enableShadowing.getValue())
toReturn += "#define ENABLE_SHADOWING\n";
if (p_enableAdaptiveStepsize.getValue())
toReturn += "#define ENABLE_ADAPTIVE_STEPSIZE\n";
if (p_enableIntersectionRefinement.getValue())
toReturn += "#define INTERSECTION_REFINEMENT\n";
return toReturn;
}
......@@ -157,7 +161,7 @@ namespace campvis {
else {
if (const ImageData* id = dynamic_cast<const ImageData*>(dh.getData())) {
if (const ImageRepresentationLocal* rep = id->getRepresentation<ImageRepresentationLocal>(true)) {
_bbv = new BinaryBrickedVolume(rep->getParent(), 2);
_bbv = new BinaryBrickedVolume(rep->getParent(), 4);
GLubyte* tfBuffer = p_transferFunction.getTF()->getTexture()->downloadTextureToBuffer(GL_RGBA, GL_UNSIGNED_BYTE);
size_t tfNumElements = p_transferFunction.getTF()->getTexture()->getDimensions().x;
......
......@@ -69,7 +69,7 @@ namespace campvis {
/// \see AbstractProcessor::getAuthor()
virtual const std::string getAuthor() const { return "Christian Schulte zu Berge <christian.szb@in.tum.de>"; };
/// \see AbstractProcessor::getProcessorState()
virtual ProcessorState getProcessorState() const { return AbstractProcessor::TESTING; };
virtual ProcessorState getProcessorState() const { return AbstractProcessor::EXPERIMENTAL; };
/// \see AbstractProcessor::init
virtual void init();
......@@ -79,7 +79,7 @@ namespace campvis {
DataNameProperty p_targetImageID; ///< image ID for output image
BoolProperty p_enableShadowing;
FloatProperty p_shadowIntensity;
BoolProperty p_enableAdaptiveStepsize;
BoolProperty p_enableIntersectionRefinement;
BoolProperty p_useEmptySpaceSkipping;
......
......@@ -34,7 +34,6 @@
#include "core/properties/floatingpointproperty.h"
#include "core/properties/genericproperty.h"
#include "core/properties/transferfunctionproperty.h"
#include "core/tools/volumebricking.h"
#include <string>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment