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.
This commit is contained in:
parent
78634b1fd1
commit
872a45f42b
Notes:
blender-bot
2023-02-13 15:17:42 +01:00
Referenced by issue #100749, Blender LTS: Maintenance Task 3.3 Referenced by issue #101601, Regression: Cryptomatte doesn't show all objects available Referenced by issue #98575, Issues with HDRIs and render result pixel values that exceed half float limits
|
@ -332,6 +332,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
|
|||
offset++;
|
||||
}
|
||||
}
|
||||
IMB_gpu_clamp_half_float(&extracted_buffer);
|
||||
|
||||
GPU_texture_update_sub(texture,
|
||||
GPU_DATA_FLOAT,
|
||||
|
@ -388,6 +389,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);
|
||||
}
|
||||
|
|
|
@ -894,6 +894,13 @@ eGPUTextureFormat IMB_gpu_get_texture_format(const struct ImBuf *ibuf,
|
|||
bool high_bitdepth,
|
||||
bool use_grayscale);
|
||||
|
||||
/**
|
||||
* 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().
|
||||
|
|
|
@ -370,3 +370,19 @@ eGPUTextureFormat IMB_gpu_get_texture_format(const ImBuf *ibuf,
|
|||
|
||||
return gpu_texture_format;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue