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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-25 21:23:52 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-01-25 21:23:52 +0400
commitf99343d3b8676543e2bd6acd6ee2274c21b1b388 (patch)
treefd40cd33691a783f82cf877e774d1b3a64d91ed3 /intern/cycles/render
parent14f475fccad7158098ddecc285c617f990b2f8b5 (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')
-rw-r--r--intern/cycles/render/buffers.cpp120
-rw-r--r--intern/cycles/render/buffers.h46
-rw-r--r--intern/cycles/render/film.cpp179
-rw-r--r--intern/cycles/render/film.h15
-rw-r--r--intern/cycles/render/object.cpp4
-rw-r--r--intern/cycles/render/object.h1
-rw-r--r--intern/cycles/render/shader.cpp5
-rw-r--r--intern/cycles/render/shader.h1
8 files changed, 324 insertions, 47 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 */
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index f4a9b37c09b..3062e5ae3e4 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -21,6 +21,10 @@
#include "device_memory.h"
+#include "film.h"
+
+#include "kernel_types.h"
+
#include "util_string.h"
#include "util_thread.h"
#include "util_types.h"
@@ -45,32 +49,16 @@ public:
int full_width;
int full_height;
- BufferParams()
- {
- width = 0;
- height = 0;
-
- full_x = 0;
- full_y = 0;
- full_width = 0;
- full_height = 0;
- }
-
- void get_offset_stride(int& offset, int& stride)
- {
- offset = -(full_x + full_y*width);
- stride = width;
- }
-
- bool 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);
- }
+ /* passes */
+ vector<Pass> passes;
+
+ /* functions */
+ BufferParams();
+
+ void get_offset_stride(int& offset, int& stride);
+ bool modified(const BufferParams& params);
+ void add_pass(PassType type);
+ int get_passes_size();
};
/* Render Buffers */
@@ -80,7 +68,7 @@ public:
/* buffer parameters */
BufferParams params;
/* float buffer */
- device_vector<float4> buffer;
+ device_vector<float> buffer;
/* random number generator state */
device_vector<uint> rng_state;
/* mutex, must be locked manually by callers */
@@ -90,7 +78,9 @@ public:
~RenderBuffers();
void reset(Device *device, BufferParams& params);
- float4 *copy_from_device(float exposure, int sample);
+
+ bool copy_from_device();
+ bool get_pass(PassType type, float exposure, int sample, int components, float *pixels);
protected:
void device_free();
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 0ae2866f182..bc51384b873 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -21,11 +21,111 @@
#include "film.h"
#include "scene.h"
+#include "util_foreach.h"
+
CCL_NAMESPACE_BEGIN
+/* Pass */
+
+void Pass::add(PassType type, vector<Pass>& passes)
+{
+ Pass pass;
+
+ pass.type = type;
+ pass.filter = true;
+ pass.exposure = false;
+
+ switch(type) {
+ case PASS_NONE:
+ pass.components = 0;
+ break;
+ case PASS_COMBINED:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_DEPTH:
+ pass.components = 1;
+ pass.filter = false;
+ break;
+ case PASS_NORMAL:
+ pass.components = 4;
+ break;
+ case PASS_UV:
+ pass.components = 4;
+ break;
+ case PASS_OBJECT_ID:
+ pass.components = 1;
+ pass.filter = false;
+ break;
+ case PASS_MATERIAL_ID:
+ pass.components = 1;
+ pass.filter = false;
+ break;
+ case PASS_DIFFUSE_COLOR:
+ pass.components = 4;
+ break;
+ case PASS_GLOSSY_COLOR:
+ pass.components = 4;
+ break;
+ case PASS_TRANSMISSION_COLOR:
+ pass.components = 4;
+ break;
+ case PASS_DIFFUSE_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_GLOSSY_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_TRANSMISSION_INDIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_DIFFUSE_DIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_GLOSSY_DIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_TRANSMISSION_DIRECT:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+
+ case PASS_EMISSION:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ case PASS_BACKGROUND:
+ pass.components = 4;
+ pass.exposure = true;
+ break;
+ }
+
+ passes.push_back(pass);
+}
+
+bool Pass::equals(const vector<Pass>& A, const vector<Pass>& B)
+{
+ if(A.size() != B.size())
+ return false;
+
+ for(int i = 0; i < A.size(); i++)
+ if(A[i].type != B[i].type)
+ return false;
+
+ return true;
+}
+
+/* Film */
+
Film::Film()
{
exposure = 0.8f;
+ Pass::add(PASS_COMBINED, passes);
need_update = true;
}
@@ -42,6 +142,82 @@ void Film::device_update(Device *device, DeviceScene *dscene)
/* update __data */
kfilm->exposure = exposure;
+ kfilm->pass_flag = 0;
+ kfilm->pass_stride = 0;
+ kfilm->use_light_pass = 0;
+
+ foreach(Pass& pass, passes) {
+ kfilm->pass_flag |= pass.type;
+
+ switch(pass.type) {
+ case PASS_COMBINED:
+ kfilm->pass_combined = kfilm->pass_stride;
+ break;
+ case PASS_DEPTH:
+ kfilm->pass_depth = kfilm->pass_stride;
+ break;
+ case PASS_NORMAL:
+ kfilm->pass_normal = kfilm->pass_stride;
+ break;
+ case PASS_UV:
+ kfilm->pass_uv = kfilm->pass_stride;
+ break;
+ case PASS_OBJECT_ID:
+ kfilm->pass_object_id = kfilm->pass_stride;
+ break;
+ case PASS_MATERIAL_ID:
+ kfilm->pass_material_id = kfilm->pass_stride;
+ break;
+ case PASS_DIFFUSE_COLOR:
+ kfilm->pass_diffuse_color = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_GLOSSY_COLOR:
+ kfilm->pass_glossy_color = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_TRANSMISSION_COLOR:
+ kfilm->pass_transmission_color = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_DIFFUSE_INDIRECT:
+ kfilm->pass_diffuse_indirect = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_GLOSSY_INDIRECT:
+ kfilm->pass_glossy_indirect = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_TRANSMISSION_INDIRECT:
+ kfilm->pass_transmission_indirect = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_DIFFUSE_DIRECT:
+ kfilm->pass_diffuse_direct = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_GLOSSY_DIRECT:
+ kfilm->pass_glossy_direct = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_TRANSMISSION_DIRECT:
+ kfilm->pass_transmission_direct = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+
+ case PASS_EMISSION:
+ kfilm->pass_emission = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ break;
+ case PASS_BACKGROUND:
+ kfilm->pass_background = kfilm->pass_stride;
+ kfilm->use_light_pass = 1;
+ case PASS_NONE:
+ break;
+ }
+
+ kfilm->pass_stride += pass.components;
+ }
need_update = false;
}
@@ -52,7 +228,8 @@ void Film::device_free(Device *device, DeviceScene *dscene)
bool Film::modified(const Film& film)
{
- return !(exposure == film.exposure);
+ return !(exposure == film.exposure
+ && Pass::equals(passes, film.passes));
}
void Film::tag_update(Scene *scene)
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index df24fad3725..511ad316460 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -20,6 +20,9 @@
#define __FILM_H__
#include "util_string.h"
+#include "util_vector.h"
+
+#include "kernel_types.h"
CCL_NAMESPACE_BEGIN
@@ -27,9 +30,21 @@ class Device;
class DeviceScene;
class Scene;
+class Pass {
+public:
+ PassType type;
+ int components;
+ bool filter;
+ bool exposure;
+
+ static void add(PassType type, vector<Pass>& passes);
+ static bool equals(const vector<Pass>& A, const vector<Pass>& B);
+};
+
class Film {
public:
float exposure;
+ vector<Pass> passes;
bool need_update;
Film();
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 3a9f0add735..f83c85c632d 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -36,6 +36,7 @@ Object::Object()
mesh = NULL;
tfm = transform_identity();
visibility = ~0;
+ pass_id = 0;
}
Object::~Object()
@@ -135,6 +136,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
/* todo: correct for displacement, and move to a better place */
float uniform_scale;
float surface_area = 0.0f;
+ float pass_id = ob->pass_id;
if(transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -171,7 +173,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
memcpy(&objects[offset], &tfm, sizeof(float4)*4);
memcpy(&objects[offset+4], &itfm, sizeof(float4)*4);
memcpy(&objects[offset+8], &ntfm, sizeof(float4)*4);
- objects[offset+12] = make_float4(surface_area, 0.0f, 0.0f, 0.0f);
+ objects[offset+12] = make_float4(surface_area, pass_id, 0.0f, 0.0f);
i++;
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 7fe83cf7d91..14da2cfb35d 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -41,6 +41,7 @@ public:
Transform tfm;
BoundBox bounds;
ustring name;
+ int pass_id;
vector<ParamValue> attributes;
uint visibility;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 6e827ec94bb..12968a79ab2 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -35,6 +35,7 @@ CCL_NAMESPACE_BEGIN
Shader::Shader()
{
name = "";
+ pass_id = 0;
graph = NULL;
graph_bump = NULL;
@@ -167,7 +168,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
if(scene->shaders.size() == 0)
return;
- uint shader_flag_size = scene->shaders.size()*2;
+ uint shader_flag_size = scene->shaders.size()*4;
uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
uint i = 0;
@@ -184,7 +185,9 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
flag |= SD_HOMOGENEOUS_VOLUME;
shader_flag[i++] = flag;
+ shader_flag[i++] = shader->pass_id;
shader_flag[i++] = flag;
+ shader_flag[i++] = shader->pass_id;
}
device->tex_alloc("__shader_flag", dscene->shader_flag);
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 45efa123ef6..35f3cfe27f5 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -47,6 +47,7 @@ class Shader {
public:
/* name */
string name;
+ int pass_id;
/* shader graph */
ShaderGraph *graph;