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:
Diffstat (limited to 'intern/cycles/kernel/kernel_film.h')
-rw-r--r--intern/cycles/kernel/kernel_film.h100
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