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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
rgba.x = rgba.x*exposure;
|
||||
rgba.y = rgba.y*exposure;
|
||||
rgba.z = rgba.z*exposure;
|
||||
bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int components, float *pixels)
|
||||
{
|
||||
int pass_offset = 0;
|
||||
|
||||
/* clamp since alpha might be > 1.0 due to russian roulette */
|
||||
rgba.w = clamp(rgba.w, 0.0f, 1.0f);
|
||||
foreach(Pass& pass, params.passes) {
|
||||
if(pass.type != type) {
|
||||
pass_offset += pass.components;
|
||||
continue;
|
||||
}
|
||||
|
||||
out[i] = rgba;
|
||||
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]);
|
||||
|
||||
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 */
|
||||
pixels[3] = clamp(f.w*scale, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return out;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Display Buffer */
|
||||
|
Reference in New Issue
Block a user