diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2019-09-05 13:47:20 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2019-09-11 13:19:44 +0300 |
commit | 7e61e597253f3ca75f2fb86a57212ca750ffbbe8 (patch) | |
tree | 6dbe0bf05fc3380f9729bf719ed1223997d5b0e3 /intern/cycles/kernel/kernel_film.h | |
parent | d4f8bc80a4bd69707a92e7141a2fb67d3f668c58 (diff) |
Cycles: Display RenderPass in Viewport
This change allows the user to select a renderpass in the 3d viewport.
Added support for external renderers to extend the `View3DShading` struct.
This way Blender doesn't need to know the features an external render engine wants to support.
Note that the View3DShading is also available in the scene->display.shading; although this is
supported, it does not make sense for render engines to put something here as it is really
scene/workbench related.
Currently cycles assumes that it always needs to calculate the combined pass; it ignores the
`pass_flag` in KernelFilm. We could optimize this but that was not in scope of this change
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D5689
Diffstat (limited to 'intern/cycles/kernel/kernel_film.h')
-rw-r--r-- | intern/cycles/kernel/kernel_film.h | 100 |
1 files changed, 75 insertions, 25 deletions
diff --git a/intern/cycles/kernel/kernel_film.h b/intern/cycles/kernel/kernel_film.h index d20f1adf663..7a974e9d852 100644 --- a/intern/cycles/kernel/kernel_film.h +++ b/intern/cycles/kernel/kernel_film.h @@ -16,18 +16,66 @@ CCL_NAMESPACE_BEGIN -ccl_device float4 film_map(KernelGlobals *kg, float4 irradiance, float scale) +ccl_device float4 film_get_pass_result(KernelGlobals *kg, + ccl_global float *buffer, + float sample_scale, + int index, + bool use_display_sample_scale) { - float exposure = kernel_data.film.exposure; - float4 result = irradiance * scale; + float4 pass_result; + + int display_pass_stride = kernel_data.film.display_pass_stride; + int display_pass_components = kernel_data.film.display_pass_components; + + if (display_pass_components == 4) { + ccl_global float4 *in = (ccl_global float4 *)(buffer + display_pass_stride + + index * kernel_data.film.pass_stride); + float alpha = use_display_sample_scale ? + (kernel_data.film.use_display_pass_alpha ? in->w : 1.0f / sample_scale) : + 1.0f; + + pass_result = make_float4(in->x, in->y, in->z, alpha); + + int display_divide_pass_stride = kernel_data.film.display_divide_pass_stride; + if (display_divide_pass_stride != -1) { + ccl_global float4 *divide_in = (ccl_global float4 *)(buffer + display_divide_pass_stride + + index * kernel_data.film.pass_stride); + if (divide_in->x != 0.0f) { + pass_result.x /= divide_in->x; + } + if (divide_in->y != 0.0f) { + pass_result.y /= divide_in->y; + } + if (divide_in->z != 0.0f) { + pass_result.z /= divide_in->z; + } + } + + if (kernel_data.film.use_display_exposure) { + float exposure = kernel_data.film.exposure; + pass_result *= make_float4(exposure, exposure, exposure, alpha); + } + } + else if (display_pass_components == 1) { + ccl_global float *in = (ccl_global float *)(buffer + display_pass_stride + + index * kernel_data.film.pass_stride); + pass_result = make_float4(*in, *in, *in, 1.0f / sample_scale); + } + + return pass_result; +} + +ccl_device float4 film_map(KernelGlobals *kg, float4 rgba_in, float scale) +{ + float4 result; /* conversion to srgb */ - result.x = color_linear_to_srgb(result.x * exposure); - result.y = color_linear_to_srgb(result.y * exposure); - result.z = color_linear_to_srgb(result.z * exposure); + result.x = color_linear_to_srgb(rgba_in.x); + result.y = color_linear_to_srgb(rgba_in.y); + result.z = color_linear_to_srgb(rgba_in.z); /* clamp since alpha might be > 1.0 due to russian roulette */ - result.w = saturate(result.w); + result.w = saturate(rgba_in.w); return result; } @@ -57,15 +105,22 @@ ccl_device void kernel_film_convert_to_byte(KernelGlobals *kg, /* buffer offset */ int index = offset + x + y * stride; + bool use_display_sample_scale = (kernel_data.film.display_divide_pass_stride == -1); + float4 rgba_in = film_get_pass_result(kg, buffer, sample_scale, index, use_display_sample_scale); + rgba += index; - buffer += index * kernel_data.film.pass_stride; /* map colors */ - float4 irradiance = *((ccl_global float4 *)buffer); - float4 float_result = film_map(kg, irradiance, sample_scale); - uchar4 byte_result = film_float_to_byte(float_result); - - *rgba = byte_result; + if (use_display_sample_scale) { + float4 float_result = film_map(kg, rgba_in, sample_scale); + uchar4 byte_result = film_float_to_byte(float_result); + *rgba = byte_result; + } + else { + float4 float_result = film_map(kg, rgba_in, 1.0); + uchar4 byte_result = film_float_to_byte(float_result); + *rgba = byte_result; + } } ccl_device void kernel_film_convert_to_half_float(KernelGlobals *kg, @@ -79,21 +134,16 @@ ccl_device void kernel_film_convert_to_half_float(KernelGlobals *kg, { /* buffer offset */ int index = offset + x + y * stride; + bool use_display_sample_scale = (kernel_data.film.display_divide_pass_stride == -1); + float4 rgba_in = film_get_pass_result(kg, buffer, sample_scale, index, use_display_sample_scale); - ccl_global float4 *in = (ccl_global float4 *)(buffer + index * kernel_data.film.pass_stride); ccl_global half *out = (ccl_global half *)rgba + index * 4; - - float exposure = kernel_data.film.exposure; - - float4 rgba_in = *in; - - if (exposure != 1.0f) { - rgba_in.x *= exposure; - rgba_in.y *= exposure; - rgba_in.z *= exposure; + if (use_display_sample_scale) { + float4_store_half(out, rgba_in, sample_scale); + } + else { + float4_store_half(out, rgba_in, 1.0f); } - - float4_store_half(out, rgba_in, sample_scale); } CCL_NAMESPACE_END |