The name of the initial branch for new projects is now "main" instead of "master". Existing projects remain unchanged. More information: https://doku.lrz.de/display/PUBLIC/GitLab

Commit 17f5574c authored by Jakob Weiss's avatar Jakob Weiss
Browse files

Fixed (?) gradient computation, added option to fix broken shaders during startup

* gradient computation now properly accounts for anisotropic voxels
* Shaders that fail to compile at startup result in an error on the console, with the option to retry computation (after editing the shader) instead of crashing campvis completely
parent 1a7665e4
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "tools/texture3d.frag" #include "tools/texture3d.frag"
/** /**
* Compute the gradient using forward differences on the texture's red channel. * Compute the gradient using forward differences on the texture's red channel. Returns the gradient in world space.
* \param tex 3D texture to calculate gradients for * \param tex 3D texture to calculate gradients for
* \param texParams Texture parameters struct (needs texParams._voxelSize) * \param texParams Texture parameters struct (needs texParams._voxelSize)
* \param texCoords Lookup position in texture coordinates * \param texCoords Lookup position in texture coordinates
...@@ -36,11 +36,12 @@ vec3 computeGradientForwardDifferencesLod(in sampler3D tex, in TextureParameters ...@@ -36,11 +36,12 @@ vec3 computeGradientForwardDifferencesLod(in sampler3D tex, in TextureParameters
float dx = textureLodOffset(tex, texCoords, lod, ivec3(1, 0, 0)).r; float dx = textureLodOffset(tex, texCoords, lod, ivec3(1, 0, 0)).r;
float dy = textureLodOffset(tex, texCoords, lod, ivec3(0, 1, 0)).r; float dy = textureLodOffset(tex, texCoords, lod, ivec3(0, 1, 0)).r;
float dz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, 1)).r; float dz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, 1)).r;
return vec3(dx - v, dy - v, dz - v) * texParams._voxelSize; vec3 g = vec3(dx - v, dy - v, dz - v) * texParams._voxelSizeRCP * 0.5;
return (texParams._textureToWorldMatrixInvTransp * vec4(g, 0.0)).xyz;
} }
/** /**
* Compute the gradient using forward differences on the texture's red channel. * Compute the gradient using forward differences on the texture's red channel. Returns the gradient in world space.
* \param tex 3D texture to calculate gradients for * \param tex 3D texture to calculate gradients for
* \param texParams Texture parameters struct (needs texParams._voxelSize) * \param texParams Texture parameters struct (needs texParams._voxelSize)
* \param texCoords Lookup position in texture coordinates * \param texCoords Lookup position in texture coordinates
...@@ -50,11 +51,12 @@ vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D ...@@ -50,11 +51,12 @@ vec3 computeGradientForwardDifferences(in sampler3D tex, in TextureParameters3D
float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r; float dx = textureOffset(tex, texCoords, ivec3(1, 0, 0)).r;
float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r; float dy = textureOffset(tex, texCoords, ivec3(0, 1, 0)).r;
float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r; float dz = textureOffset(tex, texCoords, ivec3(0, 0, 1)).r;
return vec3(dx - v, dy - v, dz - v) * texParams._voxelSize; vec3 g = vec3(dx - v, dy - v, dz - v) * texParams._voxelSizeRCP;
return (texParams._textureToWorldMatrixInvTransp * vec4(g, 0.0)).xyz;
} }
/** /**
* Compute the gradient using central differences on the texture's red channel. * Compute the gradient using central differences on the texture's red channel. Returns the gradient in world space.
* \param tex 3D texture to calculate gradients for * \param tex 3D texture to calculate gradients for
* \param texParams Texture parameters struct (needs texParams._voxelSize) * \param texParams Texture parameters struct (needs texParams._voxelSize)
* \param texCoords Lookup position in texture coordinates * \param texCoords Lookup position in texture coordinates
...@@ -67,11 +69,12 @@ vec3 computeGradientCentralDifferencesLod(in sampler3D tex, in TextureParameters ...@@ -67,11 +69,12 @@ vec3 computeGradientCentralDifferencesLod(in sampler3D tex, in TextureParameters
float mdx = textureLodOffset(tex, texCoords, lod, ivec3(-1, 0, 0)).r; float mdx = textureLodOffset(tex, texCoords, lod, ivec3(-1, 0, 0)).r;
float mdy = textureLodOffset(tex, texCoords, lod, ivec3(0, -1, 0)).r; float mdy = textureLodOffset(tex, texCoords, lod, ivec3(0, -1, 0)).r;
float mdz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, -1)).r; float mdz = textureLodOffset(tex, texCoords, lod, ivec3(0, 0, -1)).r;
return vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSize * 0.5; vec3 g = vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSizeRCP * 0.5;
return (texParams._textureToWorldMatrixInvTransp * vec4(g, 0.0)).xyz;
} }
/** /**
* Compute the gradient using central differences on the texture's red channel. * Compute the gradient using central differences on the texture's red channel. Returns the gradient in world space.
* \param tex 3D texture to calculate gradients for * \param tex 3D texture to calculate gradients for
* \param texParams Texture parameters struct (needs texParams._voxelSize) * \param texParams Texture parameters struct (needs texParams._voxelSize)
* \param texCoords Lookup position in texture coordinates * \param texCoords Lookup position in texture coordinates
...@@ -83,7 +86,8 @@ vec3 computeGradientCentralDifferences(in sampler3D tex, in TextureParameters3D ...@@ -83,7 +86,8 @@ vec3 computeGradientCentralDifferences(in sampler3D tex, in TextureParameters3D
float mdx = textureOffset(tex, texCoords, ivec3(-1, 0, 0)).r; float mdx = textureOffset(tex, texCoords, ivec3(-1, 0, 0)).r;
float mdy = textureOffset(tex, texCoords, ivec3(0, -1, 0)).r; float mdy = textureOffset(tex, texCoords, ivec3(0, -1, 0)).r;
float mdz = textureOffset(tex, texCoords, ivec3(0, 0, -1)).r; float mdz = textureOffset(tex, texCoords, ivec3(0, 0, -1)).r;
return vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSize * 0.5; vec3 g = vec3(dx - mdx, dy - mdy, dz - mdz) * texParams._voxelSizeRCP * 0.5;
return (texParams._textureToWorldMatrixInvTransp * vec4(g, 0.0)).xyz;
} }
...@@ -114,7 +118,7 @@ vec3 computeGradientFilteredCentralDifferences(in sampler3D tex, in TextureParam ...@@ -114,7 +118,7 @@ vec3 computeGradientFilteredCentralDifferences(in sampler3D tex, in TextureParam
* \param tex 3D texture to calculate gradients for * \param tex 3D texture to calculate gradients for
* \param texCoords Lookup position in texture coordinates * \param texCoords Lookup position in texture coordinates
*/ */
vec3 computeGradientSobel(in sampler3D tex, in vec3 texCoords) { vec3 computeGradientSobel(in sampler3D tex, in TextureParameters3D texParams, in vec3 texCoords) {
const float sobelScale = 1.0 / 44.0; const float sobelScale = 1.0 / 44.0;
vec3 sobel = vec3(0.0); vec3 sobel = vec3(0.0);
float value = 0.0; float value = 0.0;
...@@ -210,7 +214,10 @@ vec3 computeGradientSobel(in sampler3D tex, in vec3 texCoords) { ...@@ -210,7 +214,10 @@ vec3 computeGradientSobel(in sampler3D tex, in vec3 texCoords) {
sobel.y += value; sobel.y += value;
sobel.z += value; sobel.z += value;
return sobelScale * sobel; //return sobelScale * sobel;
vec3 g = sobelScale*sobel* texParams._voxelSizeRCP * 0.5;
return (texParams._textureToWorldMatrixInvTransp * vec4(g, 0.0)).xyz;
} }
...@@ -308,4 +315,4 @@ vec3 computeEigenvalues(in mat3 hessian) { ...@@ -308,4 +315,4 @@ vec3 computeEigenvalues(in mat3 hessian) {
} }
return toReturn; return toReturn;
} }
\ No newline at end of file
...@@ -63,7 +63,7 @@ namespace campvis { ...@@ -63,7 +63,7 @@ namespace campvis {
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; break;
case SobelFilter: case SobelFilter:
toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientSobel(tex, texCoords)\n"); toReturn.append("#define computeGradient(tex, texParams, texCoords) computeGradientSobel(tex, texParams, texCoords)\n");
break; break;
default: default:
cgtAssert(false, "Invalid enum!"); cgtAssert(false, "Invalid enum!");
......
...@@ -1388,7 +1388,27 @@ Shader* ShaderManager::load(const std::string& vertFilename, const std::string& ...@@ -1388,7 +1388,27 @@ Shader* ShaderManager::load(const std::string& vertFilename, const std::string&
return loadWithCustomGlslVersion(vertFilename, geomFilename, fragFilename, customHeader, ""); return loadWithCustomGlslVersion(vertFilename, geomFilename, fragFilename, customHeader, "");
} }
Shader * ShaderManager::loadCompute(const std::string& compFilename, const std::string & customHeader, const std::string & customGlslVersion) throw(Exception) Shader * ShaderManager::loadCompute(const std::string & compFilename, const std::string & customHeader, const std::string & customGlslVersion) throw(Exception)
{
Shader* shader = nullptr;
do {
try {
shader = loadComputeInternal(compFilename, customHeader, customGlslVersion);
}
catch (const cgt::Exception& e) {
LERROR("Shader compilation of " << compFilename << " failed with exception:" << std::endl << e.what());
#ifdef CGT_DEBUG
cgtAssert(false, "Shader compilation failed! Ignore this assertion to retry compilation.");
#else
throw;
#endif
}
} while (!shader && std::getchar() != 'c');
return shader;
}
Shader * ShaderManager::loadComputeInternal(const std::string& compFilename, const std::string & customHeader, const std::string & customGlslVersion) throw(Exception)
{ {
//LDEBUG("Loading files " << vertFilename << " and " << fragFilename); //LDEBUG("Loading files " << vertFilename << " and " << fragFilename);
if (!GpuCaps.areComputeShadersSupported()) { if (!GpuCaps.areComputeShadersSupported()) {
...@@ -1427,7 +1447,27 @@ Shader * ShaderManager::loadCompute(const std::string& compFilename, const std:: ...@@ -1427,7 +1447,27 @@ Shader * ShaderManager::loadCompute(const std::string& compFilename, const std::
} }
} }
Shader* ShaderManager::loadWithCustomGlslVersion(const std::string& vertFilename, const std::string& geomFilename, const std::string& fragFilename, const std::string& customHeader, const std::string& customGlslVersion) throw(Exception) { Shader * ShaderManager::loadWithCustomGlslVersion(const std::string & vertFilename, const std::string & geomFilename, const std::string & fragFilename, const std::string & customHeader, const std::string & customGlslVersion) throw(Exception)
{
Shader* shader = nullptr;
do {
try {
shader = loadWithCustomGlslVersionInternal(vertFilename, geomFilename, fragFilename, customHeader, customGlslVersion);
}
catch (const cgt::Exception& e) {
#ifdef CGT_DEBUG
LERROR("Shader compilation of " << vertFilename << " | " << geomFilename << " | " << fragFilename << " failed with exception:" << std::endl << e.what());
cgtAssert(false, "Shader compilation failed! Ignore this assertion to retry compilation.");
#else
throw;
#endif
}
} while (!shader);
return shader;
}
Shader* ShaderManager::loadWithCustomGlslVersionInternal(const std::string& vertFilename, const std::string& geomFilename, const std::string& fragFilename, const std::string& customHeader, const std::string& customGlslVersion) throw(Exception) {
//LDEBUG("Loading files " << vertFilename << " and " << fragFilename); //LDEBUG("Loading files " << vertFilename << " and " << fragFilename);
if (!GpuCaps.areShadersSupported()) { if (!GpuCaps.areShadersSupported()) {
LERROR("Shaders are not supported."); LERROR("Shaders are not supported.");
......
...@@ -540,6 +540,9 @@ public: ...@@ -540,6 +540,9 @@ public:
const std::string& customHeader, const std::string& customGlslVersion) const std::string& customHeader, const std::string& customGlslVersion)
throw(Exception); throw(Exception);
/**
* Rebuilds all currently loaded shaders from the source file.
*/
bool rebuildAllShadersFromFile(); bool rebuildAllShadersFromFile();
/** /**
...@@ -575,6 +578,20 @@ public: ...@@ -575,6 +578,20 @@ public:
return defaultGlslVersion_; return defaultGlslVersion_;
} }
protected:
/**
* Actually loads the shader. \see loadCompute()
*/
Shader* loadComputeInternal(const std::string& compFilename, const std::string& customHeader, const std::string& customGlslVersion = "")
throw(Exception);
/**
* Actually loads the shader. \see loadWithCustomGlslVersion()
*/
Shader* loadWithCustomGlslVersionInternal(const std::string& vertFilename, const std::string& geomFilename, const std::string& fragFilename,
const std::string& customHeader, const std::string& customGlslVersion)
throw(Exception);
protected: protected:
std::string defaultGlslVersion_; ///< Default GLSL version string, will be added to the '#version' pragma at the beginning of each shader std::string defaultGlslVersion_; ///< Default GLSL version string, will be added to the '#version' pragma at the beginning of each shader
std::string globalHeader_; ///< Global header that will be added to all shaders. std::string globalHeader_; ///< Global header that will be added to all shaders.
......
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