_fix_shader_crash
authorDebian Science Team <debian-science-maintainers@lists.alioth.debian.org>
Mon, 21 Aug 2023 22:27:20 +0000 (23:27 +0100)
committerMichael R. Crusoe <crusoe@debian.org>
Mon, 21 Aug 2023 22:27:20 +0000 (23:27 +0100)
commit bc4d0fec4f791fb198ff316849aaf3faba24b45a
Author: Gaspard Thevenon <gaspard.thevenon@kitware.com>
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

Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h

index cdcec460ef12c709d19b1a5923adb7111fcfccc5..dfc65de04be9d50cb9684a23b6eb72d580d4642a 100644 (file)
@@ -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);
index 766f36ab6320a5478a43ba981e97164b1f85151f..3406bfb4313d030058c8cc9e02cc4eaf11c50fad 100644 (file)
@@ -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())
           {