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>2011-08-28 17:55:59 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-08-28 17:55:59 +0400
commitbae896691aa3d7bb2a75292da3cc490894996b01 (patch)
tree9c3703f11ccdf76c575c2ea18b70dee1ff665913 /intern/cycles/render
parentd48e4fc92be346810baa8cac595ab0a735882a87 (diff)
Cycles:
* Add alpha pass output, to use set Transparent option in Film panel. * Add Holdout closure (OSL terminology), this is like the Sky option in the internal renderer, objects with this closure show the background / zero alpha. * Add option to use Gaussian instead of Box pixel filter in the UI. * Remove camera response curves for now, they don't really belong here in the pipeline, should be moved to compositor. * Output full float values for rendering now, previously was only byte precision. * Add a patch from Thomas to get a preview passes option, but still disabled because it isn't quite working right yet. * CUDA: don't compile shader graph evaluation inline. * Convert tabs to spaces in python files.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/CMakeLists.txt2
-rw-r--r--intern/cycles/render/background.cpp6
-rw-r--r--intern/cycles/render/background.h1
-rw-r--r--intern/cycles/render/buffers.cpp59
-rw-r--r--intern/cycles/render/buffers.h4
-rw-r--r--intern/cycles/render/camera.h2
-rw-r--r--intern/cycles/render/film.cpp72
-rw-r--r--intern/cycles/render/film.h2
-rw-r--r--intern/cycles/render/filter.cpp11
-rw-r--r--intern/cycles/render/filter.h7
-rw-r--r--intern/cycles/render/mesh.cpp2
-rw-r--r--intern/cycles/render/nodes.cpp18
-rw-r--r--intern/cycles/render/nodes.h5
-rw-r--r--intern/cycles/render/scene.h5
-rw-r--r--intern/cycles/render/session.cpp49
-rw-r--r--intern/cycles/render/session.h10
-rw-r--r--intern/cycles/render/tile.cpp12
-rw-r--r--intern/cycles/render/tile.h3
18 files changed, 163 insertions, 107 deletions
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index c3d5ae1ea05..14859aa4414 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -15,7 +15,6 @@ set(sources
buffers.cpp
camera.cpp
film.cpp
- film_response.cpp
filter.cpp
graph.cpp
image.cpp
@@ -39,7 +38,6 @@ set(headers
buffers.h
camera.h
film.h
- film_response.h
filter.h
graph.h
image.h
diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp
index 871fe128514..bf4131b6d38 100644
--- a/intern/cycles/render/background.cpp
+++ b/intern/cycles/render/background.cpp
@@ -31,6 +31,7 @@ CCL_NAMESPACE_BEGIN
Background::Background()
{
+ transparent = false;
need_update = true;
}
@@ -45,8 +46,9 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene
device_free(device, dscene);
- /* set shader index */
+ /* set shader index and transparent option */
KernelBackground *kbackground = &dscene->data.background;
+ kbackground->transparent = transparent;
kbackground->shader = scene->shader_manager->get_shader_id(scene->default_background);
need_update = false;
@@ -58,7 +60,7 @@ void Background::device_free(Device *device, DeviceScene *dscene)
bool Background::modified(const Background& background)
{
- return false;
+ return !(transparent == background.transparent);
}
void Background::tag_update(Scene *scene)
diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h
index a048cbc535c..16d2ccb6caa 100644
--- a/intern/cycles/render/background.h
+++ b/intern/cycles/render/background.h
@@ -29,6 +29,7 @@ class Scene;
class Background {
public:
+ bool transparent;
bool need_update;
Background();
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index c1d9158c85e..62dc17960ae 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -24,6 +24,7 @@
#include "util_debug.h"
#include "util_hash.h"
#include "util_image.h"
+#include "util_math.h"
#include "util_opengl.h"
#include "util_time.h"
#include "util_types.h"
@@ -84,6 +85,33 @@ void RenderBuffers::reset(Device *device, int width_, int height_)
device->mem_copy_to(rng_state);
}
+float4 *RenderBuffers::copy_from_device(float exposure, int pass)
+{
+ if(!buffer.device_pointer)
+ return NULL;
+
+ device->mem_copy_from(buffer, 0, buffer.memory_size());
+
+ float4 *out = new float4[width*height];
+ float4 *in = (float4*)buffer.data_pointer;
+ float scale = 1.0f/(float)pass;
+
+ for(int i = width*height - 1; i >= 0; i--) {
+ float4 rgba = in[i]*scale;
+
+ rgba.x = rgba.x*exposure;
+ rgba.y = rgba.y*exposure;
+ rgba.z = rgba.z*exposure;
+
+ /* clamp since alpha might be > 1.0 due to russian roulette */
+ rgba.w = clamp(rgba.w, 0.0f, 1.0f);
+
+ out[i] = rgba;
+ }
+
+ return out;
+}
+
/* Display Buffer */
DisplayBuffer::DisplayBuffer(Device *device_)
@@ -93,6 +121,7 @@ DisplayBuffer::DisplayBuffer(Device *device_)
height = 0;
draw_width = 0;
draw_height = 0;
+ transparent = true; /* todo: determine from background */
}
DisplayBuffer::~DisplayBuffer()
@@ -132,10 +161,36 @@ void DisplayBuffer::draw_set(int width_, int height_)
draw_height = height_;
}
+void DisplayBuffer::draw_transparency_grid()
+{
+ GLubyte checker_stipple_sml[32*32/8] = {
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ };
+
+ glColor4ub(50, 50, 50, 255);
+ glRectf(0, 0, width, height);
+ glEnable(GL_POLYGON_STIPPLE);
+ glColor4ub(55, 55, 55, 255);
+ glPolygonStipple(checker_stipple_sml);
+ glRectf(0, 0, width, height);
+ glDisable(GL_POLYGON_STIPPLE);
+}
+
void DisplayBuffer::draw(Device *device)
{
- if(draw_width != 0 && draw_height != 0)
- device->draw_pixels(rgba, 0, draw_width, draw_height, width, height);
+ if(draw_width != 0 && draw_height != 0) {
+ if(transparent)
+ draw_transparency_grid();
+
+ device->draw_pixels(rgba, 0, draw_width, draw_height, width, height, transparent);
+ }
}
bool DisplayBuffer::draw_ready()
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 1922f875d86..e99fedb0dff 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -47,6 +47,7 @@ public:
~RenderBuffers();
void reset(Device *device, int width, int height);
+ float4 *copy_from_device(float exposure, int pass);
protected:
void device_free();
@@ -67,6 +68,8 @@ public:
with progressive render we can be using only a subset of the buffer.
if these are zero, it means nothing can be drawn yet */
int draw_width, draw_height;
+ /* draw alpha channel? */
+ bool transparent;
/* byte buffer for tonemapped result */
device_vector<uchar4> rgba;
/* mutex, must be locked manually by callers */
@@ -83,6 +86,7 @@ public:
bool draw_ready();
protected:
+ void draw_transparency_grid();
void device_free();
Device *device;
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 6ae8c8fa4ae..d385aa274f4 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -19,8 +19,6 @@
#ifndef __CAMERA_H__
#define __CAMERA_H__
-#include "film_response.h"
-
#include "util_transform.h"
#include "util_types.h"
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 05874244605..657abd97f70 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -19,30 +19,13 @@
#include "camera.h"
#include "device.h"
#include "film.h"
-#include "film_response.h"
#include "scene.h"
CCL_NAMESPACE_BEGIN
-static FilmResponseType find_response_type(const string& name)
-{
- if(name == "" || name == "None")
- return FILM_RESPONSE_NONE;
-
- for(size_t i = 0; i < FILM_RESPONSE_NUM; i++) {
- FilmResponse *curve = &FILM_RESPONSE[i];
- if(curve->name == name)
- return (FilmResponseType)i;
- }
-
- return FILM_RESPONSE_NONE;
-}
-
Film::Film()
{
exposure = 0.8f;
- response = "Advantix 400";
- last_response = "";
need_update = true;
}
@@ -50,18 +33,6 @@ Film::~Film()
{
}
-#if 0
-static void generate_python_enum()
-{
- for(size_t i = 0; i < FILM_RESPONSE_NUM; i++) {
- FilmResponse *curve = &FILM_RESPONSE[i];
- /*if(i == 0 || strcmp(curve->brand, FILM_RESPONSE[i-1].brand))
- printf("(\"\", \"%s\", \"\"),\n", curve->brand);*/
- printf("(\"%s\", \"%s %s\", \"\"),\n", curve->name, curve->brand, curve->name);
- }
-}
-#endif
-
void Film::device_update(Device *device, DeviceScene *dscene)
{
if(!need_update)
@@ -72,57 +43,16 @@ void Film::device_update(Device *device, DeviceScene *dscene)
/* update __data */
kfilm->exposure = exposure;
- FilmResponseType response_type = find_response_type(response);
-
- /* update __response_curves */
- if(response != last_response) {
- device_free(device, dscene);
-
- if(response_type != FILM_RESPONSE_NONE) {
- FilmResponse *curve = &FILM_RESPONSE[response_type];
- size_t response_curve_size = FILM_RESPONSE_SIZE;
-
- dscene->response_curve_R.copy(curve->B_R, response_curve_size);
-
- if(curve->rgb) {
- dscene->response_curve_G.copy(curve->B_G, response_curve_size);
- dscene->response_curve_B.copy(curve->B_B, response_curve_size);
- }
- else {
- dscene->response_curve_G.copy(curve->B_R, response_curve_size);
- dscene->response_curve_B.copy(curve->B_R, response_curve_size);
- }
-
- device->tex_alloc("__response_curve_R", dscene->response_curve_R, true);
- device->tex_alloc("__response_curve_G", dscene->response_curve_G, true);
- device->tex_alloc("__response_curve_B", dscene->response_curve_B, true);
- }
-
- last_response = response;
- }
-
- kfilm->use_response_curve = (response_type != FILM_RESPONSE_NONE);
-
need_update = false;
}
void Film::device_free(Device *device, DeviceScene *dscene)
{
- device->tex_free(dscene->response_curve_R);
- device->tex_free(dscene->response_curve_G);
- device->tex_free(dscene->response_curve_B);
-
- dscene->response_curve_R.clear();
- dscene->response_curve_G.clear();
- dscene->response_curve_B.clear();
-
- last_response = "";
}
bool Film::modified(const Film& film)
{
- return !(response == film.response &&
- exposure == film.exposure &&
+ return !(exposure == film.exposure &&
pass == film.pass);
}
diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h
index 9d6c58b30d1..201fc174f4f 100644
--- a/intern/cycles/render/film.h
+++ b/intern/cycles/render/film.h
@@ -29,8 +29,6 @@ class Scene;
class Film {
public:
- string response;
- string last_response;
float exposure;
int pass;
bool need_update;
diff --git a/intern/cycles/render/filter.cpp b/intern/cycles/render/filter.cpp
index d7682bedc12..4925521e4a5 100644
--- a/intern/cycles/render/filter.cpp
+++ b/intern/cycles/render/filter.cpp
@@ -125,5 +125,16 @@ void Filter::device_free(Device *device, DeviceScene *dscene)
dscene->filter_table.clear();
}
+bool Filter::modified(const Filter& filter)
+{
+ return !(filter_type == filter.filter_type &&
+ filter_width == filter.filter_width);
+}
+
+void Filter::tag_update(Scene *scene)
+{
+ need_update = true;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/filter.h b/intern/cycles/render/filter.h
index 620e6ebe083..5df7bb8fd14 100644
--- a/intern/cycles/render/filter.h
+++ b/intern/cycles/render/filter.h
@@ -21,6 +21,10 @@
CCL_NAMESPACE_BEGIN
+class Device;
+class DeviceScene;
+class Scene;
+
typedef enum FilterType {
FILTER_BOX,
FILTER_GAUSSIAN
@@ -38,6 +42,9 @@ public:
void device_update(Device *device, DeviceScene *dscene);
void device_free(Device *device, DeviceScene *dscene);
+
+ bool modified(const Filter& filter);
+ void tag_update(Scene *scene);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index aae32851131..b9163309652 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -392,7 +392,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
progress.set_status("Updating Mesh", "Computing attributes");
/* gather per mesh requested attributes. as meshes may have multiple
- * shaders assigned, this merged the requested attributes that have
+ * shaders assigned, this merges the requested attributes that have
* been set per shader by the shader manager */
vector<AttributeRequestSet> mesh_attributes(scene->meshes.size());
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 546d74c5c22..5ffc3fbbabb 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1275,6 +1275,24 @@ void BackgroundNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_background");
}
+/* Holdout Closure */
+
+HoldoutNode::HoldoutNode()
+: ShaderNode("holdout")
+{
+ add_output("Holdout", SHADER_SOCKET_CLOSURE);
+}
+
+void HoldoutNode::compile(SVMCompiler& compiler)
+{
+ compiler.add_node(NODE_CLOSURE_HOLDOUT, CLOSURE_HOLDOUT_ID);
+}
+
+void HoldoutNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_holdout");
+}
+
/* Geometry */
GeometryNode::GeometryNode()
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index da3b743e79b..2afe585c3ac 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -257,6 +257,11 @@ public:
SHADER_NODE_CLASS(BackgroundNode)
};
+class HoldoutNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(HoldoutNode)
+};
+
class GeometryNode : public ShaderNode {
public:
SHADER_NODE_CLASS(GeometryNode)
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 965a0054846..9d475cd9fa5 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -84,11 +84,6 @@ public:
/* filter */
device_vector<float> filter_table;
- /* film */
- device_vector<float> response_curve_R;
- device_vector<float> response_curve_G;
- device_vector<float> response_curve_B;
-
/* integrator */
device_vector<uint> sobol_directions;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 56fbadcee08..5890714d740 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -52,6 +52,7 @@ Session::Session(const SessionParams& params_)
delayed_reset.do_reset = false;
delayed_reset.w = 0;
delayed_reset.h = 0;
+ delayed_reset.passes = 0;
display_outdated = false;
gpu_draw_ready = false;
@@ -95,7 +96,7 @@ bool Session::ready_to_reset()
/* GPU Session */
-void Session::reset_gpu(int w, int h)
+void Session::reset_gpu(int w, int h, int passes)
{
/* block for buffer acces and reset immediately. we can't do this
in the thread, because we need to allocate an OpenGL buffer, and
@@ -106,7 +107,7 @@ void Session::reset_gpu(int w, int h)
display_outdated = true;
reset_time = time_dt();
- reset_(w, h);
+ reset_(w, h, passes);
gpu_need_tonemap = false;
gpu_need_tonemap_cond.notify_all();
@@ -148,7 +149,14 @@ void Session::run_gpu()
start_time = time_dt();
reset_time = time_dt();
- while(!progress.get_cancel() && tile_manager.next()) {
+ while(!progress.get_cancel()) {
+ bool done = !tile_manager.next();
+
+ if(done && params.background)
+ break;
+
+ /* todo: wait when done in interactive mode */
+
/* buffers mutex is locked entirely while rendering each
pass, and released/reacquired on each iteration to allow
reset and draw in between */
@@ -193,7 +201,7 @@ void Session::run_gpu()
/* CPU Session */
-void Session::reset_cpu(int w, int h)
+void Session::reset_cpu(int w, int h, int passes)
{
thread_scoped_lock reset_lock(delayed_reset.mutex);
@@ -202,6 +210,7 @@ void Session::reset_cpu(int w, int h)
delayed_reset.w = w;
delayed_reset.h = h;
+ delayed_reset.passes = passes;
delayed_reset.do_reset = true;
device->task_cancel();
}
@@ -235,11 +244,18 @@ void Session::run_cpu()
thread_scoped_lock buffers_lock(buffers->mutex);
thread_scoped_lock display_lock(display->mutex);
- reset_(delayed_reset.w, delayed_reset.h);
+ reset_(delayed_reset.w, delayed_reset.h, delayed_reset.passes);
delayed_reset.do_reset = false;
}
- while(!progress.get_cancel() && tile_manager.next()) {
+ while(!progress.get_cancel()) {
+ bool done = !tile_manager.next();
+
+ if(done && params.background)
+ break;
+
+ /* todo: wait when done in interactive mode */
+
{
thread_scoped_lock buffers_lock(buffers->mutex);
@@ -266,7 +282,7 @@ void Session::run_cpu()
if(delayed_reset.do_reset) {
/* reset rendering if request from main thread */
delayed_reset.do_reset = false;
- reset_(delayed_reset.w, delayed_reset.h);
+ reset_(delayed_reset.w, delayed_reset.h, delayed_reset.passes);
}
else {
/* tonemap only if we do not reset, we don't we don't
@@ -313,7 +329,7 @@ bool Session::draw(int w, int h)
return draw_cpu(w, h);
}
-void Session::reset_(int w, int h)
+void Session::reset_(int w, int h, int passes)
{
if(w != buffers->width || h != buffers->height) {
gpu_draw_ready = false;
@@ -321,19 +337,28 @@ void Session::reset_(int w, int h)
display->reset(device, w, h);
}
- tile_manager.reset(w, h);
+ tile_manager.reset(w, h, passes);
start_time = time_dt();
preview_time = 0.0;
pass = 0;
}
-void Session::reset(int w, int h)
+void Session::reset(int w, int h, int passes)
{
if(device_use_gl)
- reset_gpu(w, h);
+ reset_gpu(w, h, passes);
else
- reset_cpu(w, h);
+ reset_cpu(w, h, passes);
+}
+
+void Session::set_passes(int passes)
+{
+ if(passes != params.passes) {
+ params.passes = passes;
+ tile_manager.set_passes(passes);
+ /* todo: awake in paused loop */
+ }
}
void Session::wait()
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 3411dcd23c6..18983f55353 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -107,13 +107,15 @@ public:
void wait();
bool ready_to_reset();
- void reset(int w, int h);
+ void reset(int w, int h, int passes);
+ void set_passes(int passes);
protected:
struct DelayedReset {
thread_mutex mutex;
bool do_reset;
int w, h;
+ int passes;
} delayed_reset;
void run();
@@ -123,15 +125,15 @@ protected:
void tonemap();
void path_trace(Tile& tile);
- void reset_(int w, int h);
+ void reset_(int w, int h, int passes);
void run_cpu();
bool draw_cpu(int w, int h);
- void reset_cpu(int w, int h);
+ void reset_cpu(int w, int h, int passes);
void run_gpu();
bool draw_gpu(int w, int h);
- void reset_gpu(int w, int h);
+ void reset_gpu(int w, int h, int passes);
TileManager tile_manager;
bool device_use_gl;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 28ea39e70ed..450090c42f8 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -25,18 +25,17 @@ CCL_NAMESPACE_BEGIN
TileManager::TileManager(bool progressive_, int passes_, int tile_size_, int min_size_)
{
progressive = progressive_;
- passes = passes_;
tile_size = tile_size_;
min_size = min_size_;
- reset(0, 0);
+ reset(0, 0, 0);
}
TileManager::~TileManager()
{
}
-void TileManager::reset(int width_, int height_)
+void TileManager::reset(int width_, int height_, int passes_)
{
full_width = width_;
full_height = height_;
@@ -54,6 +53,8 @@ void TileManager::reset(int width_, int height_)
}
}
+ passes = passes_;
+
state.width = 0;
state.height = 0;
state.pass = -1;
@@ -61,6 +62,11 @@ void TileManager::reset(int width_, int height_)
state.tiles.clear();
}
+void TileManager::set_passes(int passes_)
+{
+ passes = passes_;
+}
+
void TileManager::set_tiles()
{
int resolution = state.resolution;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index c3517b1e24d..56c69cdce88 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -50,7 +50,8 @@ public:
TileManager(bool progressive, int passes, int tile_size, int min_size);
~TileManager();
- void reset(int width, int height);
+ void reset(int width, int height, int passes);
+ void set_passes(int passes);
bool next();
bool done();