diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-01-25 21:23:52 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-01-25 21:23:52 +0400 |
commit | f99343d3b8676543e2bd6acd6ee2274c21b1b388 (patch) | |
tree | fd40cd33691a783f82cf877e774d1b3a64d91ed3 /intern/cycles/render/buffers.cpp | |
parent | 14f475fccad7158098ddecc285c617f990b2f8b5 (diff) |
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
Diffstat (limited to 'intern/cycles/render/buffers.cpp')
-rw-r--r-- | intern/cycles/render/buffers.cpp | 120 |
1 files changed, 104 insertions, 16 deletions
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index a6bbbc91901..08dda944111 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -22,6 +22,7 @@ #include "device.h" #include "util_debug.h" +#include "util_foreach.h" #include "util_hash.h" #include "util_image.h" #include "util_math.h" @@ -31,6 +32,48 @@ CCL_NAMESPACE_BEGIN +/* Buffer Params */ + +BufferParams::BufferParams() +{ + width = 0; + height = 0; + + full_x = 0; + full_y = 0; + full_width = 0; + full_height = 0; + + Pass::add(PASS_COMBINED, passes); +} + +void BufferParams::get_offset_stride(int& offset, int& stride) +{ + offset = -(full_x + full_y*width); + stride = width; +} + +bool BufferParams::modified(const BufferParams& params) +{ + return !(full_x == params.full_x + && full_y == params.full_y + && width == params.width + && height == params.height + && full_width == params.full_width + && full_height == params.full_height + && Pass::equals(passes, params.passes)); +} + +int BufferParams::get_passes_size() +{ + int size = 0; + + foreach(Pass& pass, passes) + size += pass.components; + + return size; +} + /* Render Buffers */ RenderBuffers::RenderBuffers(Device *device_) @@ -64,7 +107,7 @@ void RenderBuffers::reset(Device *device, BufferParams& params_) device_free(); /* allocate buffer */ - buffer.resize(params.width, params.height); + buffer.resize(params.width*params.height*params.get_passes_size()); device->mem_alloc(buffer, MEM_READ_WRITE); device->mem_zero(buffer); @@ -82,31 +125,76 @@ void RenderBuffers::reset(Device *device, BufferParams& params_) device->mem_copy_to(rng_state); } -float4 *RenderBuffers::copy_from_device(float exposure, int sample) +bool RenderBuffers::copy_from_device() { if(!buffer.device_pointer) - return NULL; + return false; device->mem_copy_from(buffer, 0, params.width, params.height, sizeof(float4)); - float4 *out = new float4[params.width*params.height]; - float4 *in = (float4*)buffer.data_pointer; - float scale = 1.0f/(float)sample; - - for(int i = params.width*params.height - 1; i >= 0; i--) { - float4 rgba = in[i]*scale; + return true; +} + +bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int components, float *pixels) +{ + int pass_offset = 0; + + foreach(Pass& pass, params.passes) { + if(pass.type != type) { + pass_offset += pass.components; + continue; + } + + float *in = (float*)buffer.data_pointer + pass_offset; + int pass_stride = params.get_passes_size(); + + float scale = (pass.filter)? 1.0f/(float)sample: 1.0f; + float scale_exposure = (pass.exposure)? scale*exposure: scale; + + int size = params.width*params.height; + + if(components == 1) { + assert(pass.components == components); + + /* scalar */ + for(int i = 0; i < size; i++, in += pass_stride, pixels++) { + float f = *in; + + pixels[0] = f*scale_exposure; + } + } + 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]); + + pixels[0] = f.x*scale_exposure; + pixels[1] = f.y*scale_exposure; + pixels[2] = f.z*scale_exposure; + } + } + else if(components == 4) { + assert(pass.components == components); + + /* RGBA */ + for(int i = 0; i < size; i++, in += pass_stride, pixels += 4) { + float4 f = make_float4(in[0], in[1], in[2], in[3]); - rgba.x = rgba.x*exposure; - rgba.y = rgba.y*exposure; - rgba.z = rgba.z*exposure; + pixels[0] = f.x*scale_exposure; + pixels[1] = f.y*scale_exposure; + pixels[2] = f.z*scale_exposure; - /* clamp since alpha might be > 1.0 due to russian roulette */ - rgba.w = clamp(rgba.w, 0.0f, 1.0f); + /* clamp since alpha might be > 1.0 due to russian roulette */ + pixels[3] = clamp(f.w*scale, 0.0f, 1.0f); + } + } - out[i] = rgba; + return true; } - return out; + return false; } /* Display Buffer */ |