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
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-28 16:18:12 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-03-28 16:18:12 +0400
commite12adeb8c98d0ef211aba2cb5c0e87ff775fe217 (patch)
tree3a4381971596645f55401490e19a3672b28745ec /intern
parented61bfc9a6580360805a3daae1003df43a7f2c11 (diff)
Fix #30551: cycles passes combining did not always give identical result combined
with antialiasing/defocus, now divide out color at the very end instead of for each sample.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h11
-rw-r--r--intern/cycles/kernel/kernel_passes.h36
-rw-r--r--intern/cycles/render/buffers.cpp36
-rw-r--r--intern/cycles/render/film.cpp14
-rw-r--r--intern/cycles/render/film.h1
-rw-r--r--intern/cycles/util/util_math.h13
6 files changed, 70 insertions, 41 deletions
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 1e6605541ca..7ba50973444 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -266,17 +266,6 @@ __device_inline void path_radiance_accum_background(PathRadiance *L, float3 thro
#endif
}
-__device_inline float3 safe_divide_color(float3 a, float3 b)
-{
- float x, y, z;
-
- x = (b.x != 0.0f)? a.x/b.x: 0.0f;
- y = (b.y != 0.0f)? a.y/b.y: 0.0f;
- z = (b.z != 0.0f)? a.z/b.z: 0.0f;
-
- return make_float3(x, y, z);
-}
-
__device_inline float3 path_radiance_sum(PathRadiance *L)
{
#ifdef __PASSES__
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 51067630f09..d195af293b7 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -94,30 +94,18 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float
if(!kernel_data.film.use_light_pass)
return;
- if(flag & PASS_DIFFUSE_INDIRECT) {
- float3 color = safe_divide_color(L->indirect_diffuse, L->color_diffuse);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, color);
- }
- if(flag & PASS_GLOSSY_INDIRECT) {
- float3 color = safe_divide_color(L->indirect_glossy, L->color_glossy);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, color);
- }
- if(flag & PASS_TRANSMISSION_INDIRECT) {
- float3 color = safe_divide_color(L->indirect_transmission, L->color_transmission);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, color);
- }
- if(flag & PASS_DIFFUSE_DIRECT) {
- float3 color = safe_divide_color(L->direct_diffuse, L->color_diffuse);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, color);
- }
- if(flag & PASS_GLOSSY_DIRECT) {
- float3 color = safe_divide_color(L->direct_glossy, L->color_glossy);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, color);
- }
- if(flag & PASS_TRANSMISSION_DIRECT) {
- float3 color = safe_divide_color(L->direct_transmission, L->color_transmission);
- kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, color);
- }
+ if(flag & PASS_DIFFUSE_INDIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_indirect, sample, L->indirect_diffuse);
+ if(flag & PASS_GLOSSY_INDIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, L->indirect_glossy);
+ if(flag & PASS_TRANSMISSION_INDIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, L->indirect_transmission);
+ if(flag & PASS_DIFFUSE_DIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, L->direct_diffuse);
+ if(flag & PASS_GLOSSY_DIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, L->direct_glossy);
+ if(flag & PASS_TRANSMISSION_DIRECT)
+ kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, L->direct_transmission);
if(flag & PASS_EMISSION)
kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index da0453e5822..62a322b3a0f 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -173,13 +173,37 @@ bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int comp
else if(components == 3) {
assert(pass.components == 4);
- /* RGB/vector */
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
- float3 f = make_float3(in[0], in[1], in[2]);
+ if(pass.divide_type != PASS_NONE) {
+ /* RGB lighting passes that need to divide out color */
+ pass_offset = 0;
+ foreach(Pass& color_pass, params.passes) {
+ if(color_pass.type == pass.divide_type)
+ break;
+ pass_offset += color_pass.components;
+ }
+
+ float *in_divide = (float*)buffer.data_pointer + pass_offset;
+
+ for(int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) {
+ float3 f = make_float3(in[0], in[1], in[2]);
+ float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]);
+
+ f = safe_divide_color(f*exposure, f_divide);
+
+ pixels[0] = f.x;
+ pixels[1] = f.y;
+ pixels[2] = f.z;
+ }
+ }
+ else {
+ /* RGB/vector */
+ for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+ float3 f = make_float3(in[0], in[1], in[2]);
- pixels[0] = f.x*scale_exposure;
- pixels[1] = f.y*scale_exposure;
- pixels[2] = f.z*scale_exposure;
+ pixels[0] = f.x*scale_exposure;
+ pixels[1] = f.y*scale_exposure;
+ pixels[2] = f.z*scale_exposure;
+ }
}
}
else if(components == 4) {
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 5fd98e20240..ed4d0b2dcde 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -38,11 +38,16 @@ static bool compare_pass_order(const Pass& a, const Pass& b)
void Pass::add(PassType type, vector<Pass>& passes)
{
+ foreach(Pass& existing_pass, passes)
+ if(existing_pass.type == type)
+ return;
+
Pass pass;
pass.type = type;
pass.filter = true;
pass.exposure = false;
+ pass.divide_type = PASS_NONE;
switch(type) {
case PASS_NONE:
@@ -82,26 +87,32 @@ void Pass::add(PassType type, vector<Pass>& passes)
case PASS_DIFFUSE_INDIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_DIFFUSE_COLOR;
break;
case PASS_GLOSSY_INDIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_GLOSSY_COLOR;
break;
case PASS_TRANSMISSION_INDIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_TRANSMISSION_COLOR;
break;
case PASS_DIFFUSE_DIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_DIFFUSE_COLOR;
break;
case PASS_GLOSSY_DIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_GLOSSY_COLOR;
break;
case PASS_TRANSMISSION_DIRECT:
pass.components = 4;
pass.exposure = true;
+ pass.divide_type = PASS_TRANSMISSION_COLOR;
break;
case PASS_EMISSION:
@@ -127,6 +138,9 @@ void Pass::add(PassType type, vector<Pass>& passes)
/* order from by components, to ensure alignment so passes with size 4
come first and then passes with size 1 */
sort(passes.begin(), passes.end(), compare_pass_order);
+
+ if(pass.divide_type != PASS_NONE)
+ Pass::add(pass.divide_type, passes);
}
bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 511ad316460..8a3dbbf1b08 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -36,6 +36,7 @@ public:
int components;
bool filter;
bool exposure;
+ PassType divide_type;
static void add(PassType type, vector<Pass>& passes);
static bool equals(const vector<Pass>& A, const vector<Pass>& B);
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 0a1d8ff4555..51dbde3e28b 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -799,6 +799,19 @@ __device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
*b = cross(N, *a);
}
+/* Color division */
+
+__device_inline float3 safe_divide_color(float3 a, float3 b)
+{
+ float x, y, z;
+
+ x = (b.x != 0.0f)? a.x/b.x: 0.0f;
+ y = (b.y != 0.0f)? a.y/b.y: 0.0f;
+ z = (b.z != 0.0f)? a.z/b.z: 0.0f;
+
+ return make_float3(x, y, z);
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */