Merge branch 'blender2.7'
This commit is contained in:
@@ -42,6 +42,7 @@ BufferParams::BufferParams()
|
||||
|
||||
denoising_data_pass = false;
|
||||
denoising_clean_pass = false;
|
||||
denoising_prefiltered_pass = false;
|
||||
|
||||
Pass::add(PASS_COMBINED, passes);
|
||||
}
|
||||
@@ -73,6 +74,7 @@ int BufferParams::get_passes_size()
|
||||
if(denoising_data_pass) {
|
||||
size += DENOISING_PASS_SIZE_BASE;
|
||||
if(denoising_clean_pass) size += DENOISING_PASS_SIZE_CLEAN;
|
||||
if(denoising_prefiltered_pass) size += DENOISING_PASS_SIZE_PREFILTERED;
|
||||
}
|
||||
|
||||
return align_up(size, 4);
|
||||
@@ -88,6 +90,20 @@ int BufferParams::get_denoising_offset()
|
||||
return offset;
|
||||
}
|
||||
|
||||
int BufferParams::get_denoising_prefiltered_offset()
|
||||
{
|
||||
assert(denoising_prefiltered_pass);
|
||||
|
||||
int offset = get_denoising_offset();
|
||||
|
||||
offset += DENOISING_PASS_SIZE_BASE;
|
||||
if(denoising_clean_pass) {
|
||||
offset += DENOISING_PASS_SIZE_CLEAN;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Render Buffer Task */
|
||||
|
||||
RenderTile::RenderTile()
|
||||
@@ -153,81 +169,62 @@ bool RenderBuffers::get_denoising_pass_rect(int type, float exposure, int sample
|
||||
return false;
|
||||
}
|
||||
|
||||
float invsample = 1.0f/sample;
|
||||
float scale = invsample;
|
||||
bool variance = (type == DENOISING_PASS_NORMAL_VAR) ||
|
||||
(type == DENOISING_PASS_ALBEDO_VAR) ||
|
||||
(type == DENOISING_PASS_DEPTH_VAR) ||
|
||||
(type == DENOISING_PASS_COLOR_VAR);
|
||||
|
||||
float scale_exposure = scale;
|
||||
if(type == DENOISING_PASS_COLOR || type == DENOISING_PASS_CLEAN) {
|
||||
scale_exposure *= exposure;
|
||||
float scale = 1.0f;
|
||||
float alpha_scale = 1.0f/sample;
|
||||
if(type == DENOISING_PASS_PREFILTERED_COLOR ||
|
||||
type == DENOISING_PASS_CLEAN ||
|
||||
type == DENOISING_PASS_PREFILTERED_INTENSITY) {
|
||||
scale *= exposure;
|
||||
}
|
||||
else if(type == DENOISING_PASS_COLOR_VAR) {
|
||||
scale_exposure *= exposure*exposure;
|
||||
else if(type == DENOISING_PASS_PREFILTERED_VARIANCE) {
|
||||
scale *= exposure*exposure * (sample - 1);
|
||||
}
|
||||
|
||||
int offset;
|
||||
if(type == DENOISING_PASS_CLEAN) {
|
||||
/* The clean pass isn't changed by prefiltering, so we use the original one there. */
|
||||
offset = type + params.get_denoising_offset();
|
||||
}
|
||||
else if (type == DENOISING_PASS_PREFILTERED_COLOR && !params.denoising_prefiltered_pass) {
|
||||
/* If we're not saving the prefiltering result, return the original noisy pass. */
|
||||
offset = params.get_denoising_offset() + DENOISING_PASS_COLOR;
|
||||
scale /= sample;
|
||||
}
|
||||
else {
|
||||
offset = type + params.get_denoising_prefiltered_offset();
|
||||
}
|
||||
|
||||
int offset = type + params.get_denoising_offset();
|
||||
int pass_stride = params.get_passes_size();
|
||||
int size = params.width*params.height;
|
||||
|
||||
if(variance) {
|
||||
/* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
|
||||
* update does not work efficiently with atomics in the kernel. */
|
||||
int mean_offset = offset - components;
|
||||
float *mean = buffer.data() + mean_offset;
|
||||
float *var = buffer.data() + offset;
|
||||
assert(mean_offset >= 0);
|
||||
float *in = buffer.data() + offset;
|
||||
|
||||
if(components == 1) {
|
||||
for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels++) {
|
||||
pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale_exposure;
|
||||
}
|
||||
if(components == 1) {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
|
||||
pixels[0] = in[0]*scale;
|
||||
}
|
||||
else if(components == 3) {
|
||||
for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels += 3) {
|
||||
pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale_exposure;
|
||||
pixels[1] = max(0.0f, var[1] - mean[1]*mean[1]*invsample)*scale_exposure;
|
||||
pixels[2] = max(0.0f, var[2] - mean[2]*mean[2]*invsample)*scale_exposure;
|
||||
}
|
||||
}
|
||||
else if(components == 3) {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
|
||||
pixels[0] = in[0]*scale;
|
||||
pixels[1] = in[1]*scale;
|
||||
pixels[2] = in[2]*scale;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
else if(components == 4) {
|
||||
/* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
|
||||
assert(params.passes[0].type == PASS_COMBINED);
|
||||
float *in_combined = buffer.data();
|
||||
|
||||
for(int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
|
||||
pixels[0] = in[0]*scale;
|
||||
pixels[1] = in[1]*scale;
|
||||
pixels[2] = in[2]*scale;
|
||||
pixels[3] = saturate(in_combined[3]*alpha_scale);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float *in = buffer.data() + offset;
|
||||
|
||||
if(components == 1) {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
|
||||
pixels[0] = in[0]*scale_exposure;
|
||||
}
|
||||
}
|
||||
else if(components == 3) {
|
||||
for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
|
||||
pixels[0] = in[0]*scale_exposure;
|
||||
pixels[1] = in[1]*scale_exposure;
|
||||
pixels[2] = in[2]*scale_exposure;
|
||||
}
|
||||
}
|
||||
else if(components == 4) {
|
||||
assert(type == DENOISING_PASS_COLOR);
|
||||
|
||||
/* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
|
||||
assert(params.passes[0].type == PASS_COMBINED);
|
||||
float *in_combined = buffer.data();
|
||||
|
||||
for(int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
|
||||
pixels[0] = in[0]*scale_exposure;
|
||||
pixels[1] = in[1]*scale_exposure;
|
||||
pixels[2] = in[2]*scale_exposure;
|
||||
pixels[3] = saturate(in_combined[3]*scale);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user