From 29a6433ab592146a279d995ab7e79d1b24b3bbb9 Mon Sep 17 00:00:00 2001 From: Debian Science Team Date: Mon, 21 Aug 2023 23:27:20 +0100 Subject: [PATCH] _fix_shader_crash commit bc4d0fec4f791fb198ff316849aaf3faba24b45a Author: Gaspard Thevenon Date: Thu Feb 10 10:19:39 2022 +0100 Fix shader crash in Multi Volume Rendering without GradientTF When using OpenGLGPUVolumeRayCastMapper with a MultiVolume, not specifying a gradient opacity TF produced an error in the composed shader (no argument would be given to functions which expected one), and nothing was rendered, although this TF is supposed to be optional. This commit fixes this by adding tests during the declarations of those functions inside the shader, and by changing their signatures as needed. Therefore, when no gradient opacity TF is given, no argument is expected and none is given. Gbp-Pq: Name 120_fix_shader_crash.patch --- .../vtkOpenGLGPUVolumeRayCastMapper.cxx | 25 ++++++++- .../VolumeOpenGL2/vtkVolumeShaderComposer.h | 56 +++++++++++++++---- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx index cdcec460..dfc65de0 100644 --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx @@ -2415,7 +2415,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::ReplaceShaderCompute( vtkvolume::ComputeGradientOpacityMulti1DDecl(this->AssembledInputs)); vtkShaderProgram::Substitute(fragmentShader, "//VTK::ComputeColor::Dec", - vtkvolume::ComputeColorMultiDeclaration(this->AssembledInputs)); + vtkvolume::ComputeColorMultiDeclaration( + this->AssembledInputs, vol->GetProperty()->HasGradientOpacity())); vtkShaderProgram::Substitute(fragmentShader, "//VTK::ComputeLighting::Dec", vtkvolume::ComputeLightingMultiDeclaration(ren, this, vol, numComps, independentComponents, @@ -2970,6 +2971,23 @@ bool vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateInputs(vtkRenderer* ren this->ForceTransferInit(); } + if (this->MultiVolume) + { + bool hasGradient = this->Parent->AssembledInputs[0].Volume->GetProperty()->HasGradientOpacity(); + for (auto& item : this->Parent->AssembledInputs) + { + if (item.second.Volume->GetProperty()->HasGradientOpacity() != hasGradient) + { + vtkGenericWarningMacro( + "Current implentation of vtkOpenGLGPUVolumeRayCastMapper does not support MultiVolume " + "where some volumes have a gradient opacity function and some others don't. " + "Rendering of the MultiVolume is disabled."); + success = false; + break; + } + } + } + return success; } @@ -3106,7 +3124,10 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, vtkVolume* vol this->Impl->MultiVolume = multiVol && this->GetInputCount() > 1 ? multiVol : nullptr; this->Impl->ClearRemovedInputs(renWin); - this->Impl->UpdateInputs(ren, vol); + if (!this->Impl->UpdateInputs(ren, vol)) + { + return; + } this->Impl->UpdateSamplingDistance(ren); this->Impl->UpdateTransfer2DYAxisArray(ren, vol); this->Impl->UpdateTransferFunctions(ren); diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 766f36ab..3406bfb4 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -1054,10 +1054,24 @@ std::string ComputeLightingMultiDeclaration(vtkRenderer* vtkNotUsed(ren), vtkVol int lightingComplexity) { vtkVolumeProperty* volProperty = vol->GetProperty(); - std::string shaderStr = std::string("\ + + std::string shaderStr = std::string(); + + // if no gradient TF is needed, don't add it into the function signature + if (volProperty->HasGradientOpacity()) + { + shaderStr += std::string("\ \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler2D gradientTF, const in sampler3D volume, const int volIdx, int component)\ \n {\ \n vec4 finalColor = vec4(0.0);"); + } + else + { + shaderStr += std::string("\ + \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler3D volume, const int volIdx, int component)\ + \n {\ + \n vec4 finalColor = vec4(0.0);"); + } // Shading for composite blending only int const shadeReqd = volProperty->GetShade() && @@ -1243,7 +1257,8 @@ std::string ComputeColorDeclaration(vtkRenderer* vtkNotUsed(ren), } //-------------------------------------------------------------------------- -std::string ComputeColorMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap& inputs) +std::string ComputeColorMultiDeclaration( + vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap& inputs, bool useGradientTF) { std::ostringstream ss; int i = 0; @@ -1274,13 +1289,28 @@ std::string ComputeColorMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::Volume } else { - ss << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " - "const in sampler2D gradientTF, const in sampler3D volume, const int volIdx)\n" - "{\n" - " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" - " vec2(scalar.w, 0.0)).xyz, opacity), gradientTF, volume, " - "volIdx, 0), 0.0, 1.0);\n" - "}\n"; + if (useGradientTF) + { + ss + << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " + "const in sampler2D gradientTF, const in sampler3D volume, const int volIdx)\n" + "{\n" + " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" + " vec2(scalar.w, 0.0)).xyz, opacity), gradientTF, volume, " + "volIdx, 0), 0.0, 1.0);\n" + "}\n"; + } + else + { + ss + << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " + "const in sampler3D volume, const int volIdx)\n" + "{\n" + " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" + " vec2(scalar.w, 0.0)).xyz, opacity), volume, " + "volIdx, 0), 0.0, 1.0);\n" + "}\n"; + } } return ss.str(); @@ -1828,14 +1858,18 @@ std::string ShadingMultipleInputs( if (property->GetTransferFunctionMode() == vtkVolumeProperty::TF_1D) { + std::string gradientopacity_param = (property->HasGradientOpacity()) + ? input.GradientOpacityTablesMap[0] + std::string(", ") + : std::string(); + toShaderStr << " g_srcColor.a = computeOpacity(scalar," << input.OpacityTablesMap[0] << ");\n" " if (g_srcColor.a > 0.0)\n" " {\n" " g_srcColor = computeColor(texPos, scalar, g_srcColor.a, " - << input.RGBTablesMap[0] << ", " << input.GradientOpacityTablesMap[0] << ", " - << "in_volume[" << i << "], " << i << ");\n"; + << input.RGBTablesMap[0] << ", " << gradientopacity_param << "in_volume[" << i + << "], " << i << ");\n"; if (property->HasGradientOpacity()) { -- 2.30.2