[Bf-blender-cvs] [03867370977] blender-v3.3-release: ImageEngine: Clamp image data to fit half float range.

Jeroen Bakker noreply at git.blender.org
Wed Oct 26 10:55:07 CEST 2022


Commit: 0386737097716870236d5e480f8ae1ec13e0b7a7
Author: Jeroen Bakker
Date:   Wed Oct 12 08:47:12 2022 +0200
Branches: blender-v3.3-release
https://developer.blender.org/rB0386737097716870236d5e480f8ae1ec13e0b7a7

ImageEngine: Clamp image data to fit half float range.

When image data exceeds half float ranges values are set to +/-
infinity that could lead to artifacts later on in the pipeline.
Color management for example.

This patch adds a utility function `IMB_gpu_clamp_half_float`
that clamps full float values to fit within the range of
half floats.

This fixes T98575 and T101601.

===================================================================

M	source/blender/draw/engines/image/image_drawing_mode.hh
M	source/blender/imbuf/IMB_imbuf.h
M	source/blender/imbuf/intern/util_gpu.c

===================================================================

diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index a1cd110e1d8..eb14ad6455a 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -335,6 +335,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
             offset++;
           }
         }
+        IMB_gpu_clamp_half_float(&extracted_buffer);
 
         GPU_texture_update_sub(texture,
                                GPU_DATA_FLOAT,
@@ -391,6 +392,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
       }
       BKE_image_release_ibuf(image, tile_buffer, lock);
     }
+    IMB_gpu_clamp_half_float(&texture_buffer);
     GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float);
     imb_freerectImbuf_all(&texture_buffer);
   }
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 99d931e7035..4e440bf3bdd 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -937,6 +937,13 @@ struct GPUTexture *IMB_create_gpu_texture(const char *name,
                                           struct ImBuf *ibuf,
                                           bool use_high_bitdepth,
                                           bool use_premult);
+/**
+ * Ensures that values stored in the float rect can safely loaded into half float gpu textures.
+ *
+ * Does nothing when given image_buffer doesn't contain a float rect.
+ */
+void IMB_gpu_clamp_half_float(struct ImBuf *image_buffer);
+
 /**
  * The `ibuf` is only here to detect the storage type. The produced texture will have undefined
  * content. It will need to be populated by using #IMB_update_gpu_texture_sub().
diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c
index 5feb0ceb515..8afa0c4e079 100644
--- a/source/blender/imbuf/intern/util_gpu.c
+++ b/source/blender/imbuf/intern/util_gpu.c
@@ -290,3 +290,19 @@ GPUTexture *IMB_create_gpu_texture(const char *name,
 
   return tex;
 }
+
+void IMB_gpu_clamp_half_float(ImBuf *image_buffer)
+{
+  const float half_min = -65504;
+  const float half_max = 65504;
+  if (!image_buffer->rect_float) {
+    return;
+  }
+
+  int rect_float_len = image_buffer->x * image_buffer->y *
+                       (image_buffer->channels == 0 ? 4 : image_buffer->channels);
+
+  for (int i = 0; i < rect_float_len; i++) {
+    image_buffer->rect_float[i] = clamp_f(image_buffer->rect_float[i], half_min, half_max);
+  }
+}



More information about the Bf-blender-cvs mailing list