Commit 0f093954 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

Revised gradient.frag fragment shader:

 * use texture and textureOffset instead of clumsy getElement3DNormalized
 * introducing Sobel filtered gradients
parent 19e69bc7
......@@ -30,38 +30,36 @@
#include "tools/texture3d.frag"
/**
* Compute the gradient using forward differences on the texture's alpha channel.
* Compute the gradient using forward differences on the texture's red channel.
* \param tex 3D texture to calculate gradients for
* \param texCoords Lookup position in texture coordinates
*/
vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
vec3 offset = texParams._sizeRCP;
float v = getElement3DNormalized(tex, texParams, texCoords).r;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).r;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).r;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).r;
float v = texture(tex, texCoords).r;
float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r;
float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r;
float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r;
return vec3(v - dx, v - dy, v - dz) * texParams._voxelSize;
}
/**
* Compute the gradient using central differences on the texture's alpha channel.
* Compute the gradient using central differences on the texture's red channel.
* \param tex 3D texture to calculate gradients for
* \param texCoords Lookup position in texture coordinates
*/
vec3 computeGradientCentralDifferences(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
vec3 offset = texParams._sizeRCP;
float dx = getElement3DNormalized(tex, texParams, texCoords + vec3(offset.x, 0.0, 0.0)).r;
float dy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, offset.y, 0)).r;
float dz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, offset.z)).r;
float mdx = getElement3DNormalized(tex, texParams, texCoords + vec3(-offset.x, 0, 0)).r;
float mdy = getElement3DNormalized(tex, texParams, texCoords + vec3(0, -offset.y, 0)).r;
float mdz = getElement3DNormalized(tex, texParams, texCoords + vec3(0, 0, -offset.z)).r;
return vec3(mdx - dx, mdy - dy, mdz - dz) * texParams._voxelSize * vec3(0.5);
float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r;
float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r;
float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r;
float mdx = textureOffset(tex, texCoords, ivec3(-1, 0, 0)).r;
float mdy = textureOffset(tex, texCoords, ivec3(0, -1, 0)).r;
float mdz = textureOffset(tex, texCoords, ivec3(0, 0, -1)).r;
return vec3(mdx - dx, mdy - dy, mdz - dz) * texParams._voxelSize * 0.5;
}
/**
* Compute the gradient using filtered central differences on the texture's alpha channel.
* Compute the gradient using filtered central differences on the texture's red channel.
* \param tex 3D texture to calculate gradients for
* \param texCoords Lookup position in texture coordinates
*/
......@@ -80,3 +78,108 @@ vec3 computeGradientFilteredCentralDifferences(in sampler3D tex, in TextureParam
vec3 mix1 = mix(mix(g5, g6, 0.5), mix(g7, g8, 0.5), 0.5);
return mix(g0, mix(mix0, mix1, 0.5), 0.75);
}
/**
* Compute the gradient using the sobel filter on the texture's red channel.
* \param tex 3D texture to calculate gradients for
* \param texCoords Lookup position in texture coordinates
*/
vec3 computeGradientSobel(in sampler3D tex, in vec3 texCoords) {
const float sobelScale = 1.0 / 44.0;
vec3 sobel = vec3(0.0);
float value = 0.0;
value = textureOffset(tex, texCoords, ivec3(-1, -1, -1)).r;
sobel.x -= value;
sobel.y -= value;
sobel.z -= value;
value = textureOffset(tex, texCoords, ivec3( 0, -1, -1)).r;
sobel.y -= 3.0 * value;
sobel.z -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, -1, -1)).r;
sobel.x += value;
sobel.y -= value;
sobel.z -= value;
value = textureOffset(tex, texCoords, ivec3(-1, 0, -1)).r;
sobel.x -= 3.0 * value;
sobel.z -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 0, 0, -1)).r;
sobel.z -= 6.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 0, -1)).r;
sobel.x += 3.0 * value;
sobel.z -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3(-1, 1, -1)).r;
sobel.x -= value;
sobel.y += value;
sobel.z -= value;
value = textureOffset(tex, texCoords, ivec3( 0, 1, -1)).r;
sobel.y += 3.0 * value;
sobel.z -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 1, -1)).r;
sobel.x += value;
sobel.y += value;
sobel.z -= value;
value = textureOffset(tex, texCoords, ivec3(-1, -1, 0)).r;
sobel.x -= 3.0 * value;
sobel.y -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 0, -1, 0)).r;
sobel.y -= 6.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, -1, 0)).r;
sobel.x += 3.0 * value;
sobel.y -= 3.0 * value;
value = textureOffset(tex, texCoords, ivec3(-1, 0, 0)).r;
sobel.x -= 6.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 0, 0)).r;
sobel.x += 6.0 * value;
value = textureOffset(tex, texCoords, ivec3(-1, 1, 0)).r;
sobel.x -= 3.0 * value;
sobel.y += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 0, 1, 0)).r;
sobel.y += 6.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 1, 0)).r;
sobel.x += 3.0 * value;
sobel.y += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3(-1, -1, 1)).r;
sobel.x -= value;
sobel.y -= value;
sobel.z += value;
value = textureOffset(tex, texCoords, ivec3( 0, -1, 1)).r;
sobel.y -= 3.0 * value;
sobel.z += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, -1, 1)).r;
sobel.x += value;
sobel.y -= value;
sobel.z += value;
value = textureOffset(tex, texCoords, ivec3(-1, 0, 1)).r;
sobel.x -= 3.0 * value;
sobel.z += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 0, 0, 1)).r;
sobel.z += 6.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 0, 1)).r;
sobel.x += 3.0 * value;
sobel.z += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3(-1, 1, 1)).r;
sobel.x -= value;
sobel.y += value;
sobel.z += value;
value = textureOffset(tex, texCoords, ivec3( 0, 1, 1)).r;
sobel.y += 3.0 * value;
sobel.z += 3.0 * value;
value = textureOffset(tex, texCoords, ivec3( 1, 1, 1)).r;
sobel.x += value;
sobel.y += value;
sobel.z += value;
return -sobelScale * sobel;
}
\ No newline at end of file
......@@ -33,16 +33,17 @@
#include "core/properties/propertycollection.h"
namespace campvis {
static const GenericOption<ProcessorDecoratorShading::GradientMethod> gradientOptions[3] = {
static const GenericOption<ProcessorDecoratorShading::GradientMethod> gradientOptions[4] = {
GenericOption<ProcessorDecoratorShading::GradientMethod>("Forward", "Forward Differences", ProcessorDecoratorShading::ForwardDifferences),
GenericOption<ProcessorDecoratorShading::GradientMethod>("Central", "Central Differences", ProcessorDecoratorShading::CentralDifferences),
GenericOption<ProcessorDecoratorShading::GradientMethod>("Sobel", "Sobel Filter", ProcessorDecoratorShading::SobelFilter),
GenericOption<ProcessorDecoratorShading::GradientMethod>("FilteredCentral", "Filtered Central Differences", ProcessorDecoratorShading::FilteredCentralDifferences)
};
ProcessorDecoratorShading::ProcessorDecoratorShading(const std::string& lightUniformName /*= "_lightSource"*/)
: AbstractProcessorDecorator()
, _enableShading("EnableShading", "Enable Shading", true, AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_RESULT)
, _gradientMethod("GradientMethod", "Gradient Computation Method", gradientOptions, 3, AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_RESULT)
, _gradientMethod("GradientMethod", "Gradient Computation Method", gradientOptions, 4, AbstractProcessor::INVALID_SHADER | AbstractProcessor::INVALID_RESULT)
, _lightPosition("LightPosition", "Light Position", tgt::vec3(-100.f), tgt::vec3(-500.f), tgt::vec3(500.f), tgt::vec3(1.f))
, _ambientColor("AmbientColor", "Ambient Light Color", tgt::vec3(0.4f), tgt::vec3(0.f), tgt::vec3(1.f))
, _diffuseColor("DiffuseColor", "Diffuse Light Color", tgt::vec3(0.75f), tgt::vec3(0.f), tgt::vec3(1.f))
......@@ -85,13 +86,16 @@ namespace campvis {
switch (_gradientMethod.getOptionValue()) {
case ForwardDifferences :
toReturn.append("#define computeGradient(tex, texParams,texCoords) computeGradientForwardDifferences(tex, texParams, texCoords)\n");
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientForwardDifferences(tex, texParams, texCoords)\n");
break;
case CentralDifferences :
toReturn.append("#define computeGradient(tex, texParams,texCoords) computeGradientCentralDifferences(tex, texParams, texCoords)\n");
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientCentralDifferences(tex, texParams, texCoords)\n");
break;
case FilteredCentralDifferences :
toReturn.append("#define computeGradient(tex, texParams,texCoords) computeGradientFilteredCentralDifferences(tex, texParams, texCoords)\n");
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientFilteredCentralDifferences(tex, texParams, texCoords)\n");
break;
case SobelFilter :
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientSobel(tex, texCoords)\n");
break;
default:
tgtAssert(false, "Invalid enum!");
......
......@@ -44,7 +44,8 @@ namespace campvis {
enum GradientMethod {
ForwardDifferences,
CentralDifferences,
FilteredCentralDifferences
FilteredCentralDifferences,
SobelFilter
};
explicit ProcessorDecoratorShading(const std::string& lightUniformName = "_lightSource");
......
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