Further work on IpsviRaycaster processor. Projection of light direction seems...

Further work on IpsviRaycaster processor. Projection of light direction seems to work now. First step to introduce extra ray integration step at IC lookup. Results are still mixed though.
parent 45fb9320
......@@ -61,7 +61,7 @@ vec4 textureToWorld(in TextureParameters3D texParams, in vec4 texCoords) {
*/
vec3 textureToWorld(in TextureParameters3D texParams, in vec3 texCoords) {
vec4 v = textureToWorld(texParams, vec4(texCoords, 1.0));
return v.xyz;
return (v / v.w).xyz;
}
/**
......@@ -82,6 +82,7 @@ vec4 worldToTexture(in TextureParameters3D texParams, in vec4 worldCoords) {
* \param worldCoords world coordinates
* \return \a texCoords transformes to texture coordinates.
*/
vec4 worldToTexture(in TextureParameters3D texParams, in vec3 worldCoords) {
return worldToTexture(texParams, vec4(worldCoords, 1.0));
vec3 worldToTexture(in TextureParameters3D texParams, in vec3 worldCoords) {
vec4 v = worldToTexture(texParams, vec4(worldCoords, 1.0));
return (v / v.w).xyz;
}
......@@ -57,8 +57,8 @@ uniform TFParameters1D _transferFunctionParams;
// Illumination cache
uniform layout(rgba8) image2D _icImageIn;
uniform layout(rgba8) image2D _icImageOut;
uniform layout(rgba32f) image2D _icImageIn;
uniform layout(rgba32f) image2D _icImageOut;
uniform vec3 _icOrigin;
uniform vec3 _icNormal;
uniform vec3 _icRightVector;
......@@ -82,6 +82,23 @@ ivec2 calcIcSamplePosition(vec3 worldPosition) {
return ivec2(dot(projected, _icRightVector), dot(projected, _icUpVector));
}
void composite(vec3 startPosition, vec3 endPosition, inout float opacity) {
vec3 direction = endPosition - startPosition;
float t = 0.0;
float tend = length(direction);
direction = normalize(direction);
while (t < tend) {
// lookup intensity and TF
vec3 samplePosition = startPosition.rgb + t * direction;
float intensity = texture(_volume, samplePosition).r;
float tfOpacity = lookupTF(_transferFunction, _transferFunctionParams, intensity).a;
opacity = opacity + (1.0 - opacity) * tfOpacity;
t += _samplingStepSize * 2;
}
}
/**
* Performs the raycasting and returns the final fragment color.
......@@ -98,15 +115,20 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
jitterEntryPoint(entryPoint, direction, _samplingStepSize * _jitterStepSizeMultiplier);
ivec2 icPositionPrev = calcIcSamplePosition(textureToWorld(_volumeTextureParams, vec4(entryPoint, 1.0)).xyz);
ivec2 icPositionPrev = calcIcSamplePosition(textureToWorld(_volumeTextureParams, entryPoint));
vec4 icOut = vec4(0.0);
while (t < tend) {
// compute sample position
vec3 samplePosition = entryPoint.rgb + t * direction;
vec4 worldPos = textureToWorld(_volumeTextureParams, vec4(samplePosition, 1.0));
ivec2 icPosition = calcIcSamplePosition(worldPos.xyz / worldPos.w);
vec3 worldPos = textureToWorld(_volumeTextureParams, samplePosition);
ivec2 icPosition = calcIcSamplePosition(worldPos);
vec4 icIn = imageLoad(_icImageIn, icPositionPrev);
// perform a compositing from samplePosition to the samplePosition of the IC
//if (icIn.xyz != vec3(0.0))
// composite(samplePosition, icIn.xyz, icIn.a);
// lookup intensity and TF
float intensity = texture(_volume, samplePosition).r;
......@@ -116,18 +138,20 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
if (color.a > 0.0) {
// compute gradient (needed for shading and normals)
vec3 gradient = computeGradient(_volume, _volumeTextureParams, samplePosition);
color.rgb = calculatePhongShading(worldPos.xyz / worldPos.w, _lightSource, _cameraPosition, gradient, color.rgb);
color.rgb = calculatePhongShading(worldPos.xyz, _lightSource, _cameraPosition, gradient, color.rgb);
// accomodate for variable sampling rates
color.a = 1.0 - pow(1.0 - color.a, _samplingStepSize * SAMPLING_BASE_INTERVAL_RCP);
// perform global illumination
// back-to-front compositing from light-direction
icOut.rgb = ((1.0 - color.a) * icIn.rgb) + (color.a * color.rgb);
// back-to-front compositing from light-direction
// (for now, we ignore the color contribution and store the world position instead)
// icOut.rgb = ((1.0 - color.a) * icIn.rgb) + (color.a * color.rgb);
icOut.xyz = samplePosition;
icOut.a = ((1.0 - color.a) * icIn.a) + color.a;
// apply shadowing
color.rgb *= (1.0 - icOut.a * _shadowIntensity);
color.rgb *= (1.0 - icIn.a * _shadowIntensity);
// front-to-back compositing along view direction
result.rgb = result.rgb + color.rgb * color.a * (1.0 - result.a);
......
......@@ -40,7 +40,7 @@ namespace campvis {
: RaycastingProcessor(viewportSizeProp, "modules/vis/glsl/ipsviraycaster.frag", true, "450")
, p_lightId("LightId", "Input Light Source", "lightsource", DataNameProperty::READ)
, p_sweepLineWidth("SweepLineWidth", "Sweep Line Width", 2, 1, 8)
, p_shadowIntensity("ShadowIntensity", "Shadow Intensity", .5f, 0.f, 1.f)
, p_shadowIntensity("ShadowIntensity", "Shadow Intensity", .9f, 0.f, 1.f)
{
addProperty(p_lightId);
addProperty(p_sweepLineWidth);
......@@ -66,33 +66,38 @@ namespace campvis {
ScopedTypedData<LightSourceData> light(data, p_lightId.getValue());
if (light != nullptr) {
cgt::vec3 lightDirection = -(light->getLightPosition());
cgt::vec3 lightDirection = (light->getLightPosition());
// TODO: This should be a world to NDC space conversion, but it does not work... :(
cgt::mat4 tmp = camera->getCamera().getViewMatrix() * camera->getCamera().getProjectionMatrix();
cgt::vec4 projectedLightDirection = tmp * cgt::vec4(lightDirection, 1.f);
projectedLightDirection /= projectedLightDirection.w;
const auto V = camera->getCamera().getViewMatrix();
const auto P = camera->getCamera().getProjectionMatrix();
// calculate viewport matrix for NDC -> viewport conversion
const cgt::vec2 halfViewport = cgt::vec2(getEffectiveViewportSize()) / 2.f;
const cgt::mat4 viewportMatrix = cgt::mat4::createTranslation(cgt::vec3(halfViewport, 0.f)) * cgt::mat4::createScale(cgt::vec3(halfViewport, 1.f));
const cgt::vec4 projectedLight = viewportMatrix*P*V*cgt::vec4(lightDirection, 1.f);
const cgt::vec4 projectedOrigin = viewportMatrix*P*V*cgt::vec4(0.f, 0.f, 0.f, 1.f);
cgt::vec2 projectedLightDirection = projectedOrigin.xy()/projectedOrigin.w - projectedLight.xy()/projectedLight.w;
// compute sweep direction (in viewport space)
enum SweepDirection { LeftToRight, RightToLeft, TopToBottom, BottomToTop };
SweepDirection sweepDir;
if (std::abs(projectedLightDirection.x) > std::abs(projectedLightDirection.y)) {
// horizontal sweep
if (projectedLightDirection.x > 0)
sweepDir = RightToLeft;
else
sweepDir = LeftToRight;
else
sweepDir = RightToLeft;
}
else {
// vertical sweep
if (projectedLightDirection.y > 0)
sweepDir = TopToBottom;
else
sweepDir = BottomToTop;
else
sweepDir = TopToBottom;
}
LINFO(cgt::normalize(projectedLightDirection.xy()) << " => " << sweepDir);
// START: compute illumination cache (IC) plane/texture
// the plane is defined by the light direction
cgt::vec3 icNormal = cgt::normalize(lightDirection);
......@@ -124,7 +129,7 @@ namespace campvis {
}
cgt::vec3 icOrigin = cgt::floor(minPixel).x * icRightVector + cgt::floor(minPixel).y * icUpVector;
cgt::ivec3 icSize(512, 512, 1);
cgt::ivec3 icSize(384, 384, 1);
icRightVector *= float(icSize.x - 1) / (std::ceil(maxPixel.x) - std::floor(minPixel.x)) ;
icUpVector *= float(icSize.y - 1) / (std::ceil(maxPixel.y) - std::floor(minPixel.y));
......@@ -145,12 +150,12 @@ namespace campvis {
cgt::TextureUnit icUnit1, icUnit2;
cgt::Texture* icTextures[2];
icUnit1.activate();
icTextures[0] = new cgt::Texture(GL_TEXTURE_2D, icSize, GL_RGBA8, zeroInit->elem, GL_RGBA, GL_UNSIGNED_BYTE);
icTextures[0] = new cgt::Texture(GL_TEXTURE_2D, icSize, GL_RGBA32F, zeroInit->elem, GL_RGBA, GL_UNSIGNED_BYTE);
icUnit2.activate();
icTextures[1] = new cgt::Texture(GL_TEXTURE_2D, icSize, GL_RGBA8, zeroInit->elem, GL_RGBA, GL_UNSIGNED_BYTE);
icTextures[1] = new cgt::Texture(GL_TEXTURE_2D, icSize, GL_RGBA32F, zeroInit->elem, GL_RGBA, GL_UNSIGNED_BYTE);
glBindImageTexture(0, icTextures[0]->getId(), 0, false, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(1, icTextures[1]->getId(), 0, false, 0, GL_READ_WRITE, GL_RGBA8);
glBindImageTexture(0, icTextures[0]->getId(), 0, false, 0, GL_READ_WRITE, GL_RGBA32F);
glBindImageTexture(1, icTextures[1]->getId(), 0, false, 0, GL_READ_WRITE, GL_RGBA32F);
delete [] zeroInit;
......
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