[Bf-blender-cvs] [f478c2c] master: Cycles: Added support for light portals
Lukas Stockner
noreply at git.blender.org
Mon Apr 27 22:31:11 CEST 2015
Commit: f478c2cfbd3861cfca1d1a019066d30a4410a1f7
Author: Lukas Stockner
Date: Tue Apr 28 00:51:55 2015 +0500
Branches: master
https://developer.blender.org/rBf478c2cfbd3861cfca1d1a019066d30a4410a1f7
Cycles: Added support for light portals
This patch adds support for light portals: objects that help sampling the
environment light, therefore improving convergence. Using them tor other
lights in a unidirectional pathtracer is virtually useless.
The sampling is done with the area-preserving code already used for area lamps.
MIS is used both for combination of different portals and for combining portal-
and envmap-sampling.
The direction of portals is considered, they aren't used if the sampling point
is behind them.
Reviewers: sergey, dingto, #cycles
Reviewed By: dingto, #cycles
Subscribers: Lapineige, nutel, jtheninja, dsisco11, januz, vitorbalbio, candreacchio, TARDISMaker, lichtwerk, ace_dragon, marcog, mib2berlin, Tunge, lopataasdf, lordodin, sergey, dingto
Differential Revision: https://developer.blender.org/D1133
===================================================================
M intern/cycles/blender/addon/properties.py
M intern/cycles/blender/addon/ui.py
M intern/cycles/blender/blender_object.cpp
M intern/cycles/blender/blender_sync.h
M intern/cycles/kernel/kernel_emission.h
M intern/cycles/kernel/kernel_light.h
M intern/cycles/kernel/kernel_types.h
M intern/cycles/render/light.cpp
M intern/cycles/render/light.h
===================================================================
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 875b5d3..538876a 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -694,6 +694,12 @@ class CyclesLampSettings(bpy.types.PropertyGroup):
"reduces noise for area lamps and sharp glossy materials",
default=False,
)
+ cls.is_portal = BoolProperty(
+ name="Is Portal",
+ description="Use this area lamp to guide sampling of the background, "
+ "note that this will make the lamp invisible",
+ default=False,
+ )
@classmethod
def unregister(cls):
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 74de318..cdacad7 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -743,7 +743,10 @@ class CyclesLamp_PT_preview(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- return context.lamp and CyclesButtonsPanel.poll(context)
+ return context.lamp and \
+ not (context.lamp.type == 'AREA' and
+ context.lamp.cycles.is_portal) \
+ and CyclesButtonsPanel.poll(context)
def draw(self, context):
self.layout.template_preview(context.lamp)
@@ -781,13 +784,21 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
sub.prop(lamp, "size", text="Size X")
sub.prop(lamp, "size_y", text="Size Y")
- if cscene.progressive == 'BRANCHED_PATH':
- col.prop(clamp, "samples")
- col.prop(clamp, "max_bounces")
+ if not (lamp.type == 'AREA' and clamp.is_portal):
+ sub = col.column(align=True)
+ if cscene.progressive == 'BRANCHED_PATH':
+ sub.prop(clamp, "samples")
+ sub.prop(clamp, "max_bounces")
col = split.column()
- col.prop(clamp, "cast_shadow")
- col.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
+
+ sub = col.column(align=True)
+ sub.active = not (lamp.type == 'AREA' and clamp.is_portal)
+ sub.prop(clamp, "cast_shadow")
+ sub.prop(clamp, "use_multiple_importance_sampling", text="Multiple Importance")
+
+ if lamp.type == 'AREA':
+ col.prop(clamp, "is_portal", text="Portal")
if lamp.type == 'HEMI':
layout.label(text="Not supported, interpreted as sun lamp")
@@ -799,7 +810,9 @@ class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- return context.lamp and CyclesButtonsPanel.poll(context)
+ return context.lamp and not (context.lamp.type == 'AREA' and
+ context.lamp.cycles.is_portal) and \
+ CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 7364a8b..bcc3667 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -90,14 +90,17 @@ static uint object_ray_visibility(BL::Object b_ob)
/* Light */
-void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm)
+void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm, bool *use_portal)
{
/* test if we need to sync */
Light *light;
ObjectKey key(b_parent, persistent_id, b_ob);
- if(!light_map.sync(&light, b_ob, b_parent, key))
+ if(!light_map.sync(&light, b_ob, b_parent, key)) {
+ if(light->is_portal)
+ *use_portal = true;
return;
+ }
BL::Lamp b_lamp(b_ob.data());
@@ -171,6 +174,14 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
light->max_bounces = get_int(clamp, "max_bounces");
+ if(light->type == LIGHT_AREA)
+ light->is_portal = get_boolean(clamp, "is_portal");
+ else
+ light->is_portal = false;
+
+ if(light->is_portal)
+ *use_portal = true;
+
/* visibility */
uint visibility = object_ray_visibility(b_ob);
light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0;
@@ -182,7 +193,7 @@ void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSI
light->tag_update(scene);
}
-void BlenderSync::sync_background_light()
+void BlenderSync::sync_background_light(bool use_portal)
{
BL::World b_world = b_scene.world();
@@ -191,19 +202,20 @@ void BlenderSync::sync_background_light()
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
bool sample_as_light = get_boolean(cworld, "sample_as_light");
- if(sample_as_light) {
+ if(sample_as_light || use_portal) {
/* test if we need to sync */
Light *light;
ObjectKey key(b_world, 0, b_world);
if(light_map.sync(&light, b_world, b_world, key) ||
- world_recalc ||
- b_world.ptr.data != world_map)
+ world_recalc ||
+ b_world.ptr.data != world_map)
{
light->type = LIGHT_BACKGROUND;
light->map_resolution = get_int(cworld, "sample_map_resolution");
light->shader = scene->default_background;
-
+ light->use_mis = sample_as_light;
+
int samples = get_int(cworld, "samples");
if(get_boolean(cscene, "use_square_samples"))
light->samples = samples * samples;
@@ -223,7 +235,7 @@ void BlenderSync::sync_background_light()
/* Object */
Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
- Transform& tfm, uint layer_flag, float motion_time, bool hide_tris)
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
bool motion = motion_time != 0.0f;
@@ -232,7 +244,7 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
if(object_is_light(b_ob)) {
/* don't use lamps for excluded layers used as mask layer */
if(!motion && !((layer_flag & render_layer.holdout_layer) && (layer_flag & render_layer.exclude_layer)))
- sync_light(b_parent, persistent_id, b_ob, tfm);
+ sync_light(b_parent, persistent_id, b_ob, tfm, use_portal);
return NULL;
}
@@ -476,6 +488,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
int dupli_settings = preview ? 1 : 2;
bool cancel = false;
+ bool use_portal = false;
for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
@@ -506,7 +519,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
/* sync object and mesh or light data */
- Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris);
+ Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris, &use_portal);
/* sync possible particle data, note particle_id
* starts counting at 1, first is dummy particle */
@@ -526,7 +539,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
if(!object_render_hide(b_ob, true, true, hide_tris)) {
/* object itself */
Transform tfm = get_transform(b_ob.matrix_world());
- sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris);
+ sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris, &use_portal);
}
}
@@ -537,7 +550,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time)
progress.set_sync_status("");
if(!cancel && !motion) {
- sync_background_light();
+ sync_background_light(use_portal);
/* handle removed data and modified pointers */
if(light_map.post_sync())
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 5fbf2c3..89d93e1 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -86,9 +86,9 @@ private:
Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index = 0);
Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob,
- Transform& tfm, uint layer_flag, float motion_time, bool hide_tris);
- void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
- void sync_background_light();
+ Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal);
+ void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm, bool *use_portal);
+ void sync_background_light(bool use_portal);
void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time);
void sync_camera_motion(BL::Object b_ob, float motion_time);
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index d3cbc5c..6c5a5fa 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -254,7 +254,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg, PathState *sta
if(!(state->flag & PATH_RAY_MIS_SKIP) && res) {
/* multiple importance sampling, get background light pdf for ray
* direction, and compute weight with respect to BSDF pdf */
- float pdf = background_light_pdf(kg, ray->D);
+ float pdf = background_light_pdf(kg, ray->P, ray->D);
float mis_weight = power_heuristic(state->ray_pdf, pdf);
return L*mis_weight;
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 76fa754..d1b8db2 100644
---
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list