Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-06-07 18:49:58 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-06-07 21:51:40 +0300
commitfb03f50e069d66c99391e4796e1b9eaa2b4cc133 (patch)
tree10c761cf548c6d4aa9160eed7c2798a96b798ccb /source/blender/imbuf
parentd05f27c7b95371db9e7e4e34a919a3623682a114 (diff)
Fix T64625: Eevee image textures with alpha have dark edges
Now texture storage of images is defined by the alpha mode of the image. The downside of this is that there can be artifacts near alpha edges where pixels with zero alpha bleed in. It also adds more code complexity since image textures are no longer all stored the same way. This changes allows us to keep using sRGB texture formats, which have edge darkening when stored with premultiplied alpha. Game engines seems to generally do the same thing, and we want to be compatible with them.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h12
-rw-r--r--source/blender/imbuf/intern/colormanagement.c59
2 files changed, 66 insertions, 5 deletions
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index a27945cc369..b12339aef6d 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -129,13 +129,21 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
struct ColorSpace *colorspace,
bool predivide);
-void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *rect,
+void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer,
const int x,
const int y,
const int width,
const int height,
const struct ImBuf *ibuf,
- const bool compress_as_srgb);
+ const bool compress_as_srgb,
+ const bool store_premultiplied);
+void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
+ const int offset_x,
+ const int offset_y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool store_premultiplied);
void IMB_colormanagement_scene_linear_to_color_picking_v3(float pixel[3]);
void IMB_colormanagement_color_picking_to_scene_linear_v3(float pixel[3]);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 583a3be8168..bec29252b6f 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2176,13 +2176,14 @@ void IMB_colormanagement_colorspace_to_scene_linear(float *buffer,
}
}
-void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *out_buffer,
+void IMB_colormanagement_imbuf_to_byte_texture(unsigned char *out_buffer,
const int offset_x,
const int offset_y,
const int width,
const int height,
const struct ImBuf *ibuf,
- const bool compress_as_srgb)
+ const bool compress_as_srgb,
+ const bool store_premultiplied)
{
/* Convert byte buffer for texture storage on the GPU. These have builtin
* support for converting sRGB to linear, which allows us to store textures
@@ -2197,7 +2198,7 @@ void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *out_buffer,
/* TODO(brecht): make this multithreaded, or at least process in batches. */
const unsigned char *in_buffer = (unsigned char *)ibuf->rect;
- const bool use_premultiply = IMB_alpha_affects_rgb(ibuf);
+ const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
for (int y = 0; y < height; y++) {
const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
@@ -2239,6 +2240,58 @@ void IMB_colormanagement_imbuf_to_srgb_texture(unsigned char *out_buffer,
}
}
+void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
+ const int offset_x,
+ const int offset_y,
+ const int width,
+ const int height,
+ const struct ImBuf *ibuf,
+ const bool store_premultiplied)
+{
+ /* Float texture are stored in scene linear color space, with premultiplied
+ * alpha depending on the image alpha mode. */
+ const float *in_buffer = ibuf->rect_float;
+ const int in_channels = ibuf->channels;
+ const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied;
+
+ for (int y = 0; y < height; y++) {
+ const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
+ const size_t out_offset = y * width;
+ const float *in = in_buffer + in_offset * 4;
+ float *out = out_buffer + out_offset * 4;
+
+ if (in_channels == 1) {
+ /* Copy single channel. */
+ for (int x = 0; x < width; x++, in += 1, out += 4) {
+ out[0] = in[0];
+ out[1] = in[0];
+ out[2] = in[0];
+ out[3] = in[0];
+ }
+ }
+ else if (in_channels == 3) {
+ /* Copy RGB. */
+ for (int x = 0; x < width; x++, in += 3, out += 4) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = 1.0f;
+ }
+ }
+ else if (in_channels == 4) {
+ /* Copy or convert RGBA. */
+ if (use_unpremultiply) {
+ for (int x = 0; x < width; x++, in += 4, out += 4) {
+ premul_to_straight_v4_v4(out, in);
+ }
+ }
+ else {
+ memcpy(out, in, sizeof(float) * 4 * width);
+ }
+ }
+ }
+}
+
/* Conversion between color picking role. Typically we would expect such a
* requirements:
* - It is approximately perceptually linear, so that the HSV numbers and