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-09-12 17:13:56 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-12 17:13:56 +0400
commitebc653463ddfd9f8b893b6acbcc6465972e6abc6 (patch)
tree6b3cc2ba3f04994cf9f8d8f5bca6d63cfe2c9d1f /intern/cycles/render
parentc40492205b4369de3babe63b43d127ca622773ec (diff)
Cycles:
* Fix missing update when editing objects with emission materials. * Fix preview pass rendering set to 1 not showing full resolution. * Fix CUDA runtime compiling failing due to missing cache directory. * Use settings from first render layer for visibility and material override. And a bunch of incomplete and still disabled code mostly related to closure sampling.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/light.cpp60
-rw-r--r--intern/cycles/render/mesh.cpp5
-rw-r--r--intern/cycles/render/nodes.cpp13
-rw-r--r--intern/cycles/render/object.cpp12
-rw-r--r--intern/cycles/render/session.cpp2
-rw-r--r--intern/cycles/render/session.h2
-rw-r--r--intern/cycles/render/svm.cpp99
-rw-r--r--intern/cycles/render/svm.h6
-rw-r--r--intern/cycles/render/tile.cpp2
9 files changed, 167 insertions, 34 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index feb9e35e785..b13cab55404 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -55,6 +55,9 @@ LightManager::~LightManager()
void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
+ /* option to always sample all point lights */
+ bool multi_light = false;
+
/* count */
size_t num_lights = scene->lights.size();
size_t num_triangles = 0;
@@ -82,7 +85,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
}
- size_t num_distribution = num_triangles + num_lights;
+ size_t num_distribution = num_triangles;
+
+ if(!multi_light)
+ num_distribution += num_lights;
/* emission area */
float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
@@ -137,14 +143,16 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
float trianglearea = totarea;
/* point lights */
- float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
-
- for(size_t i = 0; i < scene->lights.size(); i++, offset++) {
- distribution[offset].x = totarea;
- distribution[offset].y = __int_as_float(-i-1);
- distribution[offset].z = 1.0f;
- distribution[offset].w = scene->lights[i]->radius;
- totarea += lightarea;
+ if(!multi_light) {
+ float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
+
+ for(size_t i = 0; i < scene->lights.size(); i++, offset++) {
+ distribution[offset].x = totarea;
+ distribution[offset].y = __int_as_float(-i-1);
+ distribution[offset].z = 1.0f;
+ distribution[offset].w = scene->lights[i]->radius;
+ totarea += lightarea;
+ }
}
/* normalize cumulative distribution functions */
@@ -163,28 +171,40 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
- kintegrator->use_emission = (totarea > 0.0f);
+ kintegrator->use_emission = (totarea > 0.0f) || (multi_light && num_lights);
if(kintegrator->use_emission) {
/* number of emissives */
- kintegrator->num_triangles = num_triangles;
- kintegrator->num_lights = num_lights;
- kintegrator->num_distribution = num_distribution;
+ kintegrator->num_distribution = (totarea > 0.0f)? num_distribution: 0;
/* precompute pdfs */
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
- if(trianglearea > 0.0f) {
- kintegrator->pdf_triangles = 1.0f/trianglearea;
+ if(multi_light) {
+ /* sample one of all triangles and all lights */
+ kintegrator->num_all_lights = num_lights;
+
+ if(trianglearea > 0.0f)
+ kintegrator->pdf_triangles = 1.0f/trianglearea;
if(num_lights)
- kintegrator->pdf_triangles *= 0.5f;
+ kintegrator->pdf_lights = 1.0f;
}
+ else {
+ /* sample one, with 0.5 probability of light or triangle */
+ kintegrator->num_all_lights = 0;
+
+ if(trianglearea > 0.0f) {
+ kintegrator->pdf_triangles = 1.0f/trianglearea;
+ if(num_lights)
+ kintegrator->pdf_triangles *= 0.5f;
+ }
- if(num_lights) {
- kintegrator->pdf_lights = 1.0f/num_lights;
- if(trianglearea > 0.0f)
- kintegrator->pdf_lights *= 0.5f;
+ if(num_lights) {
+ kintegrator->pdf_lights = 1.0f/num_lights;
+ if(trianglearea > 0.0f)
+ kintegrator->pdf_lights *= 0.5f;
+ }
}
/* CDF */
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index b73013fc378..7a6ce547486 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -21,6 +21,7 @@
#include "device.h"
#include "shader.h"
+#include "light.h"
#include "mesh.h"
#include "object.h"
#include "scene.h"
@@ -250,6 +251,10 @@ void Mesh::tag_update(Scene *scene, bool rebuild)
scene->mesh_manager->need_update = true;
scene->object_manager->need_update = true;
+
+ foreach(uint sindex, used_shaders)
+ if(scene->shaders[sindex]->has_surface_emission)
+ scene->light_manager->need_update = true;
}
/* Mesh Manager */
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 0ff774bce59..f2030256814 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1024,7 +1024,8 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
compiler.add_node(NODE_CLOSURE_BSDF,
compiler.encode_uchar4(closure,
(param1)? param1->stack_offset: SVM_STACK_INVALID,
- (param2)? param2->stack_offset: SVM_STACK_INVALID),
+ (param2)? param2->stack_offset: SVM_STACK_INVALID,
+ compiler.closure_mix_weight_offset()),
__float_as_int((param1)? param1->value.x: 0.0f),
__float_as_int((param2)? param2->value.x: 0.0f));
}
@@ -1222,8 +1223,6 @@ EmissionNode::EmissionNode()
void EmissionNode::compile(SVMCompiler& compiler)
{
- compiler.add_node(NODE_CLOSURE_EMISSION, CLOSURE_EMISSION_ID);
-
ShaderInput *color_in = input("Color");
ShaderInput *strength_in = input("Strength");
@@ -1236,6 +1235,8 @@ void EmissionNode::compile(SVMCompiler& compiler)
compiler.add_node(NODE_EMISSION_SET_WEIGHT_TOTAL, color_in->value * strength_in->value.x);
else
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value * strength_in->value.x);
+
+ compiler.add_node(NODE_CLOSURE_EMISSION, compiler.closure_mix_weight_offset());
}
void EmissionNode::compile(OSLCompiler& compiler)
@@ -1256,8 +1257,6 @@ BackgroundNode::BackgroundNode()
void BackgroundNode::compile(SVMCompiler& compiler)
{
- compiler.add_node(NODE_CLOSURE_BACKGROUND, CLOSURE_BACKGROUND_ID);
-
ShaderInput *color_in = input("Color");
ShaderInput *strength_in = input("Strength");
@@ -1268,6 +1267,8 @@ void BackgroundNode::compile(SVMCompiler& compiler)
}
else
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value*strength_in->value.x);
+
+ compiler.add_node(NODE_CLOSURE_BACKGROUND, CLOSURE_BACKGROUND_ID);
}
void BackgroundNode::compile(OSLCompiler& compiler)
@@ -1285,7 +1286,7 @@ HoldoutNode::HoldoutNode()
void HoldoutNode::compile(SVMCompiler& compiler)
{
- compiler.add_node(NODE_CLOSURE_HOLDOUT, CLOSURE_HOLDOUT_ID);
+ compiler.add_node(NODE_CLOSURE_HOLDOUT, compiler.closure_mix_weight_offset());
}
void HoldoutNode::compile(OSLCompiler& compiler)
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index fab051bde72..1059254d5c4 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -17,6 +17,7 @@
*/
#include "device.h"
+#include "light.h"
#include "mesh.h"
#include "object.h"
#include "scene.h"
@@ -83,8 +84,15 @@ void Object::apply_transform()
void Object::tag_update(Scene *scene)
{
- if(mesh && mesh->transform_applied)
- mesh->need_update = true;
+ if(mesh) {
+ if(mesh->transform_applied)
+ mesh->need_update = true;
+
+ foreach(uint sindex, mesh->used_shaders)
+ if(scene->shaders[sindex]->has_surface_emission)
+ scene->light_manager->need_update = true;
+ }
+
scene->mesh_manager->need_update = true;
scene->object_manager->need_update = true;
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 5fb687971ef..5eb8d51a816 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -35,7 +35,7 @@ Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.passes, params.tile_size, params.min_size)
{
- device_use_gl = ((params.device_type == DEVICE_CUDA || params.device_type == DEVICE_OPENCL) && !params.background);
+ device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background);
device = Device::create(params.device_type, params.background, params.threads);
buffers = new RenderBuffers(device);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 4d5cf434098..ca775939c09 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -58,7 +58,7 @@ public:
background = false;
output_path = "";
- progressive = false;
+ progressive = true;
passes = INT_MAX;
tile_size = 64;
min_size = 64;
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index da52eaecc18..c4188fda421 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -105,6 +105,7 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_man
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
background = false;
+ mix_weight_offset = SVM_STACK_INVALID;
}
int SVMCompiler::stack_size(ShaderSocketType type)
@@ -419,6 +420,84 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*> done, Stac
}
}
+void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset)
+{
+ /* todo: the weaks point here is that unlike the single closure sampling
+ we will evaluate all nodes even if they are used as input for closures
+ that are unused. it's not clear what would be the best way to skip such
+ nodes at runtime, especially if they are tangled up */
+
+ if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
+ ShaderInput *fin = node->input("Fac");
+ ShaderInput *cl1in = node->input("Closure1");
+ ShaderInput *cl2in = node->input("Closure2");
+
+ uint out1_offset = SVM_STACK_INVALID;
+ uint out2_offset = SVM_STACK_INVALID;
+
+ if(fin) {
+ /* mix closure */
+ set<ShaderNode*> dependencies;
+ find_dependencies(dependencies, done, fin);
+ generate_svm_nodes(dependencies, done);
+
+ stack_assign(fin);
+
+ if(cl1in->link)
+ out1_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
+ if(cl2in->link)
+ out2_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
+
+ add_node(NODE_MIX_CLOSURE,
+ encode_uchar4(fin->stack_offset, in_offset, out1_offset, out2_offset));
+ }
+ else {
+ /* add closure */
+ out1_offset = in_offset;
+ out2_offset = in_offset;
+ }
+
+ if(cl1in->link) {
+ generate_multi_closure(cl1in->link->parent, done, out1_offset);
+
+ if(fin)
+ active_stack.users[out1_offset]--;
+ }
+
+ if(cl2in->link) {
+ generate_multi_closure(cl2in->link->parent, done, out2_offset);
+
+ if(fin)
+ active_stack.users[out2_offset]--;
+ }
+ }
+ else {
+ /* execute dependencies for closure */
+ foreach(ShaderInput *in, node->inputs) {
+ if(!node_skip_input(node, in) && in->link) {
+ set<ShaderNode*> dependencies;
+ find_dependencies(dependencies, done, in);
+ generate_svm_nodes(dependencies, done);
+ }
+ }
+
+ mix_weight_offset = in_offset;
+
+ /* compile closure itself */
+ node->compile(*this);
+ stack_clear_users(node, done);
+ stack_clear_temporary(node);
+
+ mix_weight_offset = SVM_STACK_INVALID;
+
+ if(node->name == ustring("emission"))
+ current_shader->has_surface_emission = true;
+
+ /* end node is added outside of this */
+ }
+}
+
+
void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
{
/* Converting a shader graph into svm_nodes that can be executed
@@ -464,21 +543,35 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
}
if(clin->link) {
+ bool generate = false;
if(type == SHADER_TYPE_SURFACE) {
/* generate surface shader */
- generate_closure(clin->link->parent, set<ShaderNode*>(), Stack());
+ generate = true;
shader->has_surface = true;
}
else if(type == SHADER_TYPE_VOLUME) {
/* generate volume shader */
- generate_closure(clin->link->parent, set<ShaderNode*>(), Stack());
+ generate = true;
shader->has_volume = true;
}
else if(type == SHADER_TYPE_DISPLACEMENT) {
/* generate displacement shader */
- generate_closure(clin->link->parent, set<ShaderNode*>(), Stack());
+ generate = true;
shader->has_displacement = true;
}
+
+ if(generate) {
+ set<ShaderNode*> done;
+ bool multi_closure = false; /* __MULTI_CLOSURE__ */
+
+ if(multi_closure) {
+ generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
+ }
+ else {
+ Stack stack;
+ generate_closure(clin->link->parent, done, stack);
+ }
+ }
}
/* compile output node */
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index f76649e4a6f..05fb85b057f 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -24,6 +24,7 @@
#include "shader.h"
#include "util_set.h"
+#include "util_string.h"
CCL_NAMESPACE_BEGIN
@@ -65,6 +66,7 @@ public:
uint attribute(ustring name);
uint attribute(Attribute::Standard std);
uint encode_uchar4(uint x, uint y = 0, uint z = 0, uint w = 0);
+ uint closure_mix_weight_offset() { return mix_weight_offset; }
ShaderType output_type() { return current_type; }
@@ -75,6 +77,8 @@ public:
protected:
struct Stack {
+ Stack() { memset(users, 0, sizeof(users)); }
+
int users[SVM_STACK_SIZE];
};
@@ -88,6 +92,7 @@ protected:
void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
void generate_closure(ShaderNode *node, set<ShaderNode*> done, Stack stack);
+ void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset);
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
@@ -96,6 +101,7 @@ protected:
Shader *current_shader;
Stack active_stack;
int max_stack_use;
+ uint mix_weight_offset;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 450090c42f8..61f3af7aa10 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -96,7 +96,7 @@ void TileManager::set_tiles()
bool TileManager::done()
{
- return (state.pass+1 >= passes);
+ return (state.pass+1 >= passes && state.resolution == 1);
}
bool TileManager::next()