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:
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/app/CMakeLists.txt5
-rw-r--r--intern/cycles/app/io_export_cycles_xml.py3
-rw-r--r--intern/cycles/blender/addon/__init__.py31
-rw-r--r--intern/cycles/blender/addon/engine.py43
-rw-r--r--intern/cycles/blender/addon/properties.py2132
-rw-r--r--intern/cycles/blender/addon/ui.py1929
-rw-r--r--intern/cycles/blender/addon/version_update.py104
-rw-r--r--intern/cycles/blender/blender_camera.cpp6
-rw-r--r--intern/cycles/blender/blender_curves.cpp60
-rw-r--r--intern/cycles/blender/blender_mesh.cpp240
-rw-r--r--intern/cycles/blender/blender_object.cpp317
-rw-r--r--intern/cycles/blender/blender_particles.cpp8
-rw-r--r--intern/cycles/blender/blender_python.cpp86
-rw-r--r--intern/cycles/blender/blender_session.cpp360
-rw-r--r--intern/cycles/blender/blender_session.h15
-rw-r--r--intern/cycles/blender/blender_shader.cpp138
-rw-r--r--intern/cycles/blender/blender_sync.cpp313
-rw-r--r--intern/cycles/blender/blender_sync.h71
-rw-r--r--intern/cycles/blender/blender_texture.cpp6
-rw-r--r--intern/cycles/blender/blender_texture.h3
-rw-r--r--intern/cycles/blender/blender_util.h18
-rw-r--r--intern/cycles/device/device.cpp327
-rw-r--r--intern/cycles/device/device.h22
-rw-r--r--intern/cycles/device/device_cuda.cpp62
-rw-r--r--intern/cycles/device/device_multi.cpp9
-rw-r--r--intern/cycles/kernel/kernel_id_passes.h2
-rw-r--r--intern/cycles/kernel/kernel_light.h180
-rw-r--r--intern/cycles/kernel/kernel_passes.h2
-rw-r--r--intern/cycles/render/buffers.cpp6
-rw-r--r--intern/cycles/render/image.cpp33
-rw-r--r--intern/cycles/render/image.h4
-rw-r--r--intern/cycles/render/light.cpp13
-rw-r--r--intern/cycles/render/light.h1
-rw-r--r--intern/cycles/render/nodes.cpp33
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--intern/cycles/render/shader.cpp3
-rw-r--r--intern/cycles/render/shader.h1
-rw-r--r--intern/cycles/util/util_math_intersect.h22
-rw-r--r--intern/cycles/util/util_opengl.h8
-rw-r--r--intern/cycles/util/util_view.cpp2
40 files changed, 3431 insertions, 3189 deletions
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 2c1367a86dc..35c54fff8a4 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -60,6 +60,10 @@ link_directories(${OPENIMAGEIO_LIBPATH}
${TIFF_LIBPATH}
${OPENEXR_LIBPATH})
+if(WITH_OPENCOLORIO)
+ link_directories(${OPENCOLORIO_LIBPATH})
+endif()
+
add_definitions(${GL_DEFINITIONS})
include_directories(${INC})
@@ -84,7 +88,6 @@ macro(cycles_target_link_libraries target)
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
endif()
if(WITH_OPENCOLORIO)
- link_directories(${OPENCOLORIO_LIBPATH})
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
endif()
target_link_libraries(
diff --git a/intern/cycles/app/io_export_cycles_xml.py b/intern/cycles/app/io_export_cycles_xml.py
index 816536c0071..437a504d014 100644
--- a/intern/cycles/app/io_export_cycles_xml.py
+++ b/intern/cycles/app/io_export_cycles_xml.py
@@ -66,8 +66,7 @@ class RenderButtonsPanel():
@classmethod
def poll(self, context):
- rd = context.scene.render
- return rd.engine == 'CYCLES'
+ return context.engine == 'CYCLES'
class PHYSICS_PT_fluid_export(RenderButtonsPanel, bpy.types.Panel):
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 038126278aa..d222b4c8038 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -19,7 +19,7 @@
bl_info = {
"name": "Cycles Render Engine",
"author": "",
- "blender": (2, 76, 0),
+ "blender": (2, 80, 0),
"location": "Info header, render engine menu",
"description": "Cycles Render Engine integration",
"warning": "",
@@ -52,7 +52,7 @@ from . import (
class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES'
- bl_label = "Cycles Render"
+ bl_label = "Cycles"
bl_use_shading_nodes = True
bl_use_preview = True
bl_use_exclude_layers = True
@@ -66,34 +66,35 @@ class CyclesRender(bpy.types.RenderEngine):
engine.free(self)
# final render
- def update(self, data, scene):
+ def update(self, data, depsgraph):
if not self.session:
if self.is_preview:
cscene = bpy.context.scene.cycles
use_osl = cscene.shading_system and cscene.device == 'CPU'
- engine.create(self, data, scene,
- None, None, None, use_osl)
+ engine.create(self, data, preview_osl=use_osl)
else:
- engine.create(self, data, scene)
- else:
- engine.reset(self, data, scene)
+ engine.create(self, data)
+
+ engine.reset(self, data, depsgraph)
- def render(self, scene):
- engine.render(self)
+ def render(self, depsgraph):
+ engine.render(self, depsgraph)
- def bake(self, scene, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
- engine.bake(self, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
+ def bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
+ engine.bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
# viewport render
def view_update(self, context):
if not self.session:
- engine.create(self, context.blend_data, context.scene,
+ engine.create(self, context.blend_data,
context.region, context.space_data, context.region_data)
- engine.update(self, context.blend_data, context.scene)
+
+ engine.reset(self, context.blend_data, context.depsgraph)
+ engine.sync(self, context.depsgraph, context.blend_data)
def view_draw(self, context):
- engine.draw(self, context.region, context.space_data, context.region_data)
+ engine.draw(self, context.depsgraph, context.region, context.space_data, context.region_data)
def update_script_node(self, node):
if engine.with_osl():
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 23239ee4352..0b74150f981 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -133,13 +133,12 @@ def exit():
_cycles.exit()
-def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=False):
- import bpy
+def create(engine, data, region=None, v3d=None, rv3d=None, preview_osl=False):
import _cycles
+ import bpy
data = data.as_pointer()
userpref = bpy.context.user_preferences.as_pointer()
- scene = scene.as_pointer()
if region:
region = region.as_pointer()
if v3d:
@@ -147,12 +146,8 @@ def create(engine, data, scene, region=None, v3d=None, rv3d=None, preview_osl=Fa
if rv3d:
rv3d = rv3d.as_pointer()
- if bpy.app.debug_value == 256:
- _cycles.debug_flags_update(scene)
- else:
- _cycles.debug_flags_reset()
-
- engine.session = _cycles.create(engine.as_pointer(), userpref, data, scene, region, v3d, rv3d, preview_osl)
+ engine.session = _cycles.create(
+ engine.as_pointer(), userpref, data, region, v3d, rv3d, preview_osl)
def free(engine):
@@ -163,38 +158,46 @@ def free(engine):
del engine.session
-def render(engine):
+def render(engine, depsgraph):
import _cycles
if hasattr(engine, "session"):
- _cycles.render(engine.session)
+ _cycles.render(engine.session, depsgraph.as_pointer())
-def bake(engine, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
+def bake(engine, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
import _cycles
session = getattr(engine, "session", None)
if session is not None:
- _cycles.bake(engine.session, obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
+ _cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
-def reset(engine, data, scene):
+def reset(engine, data, depsgraph):
import _cycles
+ import bpy
+
+ if bpy.app.debug_value == 256:
+ _cycles.debug_flags_update(depsgraph.scene.as_pointer())
+ else:
+ _cycles.debug_flags_reset()
+
data = data.as_pointer()
- scene = scene.as_pointer()
- _cycles.reset(engine.session, data, scene)
+ depsgraph = depsgraph.as_pointer()
+ _cycles.reset(engine.session, data, depsgraph)
-def update(engine, data, scene):
+def sync(engine, depsgraph, data):
import _cycles
- _cycles.sync(engine.session)
+ _cycles.sync(engine.session, depsgraph.as_pointer())
-def draw(engine, region, v3d, rv3d):
+def draw(engine, depsgraph, region, v3d, rv3d):
import _cycles
+ depsgraph = depsgraph.as_pointer()
v3d = v3d.as_pointer()
rv3d = rv3d.as_pointer()
# draw render image
- _cycles.draw(engine.session, v3d, rv3d)
+ _cycles.draw(engine.session, depsgraph, v3d, rv3d)
def available_devices():
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index d986ba8c7a8..0d68138ffb4 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -17,12 +17,16 @@
# <pep8 compliant>
import bpy
-from bpy.props import (BoolProperty,
- EnumProperty,
- FloatProperty,
- IntProperty,
- PointerProperty,
- StringProperty)
+from bpy.props import (
+ BoolProperty,
+ EnumProperty,
+ FloatProperty,
+ IntProperty,
+ PointerProperty,
+ StringProperty,
+)
+
+from math import pi
# enums
@@ -154,586 +158,586 @@ enum_texture_limit = (
class CyclesRenderSettings(bpy.types.PropertyGroup):
- @classmethod
- def register(cls):
- bpy.types.Scene.cycles = PointerProperty(
- name="Cycles Render Settings",
- description="Cycles render settings",
- type=cls,
- )
- cls.device = EnumProperty(
- name="Device",
- description="Device to use for rendering",
- items=enum_devices,
- default='CPU',
- )
- cls.feature_set = EnumProperty(
- name="Feature Set",
- description="Feature set to use for rendering",
- items=enum_feature_set,
- default='SUPPORTED',
- )
- cls.shading_system = BoolProperty(
- name="Open Shading Language",
- description="Use Open Shading Language (CPU rendering only)",
- )
- cls.progressive = EnumProperty(
- name="Integrator",
- description="Method to sample lights and materials",
- items=enum_integrator,
- default='PATH',
- )
+ device: EnumProperty(
+ name="Device",
+ description="Device to use for rendering",
+ items=enum_devices,
+ default='CPU',
+ )
+ feature_set: EnumProperty(
+ name="Feature Set",
+ description="Feature set to use for rendering",
+ items=enum_feature_set,
+ default='SUPPORTED',
+ )
+ shading_system: BoolProperty(
+ name="Open Shading Language",
+ description="Use Open Shading Language (CPU rendering only)",
+ )
- cls.use_square_samples = BoolProperty(
- name="Square Samples",
- description="Square sampling values for easier artist control",
- default=False,
- )
+ progressive: EnumProperty(
+ name="Integrator",
+ description="Method to sample lights and materials",
+ items=enum_integrator,
+ default='PATH',
+ )
- cls.samples = IntProperty(
- name="Samples",
- description="Number of samples to render for each pixel",
- min=1, max=2147483647,
- default=128,
- )
- cls.preview_samples = IntProperty(
- name="Preview Samples",
- description="Number of samples to render in the viewport, unlimited if 0",
- min=0, max=2147483647,
- default=32,
- )
- cls.preview_pause = BoolProperty(
- name="Pause Preview",
- description="Pause all viewport preview renders",
- default=False,
- )
- cls.preview_active_layer = BoolProperty(
- name="Preview Active Layer",
- description="Preview active render layer in viewport",
- default=False,
- )
+ use_square_samples: BoolProperty(
+ name="Square Samples",
+ description="Square sampling values for easier artist control",
+ default=False,
+ )
- cls.aa_samples = IntProperty(
- name="AA Samples",
- description="Number of antialiasing samples to render for each pixel",
- min=1, max=2097151,
- default=128,
- )
- cls.preview_aa_samples = IntProperty(
- name="AA Samples",
- description="Number of antialiasing samples to render in the viewport, unlimited if 0",
- min=0, max=2097151,
- default=32,
- )
- cls.diffuse_samples = IntProperty(
- name="Diffuse Samples",
- description="Number of diffuse bounce samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
- cls.glossy_samples = IntProperty(
- name="Glossy Samples",
- description="Number of glossy bounce samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
- cls.transmission_samples = IntProperty(
- name="Transmission Samples",
- description="Number of transmission bounce samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
- cls.ao_samples = IntProperty(
- name="Ambient Occlusion Samples",
- description="Number of ambient occlusion samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
- cls.mesh_light_samples = IntProperty(
- name="Mesh Light Samples",
- description="Number of mesh emission light samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
+ samples: IntProperty(
+ name="Samples",
+ description="Number of samples to render for each pixel",
+ min=1, max=2147483647,
+ default=128,
+ )
+ preview_samples: IntProperty(
+ name="Preview Samples",
+ description="Number of samples to render in the viewport, unlimited if 0",
+ min=0, max=2147483647,
+ default=32,
+ )
+ preview_pause: BoolProperty(
+ name="Pause Preview",
+ description="Pause all viewport preview renders",
+ default=False,
+ )
+ aa_samples: IntProperty(
+ name="AA Samples",
+ description="Number of antialiasing samples to render for each pixel",
+ min=1, max=2097151,
+ default=128,
+ )
+ preview_aa_samples: IntProperty(
+ name="AA Samples",
+ description="Number of antialiasing samples to render in the viewport, unlimited if 0",
+ min=0, max=2097151,
+ default=32,
+ )
+ diffuse_samples: IntProperty(
+ name="Diffuse Samples",
+ description="Number of diffuse bounce samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
+ glossy_samples: IntProperty(
+ name="Glossy Samples",
+ description="Number of glossy bounce samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
+ transmission_samples: IntProperty(
+ name="Transmission Samples",
+ description="Number of transmission bounce samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
+ ao_samples: IntProperty(
+ name="Ambient Occlusion Samples",
+ description="Number of ambient occlusion samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
+ mesh_light_samples: IntProperty(
+ name="Mesh Light Samples",
+ description="Number of mesh emission light samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
- cls.subsurface_samples = IntProperty(
- name="Subsurface Samples",
- description="Number of subsurface scattering samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
+ subsurface_samples: IntProperty(
+ name="Subsurface Samples",
+ description="Number of subsurface scattering samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
- cls.volume_samples = IntProperty(
- name="Volume Samples",
- description="Number of volume scattering samples to render for each AA sample",
- min=1, max=1024,
- default=1,
- )
+ volume_samples: IntProperty(
+ name="Volume Samples",
+ description="Number of volume scattering samples to render for each AA sample",
+ min=1, max=1024,
+ default=1,
+ )
- cls.sampling_pattern = EnumProperty(
- name="Sampling Pattern",
- description="Random sampling pattern used by the integrator",
- items=enum_sampling_pattern,
- default='SOBOL',
- )
+ sampling_pattern: EnumProperty(
+ name="Sampling Pattern",
+ description="Random sampling pattern used by the integrator",
+ items=enum_sampling_pattern,
+ default='SOBOL',
+ )
- cls.use_layer_samples = EnumProperty(
- name="Layer Samples",
- description="How to use per render layer sample settings",
- items=enum_use_layer_samples,
- default='USE',
- )
+ use_layer_samples: EnumProperty(
+ name="Layer Samples",
+ description="How to use per render layer sample settings",
+ items=enum_use_layer_samples,
+ default='USE',
+ )
- cls.sample_all_lights_direct = BoolProperty(
- name="Sample All Direct Lights",
- description="Sample all lights (for direct samples), rather than randomly picking one",
- default=True,
- )
+ sample_all_lights_direct: BoolProperty(
+ name="Sample All Direct Lights",
+ description="Sample all lights (for direct samples), rather than randomly picking one",
+ default=True,
+ )
- cls.sample_all_lights_indirect = BoolProperty(
- name="Sample All Indirect Lights",
- description="Sample all lights (for indirect samples), rather than randomly picking one",
- default=True,
- )
- cls.light_sampling_threshold = FloatProperty(
- name="Light Sampling Threshold",
- description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
- "Zero disables the test and never ignores lights",
- min=0.0, max=1.0,
- default=0.01,
- )
+ sample_all_lights_indirect: BoolProperty(
+ name="Sample All Indirect Lights",
+ description="Sample all lights (for indirect samples), rather than randomly picking one",
+ default=True,
+ )
+ light_sampling_threshold: FloatProperty(
+ name="Light Sampling Threshold",
+ description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
+ "Zero disables the test and never ignores lights",
+ min=0.0, max=1.0,
+ default=0.01,
+ )
- cls.caustics_reflective = BoolProperty(
- name="Reflective Caustics",
- description="Use reflective caustics, resulting in a brighter image (more noise but added realism)",
- default=True,
- )
+ caustics_reflective: BoolProperty(
+ name="Reflective Caustics",
+ description="Use reflective caustics, resulting in a brighter image (more noise but added realism)",
+ default=True,
+ )
- cls.caustics_refractive = BoolProperty(
- name="Refractive Caustics",
- description="Use refractive caustics, resulting in a brighter image (more noise but added realism)",
- default=True,
- )
+ caustics_refractive: BoolProperty(
+ name="Refractive Caustics",
+ description="Use refractive caustics, resulting in a brighter image (more noise but added realism)",
+ default=True,
+ )
- cls.blur_glossy = FloatProperty(
- name="Filter Glossy",
- description="Adaptively blur glossy shaders after blurry bounces, "
- "to reduce noise at the cost of accuracy",
- min=0.0, max=10.0,
- default=1.0,
- )
+ blur_glossy: FloatProperty(
+ name="Filter Glossy",
+ description="Adaptively blur glossy shaders after blurry bounces, "
+ "to reduce noise at the cost of accuracy",
+ min=0.0, max=10.0,
+ default=1.0,
+ )
- cls.max_bounces = IntProperty(
- name="Max Bounces",
- description="Total maximum number of bounces",
- min=0, max=1024,
- default=12,
- )
+ max_bounces: IntProperty(
+ name="Max Bounces",
+ description="Total maximum number of bounces",
+ min=0, max=1024,
+ default=12,
+ )
- cls.diffuse_bounces = IntProperty(
- name="Diffuse Bounces",
- description="Maximum number of diffuse reflection bounces, bounded by total maximum",
- min=0, max=1024,
- default=4,
- )
- cls.glossy_bounces = IntProperty(
- name="Glossy Bounces",
- description="Maximum number of glossy reflection bounces, bounded by total maximum",
- min=0, max=1024,
- default=4,
- )
- cls.transmission_bounces = IntProperty(
- name="Transmission Bounces",
- description="Maximum number of transmission bounces, bounded by total maximum",
- min=0, max=1024,
- default=12,
- )
- cls.volume_bounces = IntProperty(
- name="Volume Bounces",
- description="Maximum number of volumetric scattering events",
- min=0, max=1024,
- default=0,
- )
+ diffuse_bounces: IntProperty(
+ name="Diffuse Bounces",
+ description="Maximum number of diffuse reflection bounces, bounded by total maximum",
+ min=0, max=1024,
+ default=4,
+ )
+ glossy_bounces: IntProperty(
+ name="Glossy Bounces",
+ description="Maximum number of glossy reflection bounces, bounded by total maximum",
+ min=0, max=1024,
+ default=4,
+ )
+ transmission_bounces: IntProperty(
+ name="Transmission Bounces",
+ description="Maximum number of transmission bounces, bounded by total maximum",
+ min=0, max=1024,
+ default=12,
+ )
+ volume_bounces: IntProperty(
+ name="Volume Bounces",
+ description="Maximum number of volumetric scattering events",
+ min=0, max=1024,
+ default=0,
+ )
- cls.transparent_max_bounces = IntProperty(
- name="Transparent Max Bounces",
- description="Maximum number of transparent bounces",
- min=0, max=1024,
- default=8,
- )
+ transparent_max_bounces: IntProperty(
+ name="Transparent Max Bounces",
+ description="Maximum number of transparent bounces",
+ min=0, max=1024,
+ default=8,
+ )
- cls.volume_step_size = FloatProperty(
- name="Step Size",
- description="Distance between volume shader samples when rendering the volume "
- "(lower values give more accurate and detailed results, but also increased render time)",
- default=0.1,
- min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4
- )
+ volume_step_size: FloatProperty(
+ name="Step Size",
+ description="Distance between volume shader samples when rendering the volume "
+ "(lower values give more accurate and detailed results, but also increased render time)",
+ default=0.1,
+ min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4
+ )
- cls.volume_max_steps = IntProperty(
- name="Max Steps",
- description="Maximum number of steps through the volume before giving up, "
- "to avoid extremely long render times with big objects or small step sizes",
- default=1024,
- min=2, max=65536
- )
+ volume_max_steps: IntProperty(
+ name="Max Steps",
+ description="Maximum number of steps through the volume before giving up, "
+ "to avoid extremely long render times with big objects or small step sizes",
+ default=1024,
+ min=2, max=65536
+ )
- cls.dicing_rate = FloatProperty(
- name="Dicing Rate",
- description="Size of a micropolygon in pixels",
- min=0.1, max=1000.0, soft_min=0.5,
- default=1.0,
- subtype="PIXEL"
- )
- cls.preview_dicing_rate = FloatProperty(
- name="Preview Dicing Rate",
- description="Size of a micropolygon in pixels during preview render",
- min=0.1, max=1000.0, soft_min=0.5,
- default=8.0,
- subtype="PIXEL"
- )
+ dicing_rate: FloatProperty(
+ name="Dicing Rate",
+ description="Size of a micropolygon in pixels",
+ min=0.1, max=1000.0, soft_min=0.5,
+ default=1.0,
+ subtype="PIXEL"
+ )
+ preview_dicing_rate: FloatProperty(
+ name="Preview Dicing Rate",
+ description="Size of a micropolygon in pixels during preview render",
+ min=0.1, max=1000.0, soft_min=0.5,
+ default=8.0,
+ subtype="PIXEL"
+ )
- cls.max_subdivisions = IntProperty(
- name="Max Subdivisions",
- description="Stop subdividing when this level is reached even if the dice rate would produce finer tessellation",
- min=0, max=16,
- default=12,
- )
+ max_subdivisions: IntProperty(
+ name="Max Subdivisions",
+ description="Stop subdividing when this level is reached even if the dice rate would produce finer tessellation",
+ min=0, max=16,
+ default=12,
+ )
- cls.dicing_camera = PointerProperty(
- name="Dicing Camera",
- description="Camera to use as reference point when subdividing geometry, useful to avoid crawling "
- "artifacts in animations when the scene camera is moving",
- type=bpy.types.Object,
- poll=lambda self, obj: obj.type == 'CAMERA',
- )
- cls.offscreen_dicing_scale = FloatProperty(
- name="Offscreen Dicing Scale",
- description="Multiplier for dicing rate of geometry outside of the camera view. The dicing rate "
- "of objects is gradually increased the further they are outside the camera view. "
- "Lower values provide higher quality reflections and shadows for off screen objects, "
- "while higher values use less memory",
- min=1.0, soft_max=25.0,
- default=4.0,
- )
+ dicing_camera: PointerProperty(
+ name="Dicing Camera",
+ description="Camera to use as reference point when subdividing geometry, useful to avoid crawling "
+ "artifacts in animations when the scene camera is moving",
+ type=bpy.types.Object,
+ poll=lambda self, obj: obj.type == 'CAMERA',
+ )
+ offscreen_dicing_scale: FloatProperty(
+ name="Offscreen Dicing Scale",
+ description="Multiplier for dicing rate of geometry outside of the camera view. The dicing rate "
+ "of objects is gradually increased the further they are outside the camera view. "
+ "Lower values provide higher quality reflections and shadows for off screen objects, "
+ "while higher values use less memory",
+ min=1.0, soft_max=25.0,
+ default=4.0,
+ )
- cls.film_exposure = FloatProperty(
- name="Exposure",
- description="Image brightness scale",
- min=0.0, max=10.0,
- default=1.0,
- )
- cls.film_transparent = BoolProperty(
- name="Transparent",
- description="World background is transparent, for compositing the render over another background",
- default=False,
- )
- cls.film_transparent_glass = BoolProperty(
- name="Transparent Glass",
- description="Render transmissive surfaces as transparent, for compositing glass over another background",
- default=False,
- )
- cls.film_transparent_roughness = FloatProperty(
- name="Transparent Roughness Threshold",
- description="For transparent transmission, keep surfaces with roughness above the threshold opaque",
- min=0.0, max=1.0,
- default=0.1,
- )
+ film_exposure: FloatProperty(
+ name="Exposure",
+ description="Image brightness scale",
+ min=0.0, max=10.0,
+ default=1.0,
+ )
+ film_transparent: BoolProperty(
+ name="Transparent",
+ description="World background is transparent, for compositing the render over another background",
+ default=False,
+ )
+ film_transparent_glass: BoolProperty(
+ name="Transparent Glass",
+ description="Render transmissive surfaces as transparent, for compositing glass over another background",
+ default=False,
+ )
+ film_transparent_roughness: FloatProperty(
+ name="Transparent Roughness Threshold",
+ description="For transparent transmission, keep surfaces with roughness above the threshold opaque",
+ min=0.0, max=1.0,
+ default=0.1,
+ )
- # Really annoyingly, we have to keep it around for a few releases,
- # otherwise forward compatibility breaks in really bad manner: CRASH!
- #
- # TODO(sergey): Remove this during 2.8x series of Blender.
- cls.filter_type = EnumProperty(
- name="Filter Type",
- description="Pixel filter type",
- items=enum_filter_types,
- default='BLACKMAN_HARRIS',
- )
+ # Really annoyingly, we have to keep it around for a few releases,
+ # otherwise forward compatibility breaks in really bad manner: CRASH!
+ #
+ # TODO(sergey): Remove this during 2.8x series of Blender.
+ filter_type: EnumProperty(
+ name="Filter Type",
+ description="Pixel filter type",
+ items=enum_filter_types,
+ default='BLACKMAN_HARRIS',
+ )
- cls.pixel_filter_type = EnumProperty(
- name="Filter Type",
- description="Pixel filter type",
- items=enum_filter_types,
- default='BLACKMAN_HARRIS',
- )
+ pixel_filter_type: EnumProperty(
+ name="Filter Type",
+ description="Pixel filter type",
+ items=enum_filter_types,
+ default='BLACKMAN_HARRIS',
+ )
- cls.filter_width = FloatProperty(
- name="Filter Width",
- description="Pixel filter width",
- min=0.01, max=10.0,
- default=1.5,
- )
+ filter_width: FloatProperty(
+ name="Filter Width",
+ description="Pixel filter width",
+ min=0.01, max=10.0,
+ default=1.5,
+ )
- cls.seed = IntProperty(
- name="Seed",
- description="Seed value for integrator to get different noise patterns",
- min=0, max=2147483647,
- default=0,
- )
+ seed: IntProperty(
+ name="Seed",
+ description="Seed value for integrator to get different noise patterns",
+ min=0, max=2147483647,
+ default=0,
+ )
- cls.use_animated_seed = BoolProperty(
- name="Use Animated Seed",
- description="Use different seed values (and hence noise patterns) at different frames",
- default=False,
- )
+ use_animated_seed: BoolProperty(
+ name="Use Animated Seed",
+ description="Use different seed values (and hence noise patterns) at different frames",
+ default=False,
+ )
- cls.sample_clamp_direct = FloatProperty(
- name="Clamp Direct",
- description="If non-zero, the maximum value for a direct sample, "
- "higher values will be scaled down to avoid too "
- "much noise and slow convergence at the cost of accuracy",
- min=0.0, max=1e8,
- default=0.0,
- )
+ sample_clamp_direct: FloatProperty(
+ name="Clamp Direct",
+ description="If non-zero, the maximum value for a direct sample, "
+ "higher values will be scaled down to avoid too "
+ "much noise and slow convergence at the cost of accuracy",
+ min=0.0, max=1e8,
+ default=0.0,
+ )
- cls.sample_clamp_indirect = FloatProperty(
- name="Clamp Indirect",
- description="If non-zero, the maximum value for an indirect sample, "
- "higher values will be scaled down to avoid too "
- "much noise and slow convergence at the cost of accuracy",
- min=0.0, max=1e8,
- default=10.0,
- )
+ sample_clamp_indirect: FloatProperty(
+ name="Clamp Indirect",
+ description="If non-zero, the maximum value for an indirect sample, "
+ "higher values will be scaled down to avoid too "
+ "much noise and slow convergence at the cost of accuracy",
+ min=0.0, max=1e8,
+ default=10.0,
+ )
- cls.debug_tile_size = IntProperty(
- name="Tile Size",
- description="",
- min=1, max=4096,
- default=1024,
- )
+ debug_tile_size: IntProperty(
+ name="Tile Size",
+ description="",
+ min=1, max=4096,
+ default=1024,
+ )
- cls.preview_start_resolution = IntProperty(
- name="Start Resolution",
- description="Resolution to start rendering preview at, "
- "progressively increasing it to the full viewport size",
- min=8, max=16384,
- default=64,
- )
+ preview_start_resolution: IntProperty(
+ name="Start Resolution",
+ description="Resolution to start rendering preview at, "
+ "progressively increasing it to the full viewport size",
+ min=8, max=16384,
+ default=64,
+ )
- cls.debug_reset_timeout = FloatProperty(
- name="Reset timeout",
- description="",
- min=0.01, max=10.0,
- default=0.1,
- )
- cls.debug_cancel_timeout = FloatProperty(
- name="Cancel timeout",
- description="",
- min=0.01, max=10.0,
- default=0.1,
- )
- cls.debug_text_timeout = FloatProperty(
- name="Text timeout",
- description="",
- min=0.01, max=10.0,
- default=1.0,
- )
+ debug_reset_timeout: FloatProperty(
+ name="Reset timeout",
+ description="",
+ min=0.01, max=10.0,
+ default=0.1,
+ )
+ debug_cancel_timeout: FloatProperty(
+ name="Cancel timeout",
+ description="",
+ min=0.01, max=10.0,
+ default=0.1,
+ )
+ debug_text_timeout: FloatProperty(
+ name="Text timeout",
+ description="",
+ min=0.01, max=10.0,
+ default=1.0,
+ )
- cls.debug_bvh_type = EnumProperty(
- name="Viewport BVH Type",
- description="Choose between faster updates, or faster render",
- items=enum_bvh_types,
- default='DYNAMIC_BVH',
- )
- cls.debug_use_spatial_splits = BoolProperty(
- name="Use Spatial Splits",
- description="Use BVH spatial splits: longer builder time, faster render",
- default=False,
- )
- cls.debug_use_hair_bvh = BoolProperty(
- name="Use Hair BVH",
- description="Use special type BVH optimized for hair (uses more ram but renders faster)",
- default=True,
- )
- cls.use_bvh_embree = BoolProperty(
- name="Use Embree",
- description="Use Embree as ray accelerator",
- default=False,
- )
- cls.debug_bvh_time_steps = IntProperty(
- name="BVH Time Steps",
- description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
- default=0,
- min=0, max=16,
- )
- cls.tile_order = EnumProperty(
- name="Tile Order",
- description="Tile order for rendering",
- items=enum_tile_order,
- default='HILBERT_SPIRAL',
- options=set(), # Not animatable!
- )
- cls.use_progressive_refine = BoolProperty(
- name="Progressive Refine",
- description="Instead of rendering each tile until it is finished, "
- "refine the whole image progressively "
- "(this renders somewhat slower, "
- "but time can be saved by manually stopping the render when the noise is low enough)",
- default=False,
- )
+ debug_bvh_type: EnumProperty(
+ name="Viewport BVH Type",
+ description="Choose between faster updates, or faster render",
+ items=enum_bvh_types,
+ default='DYNAMIC_BVH',
+ )
+ use_bvh_embree: BoolProperty(
+ name="Use Embree",
+ description="Use Embree as ray accelerator",
+ default=False,
+ )
+ debug_use_spatial_splits: BoolProperty(
+ name="Use Spatial Splits",
+ description="Use BVH spatial splits: longer builder time, faster render",
+ default=False,
+ )
+ debug_use_hair_bvh: BoolProperty(
+ name="Use Hair BVH",
+ description="Use special type BVH optimized for hair (uses more ram but renders faster)",
+ default=True,
+ )
+ debug_bvh_time_steps: IntProperty(
+ name="BVH Time Steps",
+ description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
+ default=0,
+ min=0, max=16,
+ )
+ tile_order: EnumProperty(
+ name="Tile Order",
+ description="Tile order for rendering",
+ items=enum_tile_order,
+ default='HILBERT_SPIRAL',
+ options=set(), # Not animatable!
+ )
+ use_progressive_refine: BoolProperty(
+ name="Progressive Refine",
+ description="Instead of rendering each tile until it is finished, "
+ "refine the whole image progressively "
+ "(this renders somewhat slower, "
+ "but time can be saved by manually stopping the render when the noise is low enough)",
+ default=False,
+ )
- cls.bake_type = EnumProperty(
- name="Bake Type",
- default='COMBINED',
- description="Type of pass to bake",
- items=(
- ('COMBINED', "Combined", ""),
- ('AO', "Ambient Occlusion", ""),
- ('SHADOW', "Shadow", ""),
- ('NORMAL', "Normal", ""),
- ('UV', "UV", ""),
- ('ROUGHNESS', "Roughness", ""),
- ('EMIT', "Emit", ""),
- ('ENVIRONMENT', "Environment", ""),
- ('DIFFUSE', "Diffuse", ""),
- ('GLOSSY', "Glossy", ""),
- ('TRANSMISSION', "Transmission", ""),
- ('SUBSURFACE', "Subsurface", ""),
- ),
- )
+ bake_type: EnumProperty(
+ name="Bake Type",
+ default='COMBINED',
+ description="Type of pass to bake",
+ items=(
+ ('COMBINED', "Combined", ""),
+ ('AO', "Ambient Occlusion", ""),
+ ('SHADOW', "Shadow", ""),
+ ('NORMAL', "Normal", ""),
+ ('UV', "UV", ""),
+ ('ROUGHNESS', "Roughness", ""),
+ ('EMIT', "Emit", ""),
+ ('ENVIRONMENT', "Environment", ""),
+ ('DIFFUSE', "Diffuse", ""),
+ ('GLOSSY', "Glossy", ""),
+ ('TRANSMISSION', "Transmission", ""),
+ ('SUBSURFACE', "Subsurface", ""),
+ ),
+ )
- cls.use_camera_cull = BoolProperty(
- name="Use Camera Cull",
- description="Allow objects to be culled based on the camera frustum",
- default=False,
- )
+ use_camera_cull: BoolProperty(
+ name="Use Camera Cull",
+ description="Allow objects to be culled based on the camera frustum",
+ default=False,
+ )
- cls.camera_cull_margin = FloatProperty(
- name="Camera Cull Margin",
- description="Margin for the camera space culling",
- default=0.1,
- min=0.0, max=5.0
- )
+ camera_cull_margin: FloatProperty(
+ name="Camera Cull Margin",
+ description="Margin for the camera space culling",
+ default=0.1,
+ min=0.0, max=5.0
+ )
- cls.use_distance_cull = BoolProperty(
- name="Use Distance Cull",
- description="Allow objects to be culled based on the distance from camera",
- default=False,
- )
+ use_distance_cull: BoolProperty(
+ name="Use Distance Cull",
+ description="Allow objects to be culled based on the distance from camera",
+ default=False,
+ )
- cls.distance_cull_margin = FloatProperty(
- name="Cull Distance",
- description="Cull objects which are further away from camera than this distance",
- default=50,
- min=0.0
- )
+ distance_cull_margin: FloatProperty(
+ name="Cull Distance",
+ description="Cull objects which are further away from camera than this distance",
+ default=50,
+ min=0.0
+ )
- cls.motion_blur_position = EnumProperty(
- name="Motion Blur Position",
- default='CENTER',
- description="Offset for the shutter's time interval, allows to change the motion blur trails",
- items=(
- ('START', "Start on Frame", "The shutter opens at the current frame"),
- ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
- ('END', "End on Frame", "The shutter closes at the current frame"),
- ),
- )
+ motion_blur_position: EnumProperty(
+ name="Motion Blur Position",
+ default='CENTER',
+ description="Offset for the shutter's time interval, allows to change the motion blur trails",
+ items=(
+ ('START', "Start on Frame", "The shutter opens at the current frame"),
+ ('CENTER', "Center on Frame", "The shutter is open during the current frame"),
+ ('END', "End on Frame", "The shutter closes at the current frame"),
+ ),
+ )
- cls.rolling_shutter_type = EnumProperty(
- name="Shutter Type",
- default='NONE',
- description="Type of rolling shutter effect matching CMOS-based cameras",
- items=(
- ('NONE', "None", "No rolling shutter effect used"),
- ('TOP', "Top-Bottom", "Sensor is being scanned from top to bottom")
- # TODO(seergey): Are there real cameras with different scanning direction?
- ),
- )
+ rolling_shutter_type: EnumProperty(
+ name="Shutter Type",
+ default='NONE',
+ description="Type of rolling shutter effect matching CMOS-based cameras",
+ items=(
+ ('NONE', "None", "No rolling shutter effect used"),
+ ('TOP', "Top-Bottom", "Sensor is being scanned from top to bottom")
+ # TODO(seergey): Are there real cameras with different scanning direction?
+ ),
+ )
- cls.rolling_shutter_duration = FloatProperty(
- name="Rolling Shutter Duration",
- description="Scanline \"exposure\" time for the rolling shutter effect",
- default=0.1,
- min=0.0, max=1.0,
- )
+ rolling_shutter_duration: FloatProperty(
+ name="Rolling Shutter Duration",
+ description="Scanline \"exposure\" time for the rolling shutter effect",
+ default=0.1,
+ min=0.0, max=1.0,
+ )
- cls.texture_limit = EnumProperty(
- name="Viewport Texture Limit",
- default='OFF',
- description="Limit texture size used by viewport rendering",
- items=enum_texture_limit
- )
+ texture_limit: EnumProperty(
+ name="Viewport Texture Limit",
+ default='OFF',
+ description="Limit texture size used by viewport rendering",
+ items=enum_texture_limit
+ )
- cls.texture_limit_render = EnumProperty(
- name="Render Texture Limit",
- default='OFF',
- description="Limit texture size used by final rendering",
- items=enum_texture_limit
- )
+ texture_limit_render: EnumProperty(
+ name="Render Texture Limit",
+ default='OFF',
+ description="Limit texture size used by final rendering",
+ items=enum_texture_limit
+ )
- cls.ao_bounces = IntProperty(
- name="AO Bounces",
- default=0,
- description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
- min=0, max=1024,
- )
+ ao_bounces: IntProperty(
+ name="AO Bounces",
+ default=0,
+ description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
+ min=0, max=1024,
+ )
- cls.ao_bounces_render = IntProperty(
- name="AO Bounces Render",
- default=0,
- description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
- min=0, max=1024,
- )
+ ao_bounces_render: IntProperty(
+ name="AO Bounces Render",
+ default=0,
+ description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
+ min=0, max=1024,
+ )
- # Various fine-tuning debug flags
-
- def devices_update_callback(self, context):
- import _cycles
- scene = context.scene.as_pointer()
- return _cycles.debug_flags_update(scene)
-
- cls.debug_use_cpu_avx2 = BoolProperty(name="AVX2", default=True)
- cls.debug_use_cpu_avx = BoolProperty(name="AVX", default=True)
- cls.debug_use_cpu_sse41 = BoolProperty(name="SSE41", default=True)
- cls.debug_use_cpu_sse3 = BoolProperty(name="SSE3", default=True)
- cls.debug_use_cpu_sse2 = BoolProperty(name="SSE2", default=True)
- cls.debug_bvh_layout = EnumProperty(
- name="BVH Layout",
- items=enum_bvh_layouts,
- default='BVH8',
- )
- cls.debug_use_cpu_split_kernel = BoolProperty(name="Split Kernel", default=False)
-
- cls.debug_use_cuda_adaptive_compile = BoolProperty(name="Adaptive Compile", default=False)
- cls.debug_use_cuda_split_kernel = BoolProperty(name="Split Kernel", default=False)
-
- cls.debug_opencl_kernel_type = EnumProperty(
- name="OpenCL Kernel Type",
- default='DEFAULT',
- items=(
- ('DEFAULT', "Default", ""),
- ('MEGA', "Mega", ""),
- ('SPLIT', "Split", ""),
- ),
- update=devices_update_callback
- )
+ # Various fine-tuning debug flags
- cls.debug_opencl_device_type = EnumProperty(
- name="OpenCL Device Type",
- default='ALL',
- items=(
- ('NONE', "None", ""),
- ('ALL', "All", ""),
- ('DEFAULT', "Default", ""),
- ('CPU', "CPU", ""),
- ('GPU', "GPU", ""),
- ('ACCELERATOR', "Accelerator", ""),
- ),
- update=devices_update_callback
- )
+ def _devices_update_callback(self, context):
+ import _cycles
+ scene = context.scene.as_pointer()
+ return _cycles.debug_flags_update(scene)
+
+ debug_use_cpu_avx2: BoolProperty(name="AVX2", default=True)
+ debug_use_cpu_avx: BoolProperty(name="AVX", default=True)
+ debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True)
+ debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True)
+ debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True)
+ debug_bvh_layout: EnumProperty(
+ name="BVH Layout",
+ items=enum_bvh_layouts,
+ default='BVH8',
+ )
+ debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False)
+
+ debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
+ debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
+
+ debug_opencl_kernel_type: EnumProperty(
+ name="OpenCL Kernel Type",
+ default='DEFAULT',
+ items=(
+ ('DEFAULT', "Default", ""),
+ ('MEGA', "Mega", ""),
+ ('SPLIT', "Split", ""),
+ ),
+ update=_devices_update_callback
+ )
- cls.debug_opencl_kernel_single_program = BoolProperty(
- name="Single Program",
- default=True,
- update=devices_update_callback,
- )
+ debug_opencl_device_type: EnumProperty(
+ name="OpenCL Device Type",
+ default='ALL',
+ items=(
+ ('NONE', "None", ""),
+ ('ALL', "All", ""),
+ ('DEFAULT', "Default", ""),
+ ('CPU', "CPU", ""),
+ ('GPU', "GPU", ""),
+ ('ACCELERATOR', "Accelerator", ""),
+ ),
+ update=_devices_update_callback
+ )
+
+ debug_opencl_kernel_single_program: BoolProperty(
+ name="Single Program",
+ default=True,
+ update=_devices_update_callback,
+ )
+ del _devices_update_callback
- cls.debug_use_opencl_debug = BoolProperty(name="Debug OpenCL", default=False)
+ debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
- cls.debug_opencl_mem_limit = IntProperty(name="Memory limit", default=0,
- description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)")
+ debug_opencl_mem_limit: IntProperty(
+ name="Memory limit",
+ default=0,
+ description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)"
+ )
+
+ @classmethod
+ def register(cls):
+ bpy.types.Scene.cycles = PointerProperty(
+ name="Cycles Render Settings",
+ description="Cycles render settings",
+ type=cls,
+ )
@classmethod
def unregister(cls):
@@ -741,6 +745,98 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
class CyclesCameraSettings(bpy.types.PropertyGroup):
+
+ aperture_type: EnumProperty(
+ name="Aperture Type",
+ description="Use f-stop number or aperture radius",
+ items=enum_aperture_types,
+ default='RADIUS',
+ )
+ aperture_fstop: FloatProperty(
+ name="Aperture f-stop",
+ description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
+ min=0.0, soft_min=0.1, soft_max=64.0,
+ default=5.6,
+ step=10,
+ precision=1,
+ )
+ aperture_size: FloatProperty(
+ name="Aperture Size",
+ description="Radius of the aperture for depth of field (higher values give more defocus)",
+ min=0.0, soft_max=10.0,
+ default=0.0,
+ step=1,
+ precision=4,
+ subtype='DISTANCE',
+ )
+ aperture_blades: IntProperty(
+ name="Aperture Blades",
+ description="Number of blades in aperture for polygonal bokeh (at least 3)",
+ min=0, max=100,
+ default=0,
+ )
+ aperture_rotation: FloatProperty(
+ name="Aperture Rotation",
+ description="Rotation of blades in aperture",
+ soft_min=-pi, soft_max=pi,
+ subtype='ANGLE',
+ default=0,
+ )
+ aperture_ratio: FloatProperty(
+ name="Aperture Ratio",
+ description="Distortion to simulate anamorphic lens bokeh",
+ min=0.01, soft_min=1.0, soft_max=2.0,
+ default=1.0,
+ precision=4,
+ )
+ panorama_type: EnumProperty(
+ name="Panorama Type",
+ description="Distortion to use for the calculation",
+ items=enum_panorama_types,
+ default='FISHEYE_EQUISOLID',
+ )
+ fisheye_fov: FloatProperty(
+ name="Field of View",
+ description="Field of view for the fisheye lens",
+ min=0.1745, soft_max=2.0 * pi, max=10.0 * pi,
+ subtype='ANGLE',
+ default=pi,
+ )
+ fisheye_lens: FloatProperty(
+ name="Fisheye Lens",
+ description="Lens focal length (mm)",
+ min=0.01, soft_max=15.0, max=100.0,
+ default=10.5,
+ )
+ latitude_min: FloatProperty(
+ name="Min Latitude",
+ description="Minimum latitude (vertical angle) for the equirectangular lens",
+ min=-0.5 * pi, max=0.5 * pi,
+ subtype='ANGLE',
+ default=-0.5 * pi,
+ )
+ latitude_max: FloatProperty(
+ name="Max Latitude",
+ description="Maximum latitude (vertical angle) for the equirectangular lens",
+ min=-0.5 * pi, max=0.5 * pi,
+ subtype='ANGLE',
+ default=0.5 * pi,
+ )
+ longitude_min: FloatProperty(
+ name="Min Longitude",
+ description="Minimum longitude (horizontal angle) for the equirectangular lens",
+ min=-pi, max=pi,
+ subtype='ANGLE',
+ default=-pi,
+ )
+ longitude_max: FloatProperty(
+ name="Max Longitude",
+ description="Maximum longitude (horizontal angle) for the equirectangular lens",
+ min=-pi, max=pi,
+ subtype='ANGLE',
+ default=pi,
+ )
+
@classmethod
def register(cls):
import math
@@ -751,103 +847,53 @@ class CyclesCameraSettings(bpy.types.PropertyGroup):
type=cls,
)
- cls.aperture_type = EnumProperty(
- name="Aperture Type",
- description="Use f-stop number or aperture radius",
- items=enum_aperture_types,
- default='RADIUS',
- )
- cls.aperture_fstop = FloatProperty(
- name="Aperture f-stop",
- description="F-stop ratio (lower numbers give more defocus, higher numbers give a sharper image)",
- min=0.0, soft_min=0.1, soft_max=64.0,
- default=5.6,
- step=10,
- precision=1,
- )
- cls.aperture_size = FloatProperty(
- name="Aperture Size",
- description="Radius of the aperture for depth of field (higher values give more defocus)",
- min=0.0, soft_max=10.0,
- default=0.0,
- step=1,
- precision=4,
- subtype='DISTANCE',
- )
- cls.aperture_blades = IntProperty(
- name="Aperture Blades",
- description="Number of blades in aperture for polygonal bokeh (at least 3)",
- min=0, max=100,
- default=0,
- )
- cls.aperture_rotation = FloatProperty(
- name="Aperture Rotation",
- description="Rotation of blades in aperture",
- soft_min=-math.pi, soft_max=math.pi,
- subtype='ANGLE',
- default=0,
- )
- cls.aperture_ratio = FloatProperty(
- name="Aperture Ratio",
- description="Distortion to simulate anamorphic lens bokeh",
- min=0.01, soft_min=1.0, soft_max=2.0,
- default=1.0,
- precision=4,
- )
- cls.panorama_type = EnumProperty(
- name="Panorama Type",
- description="Distortion to use for the calculation",
- items=enum_panorama_types,
- default='FISHEYE_EQUISOLID',
- )
- cls.fisheye_fov = FloatProperty(
- name="Field of View",
- description="Field of view for the fisheye lens",
- min=0.1745, soft_max=2.0 * math.pi, max=10.0 * math.pi,
- subtype='ANGLE',
- default=math.pi,
- )
- cls.fisheye_lens = FloatProperty(
- name="Fisheye Lens",
- description="Lens focal length (mm)",
- min=0.01, soft_max=15.0, max=100.0,
- default=10.5,
- )
- cls.latitude_min = FloatProperty(
- name="Min Latitude",
- description="Minimum latitude (vertical angle) for the equirectangular lens",
- min=-0.5 * math.pi, max=0.5 * math.pi,
- subtype='ANGLE',
- default=-0.5 * math.pi,
- )
- cls.latitude_max = FloatProperty(
- name="Max Latitude",
- description="Maximum latitude (vertical angle) for the equirectangular lens",
- min=-0.5 * math.pi, max=0.5 * math.pi,
- subtype='ANGLE',
- default=0.5 * math.pi,
- )
- cls.longitude_min = FloatProperty(
- name="Min Longitude",
- description="Minimum longitude (horizontal angle) for the equirectangular lens",
- min=-math.pi, max=math.pi,
- subtype='ANGLE',
- default=-math.pi,
- )
- cls.longitude_max = FloatProperty(
- name="Max Longitude",
- description="Maximum longitude (horizontal angle) for the equirectangular lens",
- min=-math.pi, max=math.pi,
- subtype='ANGLE',
- default=math.pi,
- )
-
@classmethod
def unregister(cls):
del bpy.types.Camera.cycles
class CyclesMaterialSettings(bpy.types.PropertyGroup):
+
+ sample_as_light: BoolProperty(
+ name="Multiple Importance Sample",
+ description="Use multiple importance sampling for this material, "
+ "disabling may reduce overall noise for large "
+ "objects that emit little light compared to other light sources",
+ default=True,
+ )
+ use_transparent_shadow: BoolProperty(
+ name="Transparent Shadows",
+ description="Use transparent shadows for this material if it contains a Transparent BSDF, "
+ "disabling will render faster but not give accurate shadows",
+ default=True,
+ )
+ homogeneous_volume: BoolProperty(
+ name="Homogeneous Volume",
+ description="When using volume rendering, assume volume has the same density everywhere "
+ "(not using any textures), for faster rendering",
+ default=False,
+ )
+ volume_sampling: EnumProperty(
+ name="Volume Sampling",
+ description="Sampling method to use for volumes",
+ items=enum_volume_sampling,
+ default='MULTIPLE_IMPORTANCE',
+ )
+
+ volume_interpolation: EnumProperty(
+ name="Volume Interpolation",
+ description="Interpolation method to use for smoke/fire volumes",
+ items=enum_volume_interpolation,
+ default='LINEAR',
+ )
+
+ displacement_method: EnumProperty(
+ name="Displacement Method",
+ description="Method to use for the displacement",
+ items=enum_displacement_methods,
+ default='DISPLACEMENT',
+ )
+
@classmethod
def register(cls):
bpy.types.Material.cycles = PointerProperty(
@@ -855,95 +901,103 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
description="Cycles material settings",
type=cls,
)
- cls.sample_as_light = BoolProperty(
- name="Multiple Importance Sample",
- description="Use multiple importance sampling for this material, "
- "disabling may reduce overall noise for large "
- "objects that emit little light compared to other light sources",
- default=True,
- )
- cls.use_transparent_shadow = BoolProperty(
- name="Transparent Shadows",
- description="Use transparent shadows for this material if it contains a Transparent BSDF, "
- "disabling will render faster but not give accurate shadows",
- default=True,
- )
- cls.homogeneous_volume = BoolProperty(
- name="Homogeneous Volume",
- description="When using volume rendering, assume volume has the same density everywhere "
- "(not using any textures), for faster rendering",
- default=False,
- )
- cls.volume_sampling = EnumProperty(
- name="Volume Sampling",
- description="Sampling method to use for volumes",
- items=enum_volume_sampling,
- default='MULTIPLE_IMPORTANCE',
- )
-
- cls.volume_interpolation = EnumProperty(
- name="Volume Interpolation",
- description="Interpolation method to use for smoke/fire volumes",
- items=enum_volume_interpolation,
- default='LINEAR',
- )
-
- cls.displacement_method = EnumProperty(
- name="Displacement Method",
- description="Method to use for the displacement",
- items=enum_displacement_methods,
- default='DISPLACEMENT',
- )
@classmethod
def unregister(cls):
del bpy.types.Material.cycles
-class CyclesLampSettings(bpy.types.PropertyGroup):
+class CyclesLightSettings(bpy.types.PropertyGroup):
+
+ cast_shadow: BoolProperty(
+ name="Cast Shadow",
+ description="Light casts shadows",
+ default=True,
+ )
+ samples: IntProperty(
+ name="Samples",
+ description="Number of light samples to render for each AA sample",
+ min=1, max=10000,
+ default=1,
+ )
+ max_bounces: IntProperty(
+ name="Max Bounces",
+ description="Maximum number of bounces the light will contribute to the render",
+ min=0, max=1024,
+ default=1024,
+ )
+ use_multiple_importance_sampling: BoolProperty(
+ name="Multiple Importance Sample",
+ description="Use multiple importance sampling for the light, "
+ "reduces noise for area lights and sharp glossy materials",
+ default=True,
+ )
+ is_portal: BoolProperty(
+ name="Is Portal",
+ description="Use this area light to guide sampling of the background, "
+ "note that this will make the light invisible",
+ default=False,
+ )
+
@classmethod
def register(cls):
- bpy.types.Lamp.cycles = PointerProperty(
- name="Cycles Lamp Settings",
- description="Cycles lamp settings",
+ bpy.types.Light.cycles = PointerProperty(
+ name="Cycles Light Settings",
+ description="Cycles light settings",
type=cls,
)
- cls.cast_shadow = BoolProperty(
- name="Cast Shadow",
- description="Lamp casts shadows",
- default=True,
- )
- cls.samples = IntProperty(
- name="Samples",
- description="Number of light samples to render for each AA sample",
- min=1, max=10000,
- default=1,
- )
- cls.max_bounces = IntProperty(
- name="Max Bounces",
- description="Maximum number of bounces the light will contribute to the render",
- min=0, max=1024,
- default=1024,
- )
- cls.use_multiple_importance_sampling = BoolProperty(
- name="Multiple Importance Sample",
- description="Use multiple importance sampling for the lamp, "
- "reduces noise for area lamps and sharp glossy materials",
- default=True,
- )
- 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):
- del bpy.types.Lamp.cycles
+ del bpy.types.Light.cycles
class CyclesWorldSettings(bpy.types.PropertyGroup):
+
+ sampling_method: EnumProperty(
+ name="Sampling method",
+ description="How to sample the background light",
+ items=enum_world_mis,
+ default='AUTOMATIC',
+ )
+ sample_map_resolution: IntProperty(
+ name="Map Resolution",
+ description="Importance map size is resolution x resolution/2; "
+ "higher values potentially produce less noise, at the cost of memory and speed",
+ min=4, max=8192,
+ default=1024,
+ )
+ samples: IntProperty(
+ name="Samples",
+ description="Number of light samples to render for each AA sample",
+ min=1, max=10000,
+ default=1,
+ )
+ max_bounces: IntProperty(
+ name="Max Bounces",
+ description="Maximum number of bounces the background light will contribute to the render",
+ min=0, max=1024,
+ default=1024,
+ )
+ homogeneous_volume: BoolProperty(
+ name="Homogeneous Volume",
+ description="When using volume rendering, assume volume has the same density everywhere"
+ "(not using any textures), for faster rendering",
+ default=False,
+ )
+ volume_sampling: EnumProperty(
+ name="Volume Sampling",
+ description="Sampling method to use for volumes",
+ items=enum_volume_sampling,
+ default='EQUIANGULAR',
+ )
+ volume_interpolation: EnumProperty(
+ name="Volume Interpolation",
+ description="Interpolation method to use for volumes",
+ items=enum_volume_interpolation,
+ default='LINEAR',
+ )
+
@classmethod
def register(cls):
bpy.types.World.cycles = PointerProperty(
@@ -951,50 +1005,6 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
description="Cycles world settings",
type=cls,
)
- cls.sampling_method = EnumProperty(
- name="Sampling method",
- description="How to sample the background light",
- items=enum_world_mis,
- default='AUTOMATIC',
- )
- cls.sample_map_resolution = IntProperty(
- name="Map Resolution",
- description="Importance map size is resolution x resolution/2; "
- "higher values potentially produce less noise, at the cost of memory and speed",
- min=4, max=8192,
- default=1024,
- )
- cls.samples = IntProperty(
- name="Samples",
- description="Number of light samples to render for each AA sample",
- min=1, max=10000,
- default=1,
- )
- cls.max_bounces = IntProperty(
- name="Max Bounces",
- description="Maximum number of bounces the background light will contribute to the render",
- min=0, max=1024,
- default=1024,
- )
- cls.homogeneous_volume = BoolProperty(
- name="Homogeneous Volume",
- description="When using volume rendering, assume volume has the same density everywhere"
- "(not using any textures), for faster rendering",
- default=False,
- )
- cls.volume_sampling = EnumProperty(
- name="Volume Sampling",
- description="Sampling method to use for volumes",
- items=enum_volume_sampling,
- default='EQUIANGULAR',
- )
-
- cls.volume_interpolation = EnumProperty(
- name="Volume Interpolation",
- description="Interpolation method to use for volumes",
- items=enum_volume_interpolation,
- default='LINEAR',
- )
@classmethod
def unregister(cls):
@@ -1002,6 +1012,38 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
class CyclesVisibilitySettings(bpy.types.PropertyGroup):
+
+ camera: BoolProperty(
+ name="Camera",
+ description="Object visibility for camera rays",
+ default=True,
+ )
+ diffuse: BoolProperty(
+ name="Diffuse",
+ description="Object visibility for diffuse reflection rays",
+ default=True,
+ )
+ glossy: BoolProperty(
+ name="Glossy",
+ description="Object visibility for glossy reflection rays",
+ default=True,
+ )
+ transmission: BoolProperty(
+ name="Transmission",
+ description="Object visibility for transmission rays",
+ default=True,
+ )
+ shadow: BoolProperty(
+ name="Shadow",
+ description="Object visibility for shadow rays",
+ default=True,
+ )
+ scatter: BoolProperty(
+ name="Volume Scatter",
+ description="Object visibility for volume scatter rays",
+ default=True,
+ )
+
@classmethod
def register(cls):
bpy.types.Object.cycles_visibility = PointerProperty(
@@ -1016,37 +1058,6 @@ class CyclesVisibilitySettings(bpy.types.PropertyGroup):
type=cls,
)
- cls.camera = BoolProperty(
- name="Camera",
- description="Object visibility for camera rays",
- default=True,
- )
- cls.diffuse = BoolProperty(
- name="Diffuse",
- description="Object visibility for diffuse reflection rays",
- default=True,
- )
- cls.glossy = BoolProperty(
- name="Glossy",
- description="Object visibility for glossy reflection rays",
- default=True,
- )
- cls.transmission = BoolProperty(
- name="Transmission",
- description="Object visibility for transmission rays",
- default=True,
- )
- cls.shadow = BoolProperty(
- name="Shadow",
- description="Object visibility for shadow rays",
- default=True,
- )
- cls.scatter = BoolProperty(
- name="Volume Scatter",
- description="Object visibility for volume scatter rays",
- default=True,
- )
-
@classmethod
def unregister(cls):
del bpy.types.Object.cycles_visibility
@@ -1080,70 +1091,71 @@ class CyclesMeshSettings(bpy.types.PropertyGroup):
class CyclesObjectSettings(bpy.types.PropertyGroup):
- @classmethod
- def register(cls):
- bpy.types.Object.cycles = PointerProperty(
- name="Cycles Object Settings",
- description="Cycles object settings",
- type=cls,
- )
- cls.use_motion_blur = BoolProperty(
- name="Use Motion Blur",
- description="Use motion blur for this object",
- default=True,
- )
+ use_motion_blur: BoolProperty(
+ name="Use Motion Blur",
+ description="Use motion blur for this object",
+ default=True,
+ )
- cls.use_deform_motion = BoolProperty(
- name="Use Deformation Motion",
- description="Use deformation motion blur for this object",
- default=True,
- )
+ use_deform_motion: BoolProperty(
+ name="Use Deformation Motion",
+ description="Use deformation motion blur for this object",
+ default=True,
+ )
- cls.motion_steps = IntProperty(
- name="Motion Steps",
- description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
- min=1, soft_max=8,
- default=1,
- )
+ motion_steps: IntProperty(
+ name="Motion Steps",
+ description="Control accuracy of motion blur, more steps gives more memory usage (actual number of steps is 2^(steps - 1))",
+ min=1, soft_max=8,
+ default=1,
+ )
- cls.use_camera_cull = BoolProperty(
- name="Use Camera Cull",
- description="Allow this object and its duplicators to be culled by camera space culling",
- default=False,
- )
+ use_camera_cull: BoolProperty(
+ name="Use Camera Cull",
+ description="Allow this object and its duplicators to be culled by camera space culling",
+ default=False,
+ )
- cls.use_distance_cull = BoolProperty(
- name="Use Distance Cull",
- description="Allow this object and its duplicators to be culled by distance from camera",
- default=False,
- )
+ use_distance_cull: BoolProperty(
+ name="Use Distance Cull",
+ description="Allow this object and its duplicators to be culled by distance from camera",
+ default=False,
+ )
- cls.use_adaptive_subdivision = BoolProperty(
- name="Use Adaptive Subdivision",
- description="Use adaptive render time subdivision",
- default=False,
- )
+ use_adaptive_subdivision: BoolProperty(
+ name="Use Adaptive Subdivision",
+ description="Use adaptive render time subdivision",
+ default=False,
+ )
- cls.dicing_rate = FloatProperty(
- name="Dicing Scale",
- description="Multiplier for scene dicing rate (located in the Geometry Panel)",
- min=0.1, max=1000.0, soft_min=0.5,
- default=1.0,
- )
+ dicing_rate: FloatProperty(
+ name="Dicing Scale",
+ description="Multiplier for scene dicing rate (located in the Geometry Panel)",
+ min=0.1, max=1000.0, soft_min=0.5,
+ default=1.0,
+ )
- cls.is_shadow_catcher = BoolProperty(
- name="Shadow Catcher",
- description="Only render shadows on this object, for compositing renders into real footage",
- default=False,
- )
+ is_shadow_catcher: BoolProperty(
+ name="Shadow Catcher",
+ description="Only render shadows on this object, for compositing renders into real footage",
+ default=False,
+ )
+
+ is_holdout: BoolProperty(
+ name="Holdout",
+ description="Render objects as a holdout or matte, creating a "
+ "hole in the image with zero alpha, to fill out in "
+ "compositing with real footange or another render",
+ default=False,
+ )
- cls.is_holdout = BoolProperty(
- name="Holdout",
- description="Render objects as a holdout or matte, creating a "
- "hole in the image with zero alpha, to fill out in "
- "compositing with real footange or another render",
- default=False,
+ @classmethod
+ def register(cls):
+ bpy.types.Object.cycles = PointerProperty(
+ name="Cycles Object Settings",
+ description="Cycles object settings",
+ type=cls,
)
@classmethod
@@ -1152,6 +1164,54 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
+
+ primitive: EnumProperty(
+ name="Primitive",
+ description="Type of primitive used for hair rendering",
+ items=enum_curve_primitives,
+ default='LINE_SEGMENTS',
+ )
+ shape: EnumProperty(
+ name="Shape",
+ description="Form of hair",
+ items=enum_curve_shape,
+ default='THICK',
+ )
+ cull_backfacing: BoolProperty(
+ name="Cull Back-faces",
+ description="Do not test the back-face of each strand",
+ default=True,
+ )
+ use_curves: BoolProperty(
+ name="Use Cycles Hair Rendering",
+ description="Activate Cycles hair rendering for particle system",
+ default=True,
+ )
+ resolution: IntProperty(
+ name="Resolution",
+ description="Resolution of generated mesh",
+ min=3, max=64,
+ default=3,
+ )
+ minimum_width: FloatProperty(
+ name="Minimal width",
+ description="Minimal pixel width for strands (0 - deactivated)",
+ min=0.0, max=100.0,
+ default=0.0,
+ )
+ maximum_width: FloatProperty(
+ name="Maximal width",
+ description="Maximum extension that strand radius can be increased by",
+ min=0.0, max=100.0,
+ default=0.1,
+ )
+ subdivisions: IntProperty(
+ name="Subdivisions",
+ description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
+ min=0, max=24,
+ default=4,
+ )
+
@classmethod
def register(cls):
bpy.types.Scene.cycles_curves = PointerProperty(
@@ -1159,52 +1219,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
description="Cycles hair rendering settings",
type=cls,
)
- cls.primitive = EnumProperty(
- name="Primitive",
- description="Type of primitive used for hair rendering",
- items=enum_curve_primitives,
- default='LINE_SEGMENTS',
- )
- cls.shape = EnumProperty(
- name="Shape",
- description="Form of hair",
- items=enum_curve_shape,
- default='THICK',
- )
- cls.cull_backfacing = BoolProperty(
- name="Cull back-faces",
- description="Do not test the back-face of each strand",
- default=True,
- )
- cls.use_curves = BoolProperty(
- name="Use Cycles Hair Rendering",
- description="Activate Cycles hair rendering for particle system",
- default=True,
- )
- cls.resolution = IntProperty(
- name="Resolution",
- description="Resolution of generated mesh",
- min=3, max=64,
- default=3,
- )
- cls.minimum_width = FloatProperty(
- name="Minimal width",
- description="Minimal pixel width for strands (0 - deactivated)",
- min=0.0, max=100.0,
- default=0.0,
- )
- cls.maximum_width = FloatProperty(
- name="Maximal width",
- description="Maximum extension that strand radius can be increased by",
- min=0.0, max=100.0,
- default=0.1,
- )
- cls.subdivisions = IntProperty(
- name="Subdivisions",
- description="Number of subdivisions used in Cardinal curve intersection (power of 2)",
- min=0, max=24,
- default=4,
- )
@classmethod
def unregister(cls):
@@ -1214,221 +1228,179 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
def update_render_passes(self, context):
scene = context.scene
rd = scene.render
- rl = rd.layers.active
- rl.update_render_passes()
+ view_layer = context.view_layer
+ view_layer.update_render_passes()
class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
- @classmethod
- def register(cls):
- bpy.types.SceneRenderLayer.cycles = PointerProperty(
- name="Cycles SceneRenderLayer Settings",
- description="Cycles SceneRenderLayer Settings",
- type=cls,
- )
- cls.pass_debug_bvh_traversed_nodes = BoolProperty(
- name="Debug BVH Traversed Nodes",
- description="Store Debug BVH Traversed Nodes pass",
- default=False,
- update=update_render_passes,
- )
- cls.pass_debug_bvh_traversed_instances = BoolProperty(
- name="Debug BVH Traversed Instances",
- description="Store Debug BVH Traversed Instances pass",
- default=False,
- update=update_render_passes,
- )
- cls.pass_debug_bvh_intersections = BoolProperty(
- name="Debug BVH Intersections",
- description="Store Debug BVH Intersections",
- default=False,
- update=update_render_passes,
- )
- cls.pass_debug_ray_bounces = BoolProperty(
- name="Debug Ray Bounces",
- description="Store Debug Ray Bounces pass",
- default=False,
- update=update_render_passes,
- )
- cls.pass_debug_render_time = BoolProperty(
- name="Debug Render Time",
- description="Render time in milliseconds per sample and pixel",
- default=False,
- update=update_render_passes,
- )
- cls.use_pass_volume_direct = BoolProperty(
- name="Volume Direct",
- description="Deliver direct volumetric scattering pass",
- default=False,
- update=update_render_passes,
- )
- cls.use_pass_volume_indirect = BoolProperty(
- name="Volume Indirect",
- description="Deliver indirect volumetric scattering pass",
- default=False,
- update=update_render_passes,
- )
- cls.use_denoising = BoolProperty(
- name="Use Denoising",
- description="Denoise the rendered image",
- default=False,
- update=update_render_passes,
- )
- cls.denoising_diffuse_direct = BoolProperty(
- name="Diffuse Direct",
- description="Denoise the direct diffuse lighting",
- default=True,
- )
- cls.denoising_diffuse_indirect = BoolProperty(
- name="Diffuse Indirect",
- description="Denoise the indirect diffuse lighting",
- default=True,
- )
- cls.denoising_glossy_direct = BoolProperty(
- name="Glossy Direct",
- description="Denoise the direct glossy lighting",
- default=True,
- )
- cls.denoising_glossy_indirect = BoolProperty(
- name="Glossy Indirect",
- description="Denoise the indirect glossy lighting",
- default=True,
- )
- cls.denoising_transmission_direct = BoolProperty(
- name="Transmission Direct",
- description="Denoise the direct transmission lighting",
- default=True,
- )
- cls.denoising_transmission_indirect = BoolProperty(
- name="Transmission Indirect",
- description="Denoise the indirect transmission lighting",
- default=True,
- )
- cls.denoising_subsurface_direct = BoolProperty(
- name="Subsurface Direct",
- description="Denoise the direct subsurface lighting",
- default=True,
- )
- cls.denoising_subsurface_indirect = BoolProperty(
- name="Subsurface Indirect",
- description="Denoise the indirect subsurface lighting",
- default=True,
- )
- cls.denoising_strength = FloatProperty(
- name="Denoising Strength",
- description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
- min=0.0, max=1.0,
- default=0.5,
- )
- cls.denoising_feature_strength = FloatProperty(
- name="Denoising Feature Strength",
- description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
- min=0.0, max=1.0,
- default=0.5,
- )
- cls.denoising_radius = IntProperty(
- name="Denoising Radius",
- description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
- min=1, max=25,
- default=8,
- )
- cls.denoising_relative_pca = BoolProperty(
- name="Relative filter",
- description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)",
- default=False,
- )
- cls.denoising_store_passes = BoolProperty(
- name="Store denoising passes",
- description="Store the denoising feature passes and the noisy image",
- default=False,
- update=update_render_passes,
- )
- cls.use_pass_crypto_object = BoolProperty(
- name="Cryptomatte Object",
- description="Render cryptomatte object pass, for isolating objects in compositing",
- default=False,
- update=update_render_passes,
- )
- cls.use_pass_crypto_material = BoolProperty(
- name="Cryptomatte Material",
- description="Render cryptomatte material pass, for isolating materials in compositing",
- default=False,
- update=update_render_passes,
- )
- cls.use_pass_crypto_asset = BoolProperty(
- name="Cryptomatte Asset",
- description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
- default=False,
- update=update_render_passes,
- )
- cls.pass_crypto_depth = IntProperty(
- name="Cryptomatte Levels",
- description="Sets how many unique objects can be distinguished per pixel",
- default=6, min=2, max=16, step=2,
- update=update_render_passes,
- )
- cls.pass_crypto_accurate = BoolProperty(
- name="Cryptomatte Accurate",
- description="Gerenate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
- default=True,
- update=update_render_passes,
- )
- @classmethod
- def unregister(cls):
- del bpy.types.SceneRenderLayer.cycles
+ pass_debug_bvh_traversed_nodes: BoolProperty(
+ name="Debug BVH Traversed Nodes",
+ description="Store Debug BVH Traversed Nodes pass",
+ default=False,
+ update=update_render_passes,
+ )
+ pass_debug_bvh_traversed_instances: BoolProperty(
+ name="Debug BVH Traversed Instances",
+ description="Store Debug BVH Traversed Instances pass",
+ default=False,
+ update=update_render_passes,
+ )
+ pass_debug_bvh_intersections: BoolProperty(
+ name="Debug BVH Intersections",
+ description="Store Debug BVH Intersections",
+ default=False,
+ update=update_render_passes,
+ )
+ pass_debug_ray_bounces: BoolProperty(
+ name="Debug Ray Bounces",
+ description="Store Debug Ray Bounces pass",
+ default=False,
+ update=update_render_passes,
+ )
+ pass_debug_render_time: BoolProperty(
+ name="Debug Render Time",
+ description="Render time in milliseconds per sample and pixel",
+ default=False,
+ update=update_render_passes,
+ )
+ use_pass_volume_direct: BoolProperty(
+ name="Volume Direct",
+ description="Deliver direct volumetric scattering pass",
+ default=False,
+ update=update_render_passes,
+ )
+ use_pass_volume_indirect: BoolProperty(
+ name="Volume Indirect",
+ description="Deliver indirect volumetric scattering pass",
+ default=False,
+ update=update_render_passes,
+ )
+ use_denoising: BoolProperty(
+ name="Use Denoising",
+ description="Denoise the rendered image",
+ default=False,
+ update=update_render_passes,
+ )
+ denoising_diffuse_direct: BoolProperty(
+ name="Diffuse Direct",
+ description="Denoise the direct diffuse lighting",
+ default=True,
+ )
+ denoising_diffuse_indirect: BoolProperty(
+ name="Diffuse Indirect",
+ description="Denoise the indirect diffuse lighting",
+ default=True,
+ )
+ denoising_glossy_direct: BoolProperty(
+ name="Glossy Direct",
+ description="Denoise the direct glossy lighting",
+ default=True,
+ )
+ denoising_glossy_indirect: BoolProperty(
+ name="Glossy Indirect",
+ description="Denoise the indirect glossy lighting",
+ default=True,
+ )
+ denoising_transmission_direct: BoolProperty(
+ name="Transmission Direct",
+ description="Denoise the direct transmission lighting",
+ default=True,
+ )
+ denoising_transmission_indirect: BoolProperty(
+ name="Transmission Indirect",
+ description="Denoise the indirect transmission lighting",
+ default=True,
+ )
+ denoising_subsurface_direct: BoolProperty(
+ name="Subsurface Direct",
+ description="Denoise the direct subsurface lighting",
+ default=True,
+ )
+ denoising_subsurface_indirect: BoolProperty(
+ name="Subsurface Indirect",
+ description="Denoise the indirect subsurface lighting",
+ default=True,
+ )
+ denoising_strength: FloatProperty(
+ name="Denoising Strength",
+ description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
+ min=0.0, max=1.0,
+ default=0.5,
+ )
+ denoising_feature_strength: FloatProperty(
+ name="Denoising Feature Strength",
+ description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
+ min=0.0, max=1.0,
+ default=0.5,
+ )
+ denoising_radius: IntProperty(
+ name="Denoising Radius",
+ description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
+ min=1, max=25,
+ default=8,
+ )
+ denoising_relative_pca: BoolProperty(
+ name="Relative filter",
+ description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)",
+ default=False,
+ )
+ denoising_store_passes: BoolProperty(
+ name="Store denoising passes",
+ description="Store the denoising feature passes and the noisy image",
+ default=False,
+ update=update_render_passes,
+ )
+ use_pass_crypto_object: BoolProperty(
+ name="Cryptomatte Object",
+ description="Render cryptomatte object pass, for isolating objects in compositing",
+ default=False,
+ update=update_render_passes,
+ )
+ use_pass_crypto_material: BoolProperty(
+ name="Cryptomatte Material",
+ description="Render cryptomatte material pass, for isolating materials in compositing",
+ default=False,
+ update=update_render_passes,
+ )
+ use_pass_crypto_asset: BoolProperty(
+ name="Cryptomatte Asset",
+ description="Render cryptomatte asset pass, for isolating groups of objects with the same parent",
+ default=False,
+ update=update_render_passes,
+ )
+ pass_crypto_depth: IntProperty(
+ name="Cryptomatte Levels",
+ description="Sets how many unique objects can be distinguished per pixel",
+ default=6, min=2, max=16, step=2,
+ update=update_render_passes,
+ )
+ pass_crypto_accurate: BoolProperty(
+ name="Cryptomatte Accurate",
+ description="Generate a more accurate Cryptomatte pass. CPU only, may render slower and use more memory",
+ default=True,
+ update=update_render_passes,
+ )
-class CyclesCurveSettings(bpy.types.PropertyGroup):
@classmethod
def register(cls):
- bpy.types.ParticleSettings.cycles = PointerProperty(
- name="Cycles Hair Settings",
- description="Cycles hair settings",
+ bpy.types.ViewLayer.cycles = PointerProperty(
+ name="Cycles ViewLayer Settings",
+ description="Cycles ViewLayer Settings",
type=cls,
)
- cls.radius_scale = FloatProperty(
- name="Radius Scaling",
- description="Multiplier of width properties",
- min=0.0, max=1000.0,
- default=0.01,
- )
- cls.root_width = FloatProperty(
- name="Root Size",
- description="Strand's width at root",
- min=0.0, max=1000.0,
- default=1.0,
- )
- cls.tip_width = FloatProperty(
- name="Tip Multiplier",
- description="Strand's width at tip",
- min=0.0, max=1000.0,
- default=0.0,
- )
- cls.shape = FloatProperty(
- name="Strand Shape",
- description="Strand shape parameter",
- min=-1.0, max=1.0,
- default=0.0,
- )
- cls.use_closetip = BoolProperty(
- name="Close tip",
- description="Set tip radius to zero",
- default=True,
- )
@classmethod
def unregister(cls):
- del bpy.types.ParticleSettings.cycles
+ del bpy.types.ViewLayer.cycles
class CyclesDeviceSettings(bpy.types.PropertyGroup):
- @classmethod
- def register(cls):
- cls.id = StringProperty(name="ID")
- cls.name = StringProperty(name="Name")
- cls.use = BoolProperty(name="Use", default=True)
- cls.type = EnumProperty(name="Type", items=enum_device_type, default='CUDA')
+ id: StringProperty(name="ID")
+ name: StringProperty(name="Name")
+ use: BoolProperty(name="Use", default=True)
+ type: EnumProperty(name="Type", items=enum_device_type, default='CUDA')
class CyclesPreferences(bpy.types.AddonPreferences):
@@ -1444,13 +1416,13 @@ class CyclesPreferences(bpy.types.AddonPreferences):
list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
return list
- compute_device_type = EnumProperty(
+ compute_device_type: EnumProperty(
name="Compute Device Type",
description="Device to use for computation (rendering with Cycles)",
items=get_device_types,
)
- devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings)
+ devices: bpy.props.CollectionProperty(type=CyclesDeviceSettings)
def find_existing_device_entry(self, device):
for device_entry in self.devices:
@@ -1540,13 +1512,12 @@ def register():
bpy.utils.register_class(CyclesRenderSettings)
bpy.utils.register_class(CyclesCameraSettings)
bpy.utils.register_class(CyclesMaterialSettings)
- bpy.utils.register_class(CyclesLampSettings)
+ bpy.utils.register_class(CyclesLightSettings)
bpy.utils.register_class(CyclesWorldSettings)
bpy.utils.register_class(CyclesVisibilitySettings)
bpy.utils.register_class(CyclesMeshSettings)
bpy.utils.register_class(CyclesObjectSettings)
bpy.utils.register_class(CyclesCurveRenderSettings)
- bpy.utils.register_class(CyclesCurveSettings)
bpy.utils.register_class(CyclesDeviceSettings)
bpy.utils.register_class(CyclesPreferences)
bpy.utils.register_class(CyclesRenderLayerSettings)
@@ -1556,13 +1527,12 @@ def unregister():
bpy.utils.unregister_class(CyclesRenderSettings)
bpy.utils.unregister_class(CyclesCameraSettings)
bpy.utils.unregister_class(CyclesMaterialSettings)
- bpy.utils.unregister_class(CyclesLampSettings)
+ bpy.utils.unregister_class(CyclesLightSettings)
bpy.utils.unregister_class(CyclesWorldSettings)
bpy.utils.unregister_class(CyclesMeshSettings)
bpy.utils.unregister_class(CyclesObjectSettings)
bpy.utils.unregister_class(CyclesVisibilitySettings)
bpy.utils.unregister_class(CyclesCurveRenderSettings)
- bpy.utils.unregister_class(CyclesCurveSettings)
bpy.utils.unregister_class(CyclesDeviceSettings)
bpy.utils.unregister_class(CyclesPreferences)
bpy.utils.unregister_class(CyclesRenderLayerSettings)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 2f1adfe4178..6372a2f5eba 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -17,6 +17,8 @@
# <pep8 compliant>
import bpy
+from bpy_extras.node_utils import find_node_input
+from bl_operators.presets import PresetMenu
import _cycles
from bpy.types import (
@@ -26,20 +28,20 @@ from bpy.types import (
)
-class CYCLES_MT_sampling_presets(Menu):
+class CYCLES_PT_sampling_presets(PresetMenu):
bl_label = "Sampling Presets"
preset_subdir = "cycles/sampling"
preset_operator = "script.execute_preset"
+ preset_add_operator = "render.cycles_sampling_preset_add"
COMPAT_ENGINES = {'CYCLES'}
- draw = Menu.draw_preset
-class CYCLES_MT_integrator_presets(Menu):
+class CYCLES_PT_integrator_presets(PresetMenu):
bl_label = "Integrator Presets"
preset_subdir = "cycles/integrator"
preset_operator = "script.execute_preset"
+ preset_add_operator = "render.cycles_integrator_preset_add"
COMPAT_ENGINES = {'CYCLES'}
- draw = Menu.draw_preset
class CyclesButtonsPanel:
@@ -50,8 +52,7 @@ class CyclesButtonsPanel:
@classmethod
def poll(cls, context):
- rd = context.scene.render
- return rd.engine in cls.COMPAT_ENGINES
+ return context.engine in cls.COMPAT_ENGINES
def get_device_type(context):
@@ -129,21 +130,23 @@ def draw_samples_info(layout, context):
if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'):
col = layout.column(align=True)
col.scale_y = 0.6
- col.label("Total Samples:")
+ col.label(text="Total Samples:")
col.separator()
if integrator == 'PATH':
- col.label("%s AA" % aa)
+ col.label(text="%s AA" % aa)
else:
- col.label("%s AA, %s Diffuse, %s Glossy, %s Transmission" %
+ col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
(aa, d * aa, g * aa, t * aa))
col.separator()
- col.label("%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
+ col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
(ao * aa, ml * aa, sss * aa, vol * aa))
class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
bl_label = "Sampling"
- bl_options = {'DEFAULT_CLOSED'}
+
+ def draw_header_preset(self, context):
+ CYCLES_PT_sampling_presets.draw_panel_header(self.layout)
def draw(self, context):
layout = self.layout
@@ -151,168 +154,295 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
scene = context.scene
cscene = scene.cycles
- row = layout.row(align=True)
- row.menu("CYCLES_MT_sampling_presets", text=bpy.types.CYCLES_MT_sampling_presets.bl_label)
- row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMIN")
- row.operator("render.cycles_sampling_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- row = layout.row()
- sub = row.row()
- sub.prop(cscene, "progressive", text="")
- row.prop(cscene, "use_square_samples")
+ layout.prop(cscene, "progressive")
- split = layout.split()
+ if cscene.progressive == 'PATH' or use_branched_path(context) is False:
+ col = layout.column(align=True)
+ col.prop(cscene, "samples", text="Render")
+ col.prop(cscene, "preview_samples", text="Viewport")
- col = split.column()
- sub = col.column(align=True)
- sub.label("Settings:")
+ draw_samples_info(layout, context)
+ else:
+ col = layout.column(align=True)
+ col.prop(cscene, "aa_samples", text="Render")
+ col.prop(cscene, "preview_aa_samples", text="Viewport")
- seed_sub = sub.row(align=True)
- seed_sub.prop(cscene, "seed")
- seed_sub.prop(cscene, "use_animated_seed", text="", icon="TIME")
- sub.prop(cscene, "sample_clamp_direct")
- sub.prop(cscene, "sample_clamp_indirect")
- sub.prop(cscene, "light_sampling_threshold")
+class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
+ bl_label = "Sub Samples"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
- if cscene.progressive == 'PATH' or use_branched_path(context) is False:
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Samples:")
- sub.prop(cscene, "samples", text="Render")
- sub.prop(cscene, "preview_samples", text="Preview")
- else:
- sub.label(text="AA Samples:")
- sub.prop(cscene, "aa_samples", text="Render")
- sub.prop(cscene, "preview_aa_samples", text="Preview")
+ @classmethod
+ def poll(self, context):
+ scene = context.scene
+ cscene = scene.cycles
+ return cscene.progressive != 'PATH' and use_branched_path(context)
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Samples:")
- sub.prop(cscene, "diffuse_samples", text="Diffuse")
- sub.prop(cscene, "glossy_samples", text="Glossy")
- sub.prop(cscene, "transmission_samples", text="Transmission")
- sub.prop(cscene, "ao_samples", text="AO")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- subsub = sub.row(align=True)
- subsub.active = use_sample_all_lights(context)
- subsub.prop(cscene, "mesh_light_samples", text="Mesh Light")
+ scene = context.scene
+ cscene = scene.cycles
+
+ col = layout.column(align=True)
+ col.prop(cscene, "diffuse_samples", text="Diffuse")
+ col.prop(cscene, "glossy_samples", text="Glossy")
+ col.prop(cscene, "transmission_samples", text="Transmission")
+ col.prop(cscene, "ao_samples", text="AO")
+
+ sub = col.row(align=True)
+ sub.active = use_sample_all_lights(context)
+ sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
+ col.prop(cscene, "subsurface_samples", text="Subsurface")
+ col.prop(cscene, "volume_samples", text="Volume")
+
+ draw_samples_info(layout, context)
+
+
+class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
+ bl_label = "Advanced"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ row = layout.row(align=True)
+ row.prop(cscene, "seed")
+ row.prop(cscene, "use_animated_seed", text="", icon='TIME')
+
+ layout.prop(cscene, "sampling_pattern", text="Pattern")
+
+ layout.prop(cscene, "use_square_samples")
- sub.prop(cscene, "subsurface_samples", text="Subsurface")
- sub.prop(cscene, "volume_samples", text="Volume")
+ layout.separator()
+
+ col = layout.column(align=True)
+ col.prop(cscene, "light_sampling_threshold", text="Light Threshold")
+ if cscene.progressive != 'PATH' and use_branched_path(context):
col = layout.column(align=True)
col.prop(cscene, "sample_all_lights_direct")
col.prop(cscene, "sample_all_lights_indirect")
- layout.row().prop(cscene, "sampling_pattern", text="Pattern")
- for rl in scene.render.layers:
- if rl.samples > 0:
- layout.separator()
- layout.row().prop(cscene, "use_layer_samples")
- break
+class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel):
+ bl_label = "Total Samples"
+ bl_parent_id = "CYCLES_RENDER_PT_sampling"
- draw_samples_info(layout, context)
+ @classmethod
+ def poll(self, context):
+ scene = context.scene
+ cscene = scene.cycles
+
+ if cscene.use_square_samples:
+ return True
+
+ return cscene.progressive != 'PATH' and use_branched_path(context)
+
+ def draw(self, context):
+ layout = self.layout
+ cscene = context.scene.cycles
+ integrator = cscene.progressive
+
+ # Calculate sample values
+ if integrator == 'PATH':
+ aa = cscene.samples
+ if cscene.use_square_samples:
+ aa = aa * aa
+ else:
+ aa = cscene.aa_samples
+ d = cscene.diffuse_samples
+ g = cscene.glossy_samples
+ t = cscene.transmission_samples
+ ao = cscene.ao_samples
+ ml = cscene.mesh_light_samples
+ sss = cscene.subsurface_samples
+ vol = cscene.volume_samples
+
+ if cscene.use_square_samples:
+ aa = aa * aa
+ d = d * d
+ g = g * g
+ t = t * t
+ ao = ao * ao
+ ml = ml * ml
+ sss = sss * sss
+ vol = vol * vol
+
+ col = layout.column(align=True)
+ col.scale_y = 0.6
+ if integrator == 'PATH':
+ col.label(text="%s AA" % aa)
+ else:
+ col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
+ (aa, d * aa, g * aa, t * aa))
+ col.separator()
+ col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
+ (ao * aa, ml * aa, sss * aa, vol * aa))
-class CYCLES_RENDER_PT_geometry(CyclesButtonsPanel, Panel):
- bl_label = "Geometry"
+class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
+ bl_label = "Subdivision"
bl_options = {'DEFAULT_CLOSED'}
+ @classmethod
+ def poll(self, context):
+ return context.scene.cycles.feature_set == 'EXPERIMENTAL'
+
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
- ccscene = scene.cycles_curves
- row = layout.row()
- row.label("Volume Sampling:")
- row = layout.row()
- row.prop(cscene, "volume_step_size")
- row.prop(cscene, "volume_max_steps")
+ col = layout.column()
+ sub = col.column(align=True)
+ sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
+ sub.prop(cscene, "preview_dicing_rate", text="Preview")
- layout.separator()
+ col.separator()
- if cscene.feature_set == 'EXPERIMENTAL':
- layout.label("Subdivision Rate:")
- split = layout.split()
+ col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale")
+ col.prop(cscene, "max_subdivisions")
- col = split.column()
- sub = col.column(align=True)
- sub.prop(cscene, "dicing_rate", text="Render")
- sub.prop(cscene, "preview_dicing_rate", text="Preview")
+ col.prop(cscene, "dicing_camera")
- col = split.column()
- col.prop(cscene, "offscreen_dicing_scale", text="Offscreen Scale")
- col.prop(cscene, "max_subdivisions")
- layout.prop(cscene, "dicing_camera")
+class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel):
+ bl_label = "Hair"
+ bl_options = {'DEFAULT_CLOSED'}
- layout.separator()
+ def draw_header(self, context):
+ layout = self.layout
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
- layout.label("Hair:")
- layout.prop(ccscene, "use_curves", text="Use Hair")
- col = layout.column()
- col.active = ccscene.use_curves
+ layout.prop(ccscene, "use_curves", text="")
- col.prop(ccscene, "primitive", text="Primitive")
- col.prop(ccscene, "shape", text="Shape")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
+
+ layout.active = ccscene.use_curves
+
+ col = layout.column()
+ col.prop(ccscene, "minimum_width", text="Min Pixels")
+ col.prop(ccscene, "maximum_width", text="Max Extension")
+ col.prop(ccscene, "shape", text="Shape")
if not (ccscene.primitive in {'CURVE_SEGMENTS', 'LINE_SEGMENTS'} and ccscene.shape == 'RIBBONS'):
col.prop(ccscene, "cull_backfacing", text="Cull back-faces")
+ col.prop(ccscene, "primitive", text="Primitive")
if ccscene.primitive == 'TRIANGLES' and ccscene.shape == 'THICK':
col.prop(ccscene, "resolution", text="Resolution")
elif ccscene.primitive == 'CURVE_SEGMENTS':
col.prop(ccscene, "subdivisions", text="Curve subdivisions")
- row = col.row()
- row.prop(ccscene, "minimum_width", text="Min Pixels")
- row.prop(ccscene, "maximum_width", text="Max Extension")
+
+class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel):
+ bl_label = "Volumes"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+ ccscene = scene.cycles_curves
+
+ col = layout.column()
+ col.prop(cscene, "volume_step_size", text="Step Size")
+ col.prop(cscene, "volume_max_steps", text="Max Steps")
class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel):
bl_label = "Light Paths"
bl_options = {'DEFAULT_CLOSED'}
+ def draw_header_preset(self, context):
+ CYCLES_PT_integrator_presets.draw_panel_header(self.layout)
+
+ def draw(self, context):
+ pass
+
+
+class CYCLES_RENDER_PT_light_paths_max_bounces(CyclesButtonsPanel, Panel):
+ bl_label = "Max Bounces"
+ bl_parent_id = "CYCLES_RENDER_PT_light_paths"
+
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
- row = layout.row(align=True)
- row.menu("CYCLES_MT_integrator_presets", text=bpy.types.CYCLES_MT_integrator_presets.bl_label)
- row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMIN")
- row.operator("render.cycles_integrator_preset_add", text="", icon="ZOOMOUT").remove_active = True
+ col = layout.column(align=True)
+ col.prop(cscene, "max_bounces", text="Total")
- split = layout.split()
+ col = layout.column(align=True)
+ col.prop(cscene, "diffuse_bounces", text="Diffuse")
+ col.prop(cscene, "glossy_bounces", text="Glossy")
+ col.prop(cscene, "transparent_max_bounces", text="Transparency")
+ col.prop(cscene, "transmission_bounces", text="Transmission")
+ col.prop(cscene, "volume_bounces", text="Volume")
- col = split.column()
- sub = col.column(align=True)
- sub.label("Transparency:")
- sub.prop(cscene, "transparent_max_bounces", text="Max")
+class CYCLES_RENDER_PT_light_paths_clamping(CyclesButtonsPanel, Panel):
+ bl_label = "Clamping"
+ bl_parent_id = "CYCLES_RENDER_PT_light_paths"
- col.separator()
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- col.prop(cscene, "caustics_reflective")
- col.prop(cscene, "caustics_refractive")
- col.prop(cscene, "blur_glossy")
+ scene = context.scene
+ cscene = scene.cycles
- col = split.column()
+ col = layout.column(align=True)
+ col.prop(cscene, "sample_clamp_direct", text="Direct Light")
+ col.prop(cscene, "sample_clamp_indirect", text="Indirect Light")
- sub = col.column(align=True)
- sub.label(text="Bounces:")
- sub.prop(cscene, "max_bounces", text="Max")
- sub = col.column(align=True)
- sub.prop(cscene, "diffuse_bounces", text="Diffuse")
- sub.prop(cscene, "glossy_bounces", text="Glossy")
- sub.prop(cscene, "transmission_bounces", text="Transmission")
- sub.prop(cscene, "volume_bounces", text="Volume")
+class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
+ bl_label = "Caustics"
+ bl_parent_id = "CYCLES_RENDER_PT_light_paths"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+
+ col = layout.column()
+ col.prop(cscene, "blur_glossy")
+ col.prop(cscene, "caustics_reflective")
+ col.prop(cscene, "caustics_refractive")
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
@@ -326,6 +456,8 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
@@ -335,9 +467,30 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
col = layout.column()
col.prop(cscene, "motion_blur_position", text="Position")
col.prop(rd, "motion_blur_shutter")
+ col.separator()
+ col.prop(cscene, "rolling_shutter_type", text="Rolling Shutter")
+ sub = col.column()
+ sub.active = cscene.rolling_shutter_type != 'NONE'
+ sub.prop(cscene, "rolling_shutter_duration")
+
+
+class CYCLES_RENDER_PT_motion_blur_curve(CyclesButtonsPanel, Panel):
+ bl_label = "Shutter Curve"
+ bl_parent_id = "CYCLES_RENDER_PT_motion_blur"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+ rd = scene.render
+ layout.active = rd.use_motion_blur
col = layout.column()
- col.label("Shutter curve:")
+
col.template_curve_mapping(rd, "motion_blur_shutter_curve")
col = layout.column(align=True)
@@ -349,40 +502,67 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
row.operator("render.shutter_curve_preset", icon='LINCURVE', text="").shape = 'LINE'
row.operator("render.shutter_curve_preset", icon='NOCURVE', text="").shape = 'MAX'
- col = layout.column()
- col.prop(cscene, "rolling_shutter_type")
- row = col.row()
- row.active = cscene.rolling_shutter_type != 'NONE'
- row.prop(cscene, "rolling_shutter_duration")
-
class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel):
bl_label = "Film"
+ bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ scene = context.scene
+ cscene = scene.cycles
+
+ col = layout.column()
+ col.prop(cscene, "film_exposure")
+
+
+class CYCLES_RENDER_PT_film_transparency(CyclesButtonsPanel, Panel):
+ bl_label = "Transparency"
+ bl_parent_id = "CYCLES_RENDER_PT_film"
+
+ def draw_header(self, context):
+ layout = self.layout
+ rd = context.scene.render
scene = context.scene
cscene = scene.cycles
- split = layout.split()
+ layout.prop(cscene, "film_transparent", text="")
- col = split.column()
- col.prop(cscene, "film_exposure")
- col.separator()
- sub = col.column(align=True)
- sub.prop(cscene, "pixel_filter_type", text="")
- if cscene.pixel_filter_type != 'BOX':
- sub.prop(cscene, "filter_width", text="Width")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ scene = context.scene
+ cscene = scene.cycles
- col = split.column()
- col.prop(cscene, "film_transparent")
- sub = col.row()
- sub.prop(cscene, "film_transparent_glass", text="Transparent Glass")
- sub.active = cscene.film_transparent
- sub = col.row()
- sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold")
+ layout.active = cscene.film_transparent
+
+ col = layout.column()
+ col.prop(cscene, "film_transparent_glass", text="Transparent Glass")
+
+ sub = col.column()
sub.active = cscene.film_transparent and cscene.film_transparent_glass
+ sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold")
+
+
+class CYCLES_RENDER_PT_film_pixel_filter(CyclesButtonsPanel, Panel):
+ bl_label = "Pixel Filter"
+ bl_parent_id = "CYCLES_RENDER_PT_film"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+ scene = context.scene
+ cscene = scene.cycles
+
+ col = layout.column()
+ col.prop(cscene, "pixel_filter_type", text="Type")
+ if cscene.pixel_filter_type != 'BOX':
+ col.prop(cscene, "filter_width", text="Width")
class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
@@ -390,320 +570,420 @@ class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel):
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ pass
+
+
+class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
+ bl_label = "Threads"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+
+ def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
rd = scene.render
cscene = scene.cycles
- split = layout.split()
-
- col = split.column(align=True)
+ col = layout.column()
- col.label(text="Threads:")
- col.row(align=True).prop(rd, "threads_mode", expand=True)
+ col.prop(rd, "threads_mode")
sub = col.column(align=True)
sub.enabled = rd.threads_mode == 'FIXED'
sub.prop(rd, "threads")
- col.separator()
- sub = col.column(align=True)
- sub.label(text="Tiles:")
- sub.prop(cscene, "tile_order", text="")
+class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
+ bl_label = "Tiles"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
- sub.prop(rd, "tile_x", text="X")
+ col = layout.column()
+
+ sub = col.column(align=True)
+ sub.prop(rd, "tile_x", text="Tiles X")
sub.prop(rd, "tile_y", text="Y")
+ col.prop(cscene, "tile_order", text="Order")
- subsub = sub.column()
- subsub.active = not rd.use_save_buffers
- for rl in rd.layers:
- if rl.cycles.use_denoising:
- subsub.active = False
- subsub.prop(cscene, "use_progressive_refine")
+ sub = col.column()
+ sub.active = not rd.use_save_buffers
+ for view_layer in scene.view_layers:
+ if view_layer.cycles.use_denoising:
+ sub.active = False
+ sub.prop(cscene, "use_progressive_refine")
- col = split.column()
- col.label(text="Final Render:")
- col.prop(rd, "use_save_buffers")
- col.prop(rd, "use_persistent_data", text="Persistent Images")
+class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel):
+ bl_label = "Acceleration Structure"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
- col.separator()
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
+
+ col = layout.column()
- col.label(text="Acceleration structure:")
if _cycles.with_embree:
row = col.row()
row.active = use_cpu(context)
row.prop(cscene, "use_bvh_embree")
- row = col.row()
col.prop(cscene, "debug_use_spatial_splits")
- row = col.row()
- row.active = not cscene.use_bvh_embree or not _cycles.with_embree
- row.prop(cscene, "debug_use_hair_bvh")
+ sub = col.column()
+ sub.active = not cscene.use_bvh_embree or not _cycles.with_embree
+ sub.prop(cscene, "debug_use_hair_bvh")
+ sub = col.column()
+ sub.active = not cscene.debug_use_spatial_splits and not cscene.use_bvh_embree
+ sub.prop(cscene, "debug_bvh_time_steps")
- row = col.row()
- row.active = not cscene.debug_use_spatial_splits and not cscene.use_bvh_embree
- row.prop(cscene, "debug_bvh_time_steps")
+
+class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
+ bl_label = "Final Render"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
col = layout.column()
- col.label(text="Viewport Resolution:")
- split = col.split()
- split.prop(rd, "preview_pixel_size", text="")
- split.prop(cscene, "preview_start_resolution")
+ col.prop(rd, "use_save_buffers")
+ col.prop(rd, "use_persistent_data", text="Persistent Images")
-class CYCLES_RENDER_PT_layer_options(CyclesButtonsPanel, Panel):
- bl_label = "Layer"
- bl_context = "render_layer"
+
+class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
+ bl_label = "Viewport"
+ bl_parent_id = "CYCLES_RENDER_PT_performance"
def draw(self, context):
layout = self.layout
- with_freestyle = bpy.app.build_options.freestyle
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
rd = scene.render
- rl = rd.layers.active
+ cscene = scene.cycles
- split = layout.split()
+ col = layout.column()
+ col.prop(rd, "preview_pixel_size", text="Pixel Size")
+ col.prop(cscene, "preview_start_resolution", text="Start Pixels")
- col = split.column()
- col.prop(scene, "layers", text="Scene")
- col.prop(rl, "layers_exclude", text="Exclude")
- col = split.column()
- col.prop(rl, "layers", text="Layer")
- col.prop(rl, "layers_zmask", text="Mask Layer")
+class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
+ bl_label = "Filter"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_context = "view_layer"
- split = layout.split()
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- col = split.column()
- col.label(text="Material:")
- col.prop(rl, "material_override", text="")
- col.separator()
- col.prop(rl, "samples")
+ with_freestyle = bpy.app.build_options.freestyle
- col = split.column()
- col.prop(rl, "use_sky", "Use Environment")
- col.prop(rl, "use_ao", "Use AO")
- col.prop(rl, "use_solid", "Use Surfaces")
- col.prop(rl, "use_strand", "Use Hair")
+ scene = context.scene
+ rd = scene.render
+ view_layer = context.view_layer
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ col = flow.column()
+ col.prop(view_layer, "use_sky", text="Environment")
+ col = flow.column()
+ col.prop(view_layer, "use_ao", text="Ambient Occlusion")
+ col = flow.column()
+ col.prop(view_layer, "use_solid", text="Surfaces")
+ col = flow.column()
+ col.prop(view_layer, "use_strand", text="Hair")
if with_freestyle:
- row = col.row()
- row.prop(rl, "use_freestyle", "Use Freestyle")
- row.active = rd.use_freestyle
+ col = flow.column()
+ col.prop(view_layer, "use_freestyle", text="Freestyle")
+ col.active = rd.use_freestyle
-class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel):
+class CYCLES_RENDER_PT_passes(CyclesButtonsPanel, Panel):
bl_label = "Passes"
- bl_context = "render_layer"
+ bl_context = "view_layer"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
+ pass
+
+
+class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
+ bl_label = "Data"
+ bl_context = "view_layer"
+ bl_parent_id = "CYCLES_RENDER_PT_passes"
+
+ def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
rd = scene.render
- rl = rd.layers.active
- crl = rl.cycles
-
- split = layout.split()
+ view_layer = context.view_layer
+ cycles_view_layer = view_layer.cycles
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+ col = flow.column()
+ col.prop(view_layer, "use_pass_combined")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_z")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_mist")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_normal")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_vector")
+ col.active = not rd.use_motion_blur
+ col = flow.column()
+ col.prop(view_layer, "use_pass_uv")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_object_index")
+ col = flow.column()
+ col.prop(view_layer, "use_pass_material_index")
- col = split.column()
- col.prop(rl, "use_pass_combined")
- col.prop(rl, "use_pass_z")
- col.prop(rl, "use_pass_mist")
- col.prop(rl, "use_pass_normal")
- row = col.row()
- row.prop(rl, "use_pass_vector")
- row.active = not rd.use_motion_blur
- col.prop(rl, "use_pass_uv")
- col.prop(rl, "use_pass_object_index")
- col.prop(rl, "use_pass_material_index")
- col.separator()
- col.prop(rl, "use_pass_shadow")
- col.prop(rl, "use_pass_ambient_occlusion")
- col.separator()
- col.prop(crl, "denoising_store_passes", text="Denoising Data")
- col.separator()
- col.prop(rl, "pass_alpha_threshold")
+ layout.separator()
- col = split.column()
- col.label(text="Diffuse:")
- row = col.row(align=True)
- row.prop(rl, "use_pass_diffuse_direct", text="Direct", toggle=True)
- row.prop(rl, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
- row.prop(rl, "use_pass_diffuse_color", text="Color", toggle=True)
- col.label(text="Glossy:")
- row = col.row(align=True)
- row.prop(rl, "use_pass_glossy_direct", text="Direct", toggle=True)
- row.prop(rl, "use_pass_glossy_indirect", text="Indirect", toggle=True)
- row.prop(rl, "use_pass_glossy_color", text="Color", toggle=True)
- col.label(text="Transmission:")
- row = col.row(align=True)
- row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True)
- row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True)
- row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True)
- col.label(text="Subsurface:")
- row = col.row(align=True)
- row.prop(rl, "use_pass_subsurface_direct", text="Direct", toggle=True)
- row.prop(rl, "use_pass_subsurface_indirect", text="Indirect", toggle=True)
- row.prop(rl, "use_pass_subsurface_color", text="Color", toggle=True)
- col.label(text="Volume:")
- row = col.row(align=True)
- row.prop(crl, "use_pass_volume_direct", text="Direct", toggle=True)
- row.prop(crl, "use_pass_volume_indirect", text="Indirect", toggle=True)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+ col = flow.column()
+ col.prop(cycles_view_layer, "denoising_store_passes", text="Denoising Data")
+ col = flow.column()
+ col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
- col.separator()
- col.prop(rl, "use_pass_emit", text="Emission")
- col.prop(rl, "use_pass_environment")
+ layout.separator()
- col = layout.column()
- col.prop(crl, "pass_debug_render_time")
- if _cycles.with_cycles_debug:
- col.prop(crl, "pass_debug_bvh_traversed_nodes")
- col.prop(crl, "pass_debug_bvh_traversed_instances")
- col.prop(crl, "pass_debug_bvh_intersections")
- col.prop(crl, "pass_debug_ray_bounces")
-
- crl = rl.cycles
- layout.label("Cryptomatte:")
- row = layout.row(align=True)
- row.prop(crl, "use_pass_crypto_object", text="Object", toggle=True)
- row.prop(crl, "use_pass_crypto_material", text="Material", toggle=True)
- row.prop(crl, "use_pass_crypto_asset", text="Asset", toggle=True)
- row = layout.row(align=True)
- row.prop(crl, "pass_crypto_depth")
- row = layout.row(align=True)
- row.active = use_cpu(context)
- row.prop(crl, "pass_crypto_accurate", text="Accurate Mode")
+ layout.prop(view_layer, "pass_alpha_threshold")
-class CYCLES_RENDER_PT_views(CyclesButtonsPanel, Panel):
- bl_label = "Views"
- bl_context = "render_layer"
- bl_options = {'DEFAULT_CLOSED'}
- def draw_header(self, context):
- rd = context.scene.render
- self.layout.prop(rd, "use_multiview", text="")
+class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
+ bl_label = "Light"
+ bl_context = "view_layer"
+ bl_parent_id = "CYCLES_RENDER_PT_passes"
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
- rd = scene.render
- rv = rd.views.active
+ view_layer = context.view_layer
+ cycles_view_layer = view_layer.cycles
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Diffuse")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_diffuse_direct", text="Direct", toggle=True)
+ row.prop(view_layer, "use_pass_diffuse_indirect", text="Indirect", toggle=True)
+ row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Glossy")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_glossy_direct", text="Direct", toggle=True)
+ row.prop(view_layer, "use_pass_glossy_indirect", text="Indirect", toggle=True)
+ row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Transmission")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_transmission_direct", text="Direct", toggle=True)
+ row.prop(view_layer, "use_pass_transmission_indirect", text="Indirect", toggle=True)
+ row.prop(view_layer, "use_pass_transmission_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Subsurface")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_subsurface_direct", text="Direct", toggle=True)
+ row.prop(view_layer, "use_pass_subsurface_indirect", text="Indirect", toggle=True)
+ row.prop(view_layer, "use_pass_subsurface_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Volume")
+ row = split.row(align=True)
+ row.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct", toggle=True)
+ row.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect", toggle=True)
- layout.active = rd.use_multiview
- basic_stereo = (rd.views_format == 'STEREO_3D')
+ col = layout.column(align=True)
+ col.prop(view_layer, "use_pass_emit", text="Emission")
+ col.prop(view_layer, "use_pass_environment")
+ col.prop(view_layer, "use_pass_shadow")
+ col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
- row = layout.row()
- row.prop(rd, "views_format", expand=True)
- if basic_stereo:
- row = layout.row()
- row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2)
+class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, Panel):
+ bl_label = "Cryptomatte"
+ bl_context = "view_layer"
+ bl_parent_id = "CYCLES_RENDER_PT_passes"
- row = layout.row()
- row.label(text="File Suffix:")
- row.prop(rv, "file_suffix", text="")
+ def draw(self, context):
+ import _cycles
- else:
- row = layout.row()
- row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2)
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- col = row.column(align=True)
- col.operator("scene.render_view_add", icon='ZOOMIN', text="")
- col.operator("scene.render_view_remove", icon='ZOOMOUT', text="")
+ cycles_view_layer = context.view_layer.cycles
- row = layout.row()
- row.label(text="Camera Suffix:")
- row.prop(rv, "camera_suffix", text="")
+ row = layout.row(align=True)
+ row.use_property_split = False
+ row.prop(cycles_view_layer, "use_pass_crypto_object", text="Object", toggle=True)
+ row.prop(cycles_view_layer, "use_pass_crypto_material", text="Material", toggle=True)
+ row.prop(cycles_view_layer, "use_pass_crypto_asset", text="Asset", toggle=True)
+
+ layout.prop(cycles_view_layer, "pass_crypto_depth", text="Levels")
+
+ row = layout.row(align=True)
+ row.active = use_cpu(context)
+ row.prop(cycles_view_layer, "pass_crypto_accurate", text="Accurate Mode")
+
+
+class CYCLES_RENDER_PT_passes_debug(CyclesButtonsPanel, Panel):
+ bl_label = "Debug"
+ bl_context = "view_layer"
+ bl_parent_id = "CYCLES_RENDER_PT_passes"
+
+ @classmethod
+ def poll(cls, context):
+ import _cycles
+ return _cycles.with_cycles_debug
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ cycles_view_layer = context.view_layer.cycles
+
+ layout.prop(cycles_view_layer, "pass_debug_bvh_traversed_nodes")
+ layout.prop(cycles_view_layer, "pass_debug_bvh_traversed_instances")
+ layout.prop(cycles_view_layer, "pass_debug_bvh_intersections")
+ layout.prop(cycles_view_layer, "pass_debug_ray_bounces")
class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
bl_label = "Denoising"
- bl_context = "render_layer"
+ bl_context = "view_layer"
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
- rd = context.scene.render
- rl = rd.layers.active
- crl = rl.cycles
- cscene = context.scene.cycles
+ scene = context.scene
+ view_layer = context.view_layer
+ cycles_view_layer = view_layer.cycles
+ cscene = scene.cycles
layout = self.layout
- layout.prop(crl, "use_denoising", text="")
+ layout.prop(cycles_view_layer, "use_denoising", text="")
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
- rd = scene.render
- rl = rd.layers.active
- crl = rl.cycles
+ view_layer = context.view_layer
+ cycles_view_layer = view_layer.cycles
split = layout.split()
- split.active = crl.use_denoising
+ split.active = cycles_view_layer.use_denoising
+
+ layout = layout.column(align=True)
+ layout.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
+ layout.prop(cycles_view_layer, "denoising_relative_pca")
+
+ layout.separator()
+
+ split = layout.split(factor=0.5)
+ split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
col = split.column()
- sub = col.column(align=True)
- sub.prop(crl, "denoising_radius", text="Radius")
- sub.prop(crl, "denoising_strength", slider=True, text="Strength")
+ col.alignment = 'RIGHT'
+ col.label(text="Diffuse")
+
+ row = split.row(align=True)
+ row.use_property_split = False
+ row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
+ row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
+
+ split = layout.split(factor=0.5)
+ split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
col = split.column()
- sub = col.column(align=True)
- sub.prop(crl, "denoising_feature_strength", slider=True, text="Feature Strength")
- sub.prop(crl, "denoising_relative_pca")
+ col.alignment = 'RIGHT'
+ col.label(text="Glossy")
- layout.separator()
+ row = split.row(align=True)
+ row.use_property_split = False
+ row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
+ row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
- row = layout.row()
- row.active = crl.use_denoising or crl.denoising_store_passes
- row.label(text="Diffuse:")
- sub = row.row(align=True)
- sub.prop(crl, "denoising_diffuse_direct", text="Direct", toggle=True)
- sub.prop(crl, "denoising_diffuse_indirect", text="Indirect", toggle=True)
+ split = layout.split(factor=0.5)
+ split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
- row = layout.row()
- row.active = crl.use_denoising or crl.denoising_store_passes
- row.label(text="Glossy:")
- sub = row.row(align=True)
- sub.prop(crl, "denoising_glossy_direct", text="Direct", toggle=True)
- sub.prop(crl, "denoising_glossy_indirect", text="Indirect", toggle=True)
+ col = split.column()
+ col.alignment = 'RIGHT'
+ col.label(text="Transmission")
- row = layout.row()
- row.active = crl.use_denoising or crl.denoising_store_passes
- row.label(text="Transmission:")
- sub = row.row(align=True)
- sub.prop(crl, "denoising_transmission_direct", text="Direct", toggle=True)
- sub.prop(crl, "denoising_transmission_indirect", text="Indirect", toggle=True)
+ row = split.row(align=True)
+ row.use_property_split = False
+ row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
+ row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
- row = layout.row()
- row.active = crl.use_denoising or crl.denoising_store_passes
- row.label(text="Subsurface:")
- sub = row.row(align=True)
- sub.prop(crl, "denoising_subsurface_direct", text="Direct", toggle=True)
- sub.prop(crl, "denoising_subsurface_indirect", text="Indirect", toggle=True)
+ split = layout.split(factor=0.5)
+ split.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
+
+ col = split.column()
+ col.alignment = 'RIGHT'
+ col.label(text="Subsurface")
+
+ row = split.row(align=True)
+ row.use_property_split = False
+ row.prop(cycles_view_layer, "denoising_subsurface_direct", text="Direct", toggle=True)
+ row.prop(cycles_view_layer, "denoising_subsurface_indirect", text="Indirect", toggle=True)
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
bl_options = {'DEFAULT_CLOSED'}
+ bl_context = "output"
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
rd = context.scene.render
- split = layout.split()
-
- col = split.column()
+ col = layout.column(align=True)
col.prop(rd, "use_compositing")
col.prop(rd, "use_sequencer")
- col = split.column()
- col.prop(rd, "dither_intensity", text="Dither", slider=True)
+ layout.prop(rd, "dither_intensity", text="Dither", slider=True)
class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
@@ -716,6 +996,7 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
cam = context.camera
ccam = cam.cycles
@@ -724,37 +1005,63 @@ class CYCLES_CAMERA_PT_dof(CyclesButtonsPanel, Panel):
split = layout.split()
col = split.column()
- col.label("Focus:")
- col.prop(cam, "dof_object", text="")
+ col.prop(cam, "dof_object", text="Focus Object")
sub = col.row()
sub.active = cam.dof_object is None
sub.prop(cam, "dof_distance", text="Distance")
- hq_support = dof_options.is_hq_supported
- sub = col.column(align=True)
- sub.label("Viewport:")
- subhq = sub.column()
- subhq.active = hq_support
- subhq.prop(dof_options, "use_high_quality")
- sub.prop(dof_options, "fstop")
- if dof_options.use_high_quality and hq_support:
- sub.prop(dof_options, "blades")
- col = split.column()
+class CYCLES_CAMERA_PT_dof_aperture(CyclesButtonsPanel, Panel):
+ bl_label = "Aperture"
+ bl_parent_id = "CYCLES_CAMERA_PT_dof"
- col.label("Aperture:")
- sub = col.column(align=True)
- sub.prop(ccam, "aperture_type", text="")
+ @classmethod
+ def poll(cls, context):
+ return context.camera and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ cam = context.camera
+ ccam = cam.cycles
+ dof_options = cam.gpu_dof
+
+ col = flow.column()
+ col.prop(ccam, "aperture_type")
if ccam.aperture_type == 'RADIUS':
- sub.prop(ccam, "aperture_size", text="Size")
+ col.prop(ccam, "aperture_size", text="Size")
elif ccam.aperture_type == 'FSTOP':
- sub.prop(ccam, "aperture_fstop", text="Number")
+ col.prop(ccam, "aperture_fstop", text="Number")
+ col.separator()
+
+ col = flow.column()
+ col.prop(ccam, "aperture_blades", text="Blades")
+ col.prop(ccam, "aperture_rotation", text="Rotation")
+ col.prop(ccam, "aperture_ratio", text="Ratio")
- sub = col.column(align=True)
- sub.prop(ccam, "aperture_blades", text="Blades")
- sub.prop(ccam, "aperture_rotation", text="Rotation")
- sub.prop(ccam, "aperture_ratio", text="Ratio")
+
+class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel):
+ bl_label = "Viewport"
+ bl_parent_id = "CYCLES_CAMERA_PT_dof"
+
+ @classmethod
+ def poll(cls, context):
+ return context.camera and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ cam = context.camera
+ dof_options = cam.gpu_dof
+
+ sub = flow.column(align=True)
+ sub.prop(dof_options, "fstop")
+ sub.prop(dof_options, "blades")
class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
@@ -764,7 +1071,10 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- return (context.material or context.object) and CyclesButtonsPanel.poll(context)
+ if context.active_object and context.active_object.type == 'GPENCIL':
+ return False
+ else:
+ return (context.material or context.object) and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
@@ -785,8 +1095,8 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
col = row.column(align=True)
- col.operator("object.material_slot_add", icon='ZOOMIN', text="")
- col.operator("object.material_slot_remove", icon='ZOOMOUT', text="")
+ col.operator("object.material_slot_add", icon='ADD', text="")
+ col.operator("object.material_slot_remove", icon='REMOVE', text="")
col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
@@ -802,7 +1112,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
row.operator("object.material_slot_select", text="Select")
row.operator("object.material_slot_deselect", text="Deselect")
- split = layout.split(percentage=0.65)
+ split = layout.split(factor=0.65)
if ob:
split.template_ID(ob, "active_material", new="material.new")
@@ -828,7 +1138,7 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
if CyclesButtonsPanel.poll(context) and ob:
if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA'}:
return True
- if ob.dupli_type == 'GROUP' and ob.dupli_group:
+ if ob.dupli_type == 'COLLECTION' and ob.dupli_group:
return True
# TODO(sergey): More duplicator types here?
return False
@@ -872,11 +1182,22 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
def poll(cls, context):
ob = context.object
return (CyclesButtonsPanel.poll(context) and
- ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LAMP'}) or
- (ob.dupli_type == 'GROUP' and ob.dupli_group)))
+ ob and ((ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META', 'LIGHT'}) or
+ (ob.dupli_type == 'COLLECTION' and ob.dupli_group)))
+
+ def draw(self, context):
+ pass
+
+
+class CYCLES_OBJECT_PT_cycles_settings_ray_visibility(CyclesButtonsPanel, Panel):
+ bl_label = "Ray Visibility"
+ bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
+ bl_context = "object"
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
cscene = scene.cycles
@@ -884,79 +1205,82 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
cob = ob.cycles
visibility = ob.cycles_visibility
- layout.label(text="Ray Visibility:")
- flow = layout.column_flow()
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
- flow.prop(visibility, "camera")
- flow.prop(visibility, "diffuse")
- flow.prop(visibility, "glossy")
- flow.prop(visibility, "transmission")
- flow.prop(visibility, "scatter")
+ col = flow.column()
+ col.prop(visibility, "camera")
+ col = flow.column()
+ col.prop(visibility, "diffuse")
+ col = flow.column()
+ col.prop(visibility, "glossy")
+ col = flow.column()
+ col.prop(visibility, "transmission")
+ col = flow.column()
+ col.prop(visibility, "scatter")
- if ob.type != 'LAMP':
- flow.prop(visibility, "shadow")
+ if ob.type != 'LIGHT':
+ col = flow.column()
+ col.prop(visibility, "shadow")
- row = layout.row()
- row.prop(cob, "is_shadow_catcher")
- row.prop(cob, "is_holdout")
+ layout.separator()
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ col = flow.column()
+ col.prop(cob, "is_shadow_catcher")
+ col = flow.column()
+ col.prop(cob, "is_holdout")
+
+
+class CYCLES_OBJECT_PT_cycles_settings_performance(CyclesButtonsPanel, Panel):
+ bl_label = "Performance"
+ bl_parent_id = "CYCLES_OBJECT_PT_cycles_settings"
+ bl_context = "object"
- col = layout.column()
- col.label(text="Performance:")
- row = col.row()
- sub = row.row()
- sub.active = scene.render.use_simplify and cscene.use_camera_cull
- sub.prop(cob, "use_camera_cull")
- sub = row.row()
- sub.active = scene.render.use_simplify and cscene.use_distance_cull
- sub.prop(cob, "use_distance_cull")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ cscene = scene.cycles
+ ob = context.object
+ cob = ob.cycles
+ visibility = ob.cycles_visibility
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ col = flow.column()
+ col.active = scene.render.use_simplify and cscene.use_camera_cull
+ col.prop(cob, "use_camera_cull")
+
+ col = flow.column()
+ col.active = scene.render.use_simplify and cscene.use_distance_cull
+ col.prop(cob, "use_distance_cull")
class CYCLES_OT_use_shading_nodes(Operator):
- """Enable nodes on a material, world or lamp"""
+ """Enable nodes on a material, world or light"""
bl_idname = "cycles.use_shading_nodes"
bl_label = "Use Nodes"
@classmethod
def poll(cls, context):
return (getattr(context, "material", False) or getattr(context, "world", False) or
- getattr(context, "lamp", False))
+ getattr(context, "light", False))
def execute(self, context):
if context.material:
context.material.use_nodes = True
elif context.world:
context.world.use_nodes = True
- elif context.lamp:
- context.lamp.use_nodes = True
+ elif context.light:
+ context.light.use_nodes = True
return {'FINISHED'}
-def find_node(material, nodetype):
- if material and material.node_tree:
- ntree = material.node_tree
-
- active_output_node = None
- for node in ntree.nodes:
- if getattr(node, "type", None) == nodetype:
- if getattr(node, "is_active_output", True):
- return node
- if not active_output_node:
- active_output_node = node
- return active_output_node
-
- return None
-
-
-def find_node_input(node, name):
- for input in node.inputs:
- if input.name == name:
- return input
-
- return None
-
-
def panel_node_draw(layout, id_data, output_type, input_name):
if not id_data.use_nodes:
layout.operator("cycles.use_shading_nodes", icon='NODETREE')
@@ -964,127 +1288,130 @@ def panel_node_draw(layout, id_data, output_type, input_name):
ntree = id_data.node_tree
- node = find_node(id_data, output_type)
- if not node:
- layout.label(text="No output node")
- else:
+ node = ntree.get_output_node('CYCLES')
+ if node:
input = find_node_input(node, input_name)
- layout.template_node_view(ntree, node, input)
+ if input:
+ layout.template_node_view(ntree, node, input)
+ else:
+ layout.label(text="Incompatible output node")
+ else:
+ layout.label(text="No output node")
return True
-class CYCLES_LAMP_PT_preview(CyclesButtonsPanel, Panel):
+class CYCLES_LIGHT_PT_preview(CyclesButtonsPanel, Panel):
bl_label = "Preview"
bl_context = "data"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
- return context.lamp and \
- not (context.lamp.type == 'AREA' and
- context.lamp.cycles.is_portal) \
- and CyclesButtonsPanel.poll(context)
+ return (
+ context.light and
+ not (
+ context.light.type == 'AREA' and
+ context.light.cycles.is_portal
+ ) and
+ CyclesButtonsPanel.poll(context)
+ )
def draw(self, context):
- self.layout.template_preview(context.lamp)
+ self.layout.template_preview(context.light)
-class CYCLES_LAMP_PT_lamp(CyclesButtonsPanel, Panel):
- bl_label = "Lamp"
+class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
+ bl_label = "Light"
bl_context = "data"
@classmethod
def poll(cls, context):
- return context.lamp and CyclesButtonsPanel.poll(context)
+ return context.light and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
- lamp = context.lamp
- clamp = lamp.cycles
+ light = context.light
+ clamp = light.cycles
# cscene = context.scene.cycles
- layout.prop(lamp, "type", expand=True)
+ layout.prop(light, "type", expand=True)
- split = layout.split()
- col = split.column(align=True)
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ col = layout.column()
- if lamp.type in {'POINT', 'SUN', 'SPOT'}:
- col.prop(lamp, "shadow_soft_size", text="Size")
- elif lamp.type == 'AREA':
- col.prop(lamp, "shape", text="")
+ if light.type in {'POINT', 'SUN', 'SPOT'}:
+ col.prop(light, "shadow_soft_size", text="Size")
+ elif light.type == 'AREA':
+ col.prop(light, "shape", text="Shape")
sub = col.column(align=True)
- if lamp.shape == 'SQUARE':
- sub.prop(lamp, "size")
- elif lamp.shape == 'RECTANGLE':
- sub.prop(lamp, "size", text="Size X")
- sub.prop(lamp, "size_y", text="Size Y")
+ if light.shape in {'SQUARE', 'DISK'}:
+ sub.prop(light, "size")
+ elif light.shape in {'RECTANGLE', 'ELLIPSE'}:
+ sub.prop(light, "size", text="Size X")
+ sub.prop(light, "size_y", text="Y")
- if not (lamp.type == 'AREA' and clamp.is_portal):
- sub = col.column(align=True)
+ if not (light.type == 'AREA' and clamp.is_portal):
+ sub = col.column()
if use_branched_path(context):
subsub = sub.row(align=True)
subsub.active = use_sample_all_lights(context)
subsub.prop(clamp, "samples")
sub.prop(clamp, "max_bounces")
- col = split.column()
-
sub = col.column(align=True)
- sub.active = not (lamp.type == 'AREA' and clamp.is_portal)
+ sub.active = not (light.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':
+ if light.type == 'AREA':
col.prop(clamp, "is_portal", text="Portal")
- if lamp.type == 'HEMI':
- layout.label(text="Not supported, interpreted as sun lamp")
+ if light.type == 'HEMI':
+ layout.label(text="Not supported, interpreted as sun light")
-class CYCLES_LAMP_PT_nodes(CyclesButtonsPanel, Panel):
+class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
bl_label = "Nodes"
bl_context = "data"
@classmethod
def poll(cls, context):
- return context.lamp and not (context.lamp.type == 'AREA' and
- context.lamp.cycles.is_portal) and \
+ return context.light and not (context.light.type == 'AREA' and
+ context.light.cycles.is_portal) and \
CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
- lamp = context.lamp
- if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
- layout.prop(lamp, "color")
+ light = context.light
+ if not panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface'):
+ layout.prop(light, "color")
-class CYCLES_LAMP_PT_spot(CyclesButtonsPanel, Panel):
+class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
bl_label = "Spot Shape"
bl_context = "data"
@classmethod
def poll(cls, context):
- lamp = context.lamp
- return (lamp and lamp.type == 'SPOT') and CyclesButtonsPanel.poll(context)
+ light = context.light
+ return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
+ light = context.light
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- lamp = context.lamp
-
- split = layout.split()
-
- col = split.column()
- sub = col.column()
- sub.prop(lamp, "spot_size", text="Size")
- sub.prop(lamp, "spot_blend", text="Blend", slider=True)
-
- col = split.column()
- col.prop(lamp, "show_cone")
+ col = layout.column()
+ col.prop(light, "spot_size", text="Size")
+ col.prop(light, "spot_blend", text="Blend", slider=True)
+ col.prop(light, "show_cone")
class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel):
@@ -1114,7 +1441,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
world = context.world
if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
- layout.prop(world, "horizon_color", text="Color")
+ layout.prop(world, "color")
class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
@@ -1137,6 +1464,7 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
bl_label = "Ambient Occlusion"
bl_context = "world"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
@@ -1148,15 +1476,17 @@ class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
light = context.world.light_settings
scene = context.scene
- row = layout.row()
- sub = row.row()
+ col = layout.column()
+ sub = col.column()
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
sub.prop(light, "ao_factor", text="Factor")
- row.prop(light, "distance", text="Distance")
+ col.prop(light, "distance", text="Distance")
class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
@@ -1168,8 +1498,8 @@ class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
def poll(cls, context):
if CyclesButtonsPanel.poll(context):
if context.world:
- for rl in context.scene.render.layers:
- if rl.use_pass_mist:
+ for view_layer in context.scene.view_layers:
+ if view_layer.use_pass_mist:
return True
return False
@@ -1221,35 +1551,71 @@ class CYCLES_WORLD_PT_settings(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
world = context.world
cworld = world.cycles
# cscene = context.scene.cycles
- split = layout.split()
+ col = layout.column()
- col = split.column()
- col.label(text="Surface:")
+class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_parent_id = "CYCLES_WORLD_PT_settings"
+ bl_context = "world"
+
+ @classmethod
+ def poll(cls, context):
+ return context.world and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ world = context.world
+ cworld = world.cycles
+
+ col = layout.column()
col.prop(cworld, "sampling_method", text="Sampling")
- sub = col.column(align=True)
+ sub = col.column()
sub.active = cworld.sampling_method != 'NONE'
subsub = sub.row(align=True)
subsub.active = cworld.sampling_method == 'MANUAL'
subsub.prop(cworld, "sample_map_resolution")
if use_branched_path(context):
- subsub = sub.row(align=True)
+ subsub = sub.column(align=True)
subsub.active = use_sample_all_lights(context)
subsub.prop(cworld, "samples")
sub.prop(cworld, "max_bounces")
- col = split.column()
- col.label(text="Volume:")
+
+class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "CYCLES_WORLD_PT_settings"
+ bl_context = "world"
+
+ @classmethod
+ def poll(cls, context):
+ return context.world and CyclesButtonsPanel.poll(context)
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ world = context.world
+ cworld = world.cycles
+
+ col = layout.column()
+
sub = col.column()
sub.active = use_cpu(context)
- sub.prop(cworld, "volume_sampling", text="")
- col.prop(cworld, "volume_interpolation", text="")
+ sub.prop(cworld, "volume_sampling", text="Sampling")
+ col.prop(cworld, "volume_interpolation", text="Interpolation")
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
@@ -1320,6 +1686,7 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
bl_label = "Settings"
bl_context = "material"
+ bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
@@ -1327,221 +1694,61 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
mat = context.material
cmat = mat.cycles
- split = layout.split()
- col = split.column()
- col.label(text="Surface:")
- col.prop(cmat, "sample_as_light", text="Multiple Importance")
- col.prop(cmat, "use_transparent_shadow")
+ layout.prop(mat, "pass_index")
- col.separator()
- col.label(text="Geometry:")
- col.prop(cmat, "displacement_method", text="")
- col = split.column()
- col.label(text="Volume:")
- sub = col.column()
- sub.active = use_cpu(context)
- sub.prop(cmat, "volume_sampling", text="")
- col.prop(cmat, "volume_interpolation", text="")
- col.prop(cmat, "homogeneous_volume", text="Homogeneous")
-
- col.separator()
- col.prop(mat, "pass_index")
-
-
-class CYCLES_MATERIAL_PT_viewport(CyclesButtonsPanel, Panel):
- bl_label = "Viewport"
+class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
+ bl_label = "Surface"
+ bl_parent_id = "CYCLES_MATERIAL_PT_settings"
bl_context = "material"
- bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.material and CyclesButtonsPanel.poll(context)
def draw(self, context):
- mat = context.material
-
layout = self.layout
- split = layout.split()
-
- col = split.column(align=True)
- col.label("Color:")
- col.prop(mat, "diffuse_color", text="")
- col.prop(mat, "alpha")
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- col.separator()
- col.label("Alpha:")
- col.prop(mat.game_settings, "alpha_blend", text="")
-
- col = split.column(align=True)
- col.label("Specular:")
- col.prop(mat, "specular_color", text="")
- col.prop(mat, "specular_hardness", text="Hardness")
-
-
-class CYCLES_TEXTURE_PT_context(CyclesButtonsPanel, Panel):
- bl_label = ""
- bl_context = "texture"
- bl_options = {'HIDE_HEADER'}
- COMPAT_ENGINES = {'CYCLES'}
-
- def draw(self, context):
- layout = self.layout
-
- tex = context.texture
- space = context.space_data
- pin_id = space.pin_id
- use_pin_id = space.use_pin_id
- user = context.texture_user
-
- space.use_limited_texture_context = False
-
- if not (use_pin_id and isinstance(pin_id, bpy.types.Texture)):
- pin_id = None
-
- if not pin_id:
- layout.template_texture_user()
-
- if user or pin_id:
- layout.separator()
-
- split = layout.split(percentage=0.65)
- col = split.column()
-
- if pin_id:
- col.template_ID(space, "pin_id")
- else:
- propname = context.texture_user_property.identifier
- col.template_ID(user, propname, new="texture.new")
-
- if tex:
- split = layout.split(percentage=0.2)
- split.label(text="Type:")
- split.prop(tex, "type", text="")
-
-
-class CYCLES_TEXTURE_PT_node(CyclesButtonsPanel, Panel):
- bl_label = "Node"
- bl_context = "texture"
-
- @classmethod
- def poll(cls, context):
- node = context.texture_node
- return node and CyclesButtonsPanel.poll(context)
-
- def draw(self, context):
- layout = self.layout
-
- node = context.texture_node
- ntree = node.id_data
- layout.template_node_view(ntree, node, None)
-
-
-class CYCLES_TEXTURE_PT_mapping(CyclesButtonsPanel, Panel):
- bl_label = "Mapping"
- bl_context = "texture"
-
- @classmethod
- def poll(cls, context):
- node = context.texture_node
- # TODO(sergey): perform a faster/nicer check?
- return node and hasattr(node, 'texture_mapping') and CyclesButtonsPanel.poll(context)
-
- def draw(self, context):
- layout = self.layout
-
- node = context.texture_node
-
- mapping = node.texture_mapping
-
- layout.prop(mapping, "vector_type", expand=True)
-
- row = layout.row()
-
- row.column().prop(mapping, "translation")
- row.column().prop(mapping, "rotation")
- row.column().prop(mapping, "scale")
-
- layout.label(text="Projection:")
-
- row = layout.row()
- row.prop(mapping, "mapping_x", text="")
- row.prop(mapping, "mapping_y", text="")
- row.prop(mapping, "mapping_z", text="")
-
-
-class CYCLES_TEXTURE_PT_colors(CyclesButtonsPanel, Panel):
- bl_label = "Color"
- bl_context = "texture"
- bl_options = {'DEFAULT_CLOSED'}
-
- @classmethod
- def poll(cls, context):
- # node = context.texture_node
- return False
- # return node and CyclesButtonsPanel.poll(context)
-
- def draw(self, context):
- layout = self.layout
-
- node = context.texture_node
-
- mapping = node.color_mapping
-
- split = layout.split()
-
- col = split.column()
- col.label(text="Blend:")
- col.prop(mapping, "blend_type", text="")
- col.prop(mapping, "blend_factor", text="Factor")
- col.prop(mapping, "blend_color", text="")
-
- col = split.column()
- col.label(text="Adjust:")
- col.prop(mapping, "brightness")
- col.prop(mapping, "contrast")
- col.prop(mapping, "saturation")
-
- layout.separator()
+ mat = context.material
+ cmat = mat.cycles
- layout.prop(mapping, "use_color_ramp", text="Ramp")
- if mapping.use_color_ramp:
- layout.template_color_ramp(mapping, "color_ramp", expand=True)
+ col = layout.column()
+ col.prop(cmat, "sample_as_light", text="Multiple Importance")
+ col.prop(cmat, "use_transparent_shadow")
+ col.prop(cmat, "displacement_method", text="Displacement Method")
-class CYCLES_PARTICLE_PT_textures(CyclesButtonsPanel, Panel):
- bl_label = "Textures"
- bl_context = "particle"
- bl_options = {'DEFAULT_CLOSED'}
+class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
+ bl_label = "Volume"
+ bl_parent_id = "CYCLES_MATERIAL_PT_settings"
+ bl_context = "material"
@classmethod
def poll(cls, context):
- psys = context.particle_system
- return psys and CyclesButtonsPanel.poll(context)
+ return context.material and CyclesButtonsPanel.poll(context)
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- psys = context.particle_system
- part = psys.settings
-
- row = layout.row()
- row.template_list("TEXTURE_UL_texslots", "", part, "texture_slots", part, "active_texture_index", rows=2)
-
- col = row.column(align=True)
- col.operator("texture.slot_move", text="", icon='TRIA_UP').type = 'UP'
- col.operator("texture.slot_move", text="", icon='TRIA_DOWN').type = 'DOWN'
- col.menu("TEXTURE_MT_specials", icon='DOWNARROW_HLT', text="")
+ mat = context.material
+ cmat = mat.cycles
- if not part.active_texture:
- layout.template_ID(part, "active_texture", new="texture.new")
- else:
- slot = part.texture_slots[part.active_texture_index]
- layout.template_ID(slot, "texture", new="texture.new")
+ col = layout.column()
+ sub = col.column()
+ sub.active = use_cpu(context)
+ sub.prop(cmat, "volume_sampling", text="Sampling")
+ col.prop(cmat, "volume_interpolation", text="Interpolation")
+ col.prop(cmat, "homogeneous_volume", text="Homogeneous")
class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
@@ -1552,69 +1759,84 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
scene = context.scene
cscene = scene.cycles
cbk = scene.render.bake
-
- layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
-
- col = layout.column()
- col.prop(cscene, "bake_type")
+ rd = scene.render
col = layout.column()
+ col.prop(rd, "use_bake_multires")
+ if rd.use_bake_multires:
+ col.prop(rd, "bake_type")
- if cscene.bake_type == 'NORMAL':
- col.prop(cbk, "normal_space", text="Space")
+ col = layout.column()
+ col.prop(rd, "bake_margin")
+ col.prop(rd, "use_bake_clear")
- row = col.row(align=True)
- row.label(text="Swizzle:")
- row.prop(cbk, "normal_r", text="")
- row.prop(cbk, "normal_g", text="")
- row.prop(cbk, "normal_b", text="")
+ if rd.bake_type == 'DISPLACEMENT':
+ col.prop(rd, "use_bake_lores_mesh")
- elif cscene.bake_type == 'COMBINED':
- row = col.row(align=True)
- row.prop(cbk, "use_pass_direct", toggle=True)
- row.prop(cbk, "use_pass_indirect", toggle=True)
+ col.operator("object.bake_image", icon='RENDER_STILL')
- split = col.split()
- split.active = cbk.use_pass_direct or cbk.use_pass_indirect
+ else:
+ col.prop(cscene, "bake_type")
+
+ col = layout.column()
+
+ if cscene.bake_type == 'NORMAL':
+ col.prop(cbk, "normal_space", text="Space")
+
+ sub = col.column(align=True)
+ sub.prop(cbk, "normal_r", text="Swizzle R")
+ sub.prop(cbk, "normal_g", text="G")
+ sub.prop(cbk, "normal_b", text="B")
+
+ elif cscene.bake_type == 'COMBINED':
+ row = col.row(align=True)
+ row.use_property_split = False
+ row.prop(cbk, "use_pass_direct", toggle=True)
+ row.prop(cbk, "use_pass_indirect", toggle=True)
+
+ col = col.column()
+ col.active = cbk.use_pass_direct or cbk.use_pass_indirect
+ col.prop(cbk, "use_pass_diffuse")
+ col.prop(cbk, "use_pass_glossy")
+ col.prop(cbk, "use_pass_transmission")
+ col.prop(cbk, "use_pass_subsurface")
+ col.prop(cbk, "use_pass_ambient_occlusion")
+ col.prop(cbk, "use_pass_emit")
+
+ elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
+ row = col.row(align=True)
+ row.use_property_split = False
+ row.prop(cbk, "use_pass_direct", toggle=True)
+ row.prop(cbk, "use_pass_indirect", toggle=True)
+ row.prop(cbk, "use_pass_color", toggle=True)
- col = split.column()
- col.prop(cbk, "use_pass_diffuse")
- col.prop(cbk, "use_pass_glossy")
- col.prop(cbk, "use_pass_transmission")
+ layout.separator()
- col = split.column()
- col.prop(cbk, "use_pass_subsurface")
- col.prop(cbk, "use_pass_ambient_occlusion")
- col.prop(cbk, "use_pass_emit")
+ col = layout.column()
+ col.prop(cbk, "margin")
+ col.prop(cbk, "use_clear", text="Clear Image")
- elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION', 'SUBSURFACE'}:
- row = col.row(align=True)
- row.prop(cbk, "use_pass_direct", toggle=True)
- row.prop(cbk, "use_pass_indirect", toggle=True)
- row.prop(cbk, "use_pass_color", toggle=True)
+ col.separator()
- layout.separator()
+ col.prop(cbk, "use_selected_to_active")
+ sub = col.column()
+ sub.active = cbk.use_selected_to_active
+ sub.prop(cbk, "use_cage", text="Cage")
+ if cbk.use_cage:
+ sub.prop(cbk, "cage_extrusion", text="Extrusion")
+ sub.prop_search(cbk, "cage_object", scene, "objects", text="Cage Object")
+ else:
+ sub.prop(cbk, "cage_extrusion", text="Ray Distance")
- split = layout.split()
+ layout.separator()
- col = split.column()
- col.prop(cbk, "margin")
- col.prop(cbk, "use_clear")
-
- col = split.column()
- col.prop(cbk, "use_selected_to_active")
- sub = col.column()
- sub.active = cbk.use_selected_to_active
- sub.prop(cbk, "use_cage", text="Cage")
- if cbk.use_cage:
- sub.prop(cbk, "cage_extrusion", text="Extrusion")
- sub.prop_search(cbk, "cage_object", scene, "objects", text="")
- else:
- sub.prop(cbk, "cage_extrusion", text="Ray Distance")
+ layout.operator("object.bake", icon='RENDER_STILL').type = cscene.bake_type
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
@@ -1635,7 +1857,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
col = layout.column()
- col.label('CPU Flags:')
+ col.label(text="CPU Flags:")
row = col.row(align=True)
row.prop(cscene, "debug_use_cpu_sse2", toggle=True)
row.prop(cscene, "debug_use_cpu_sse3", toggle=True)
@@ -1648,14 +1870,14 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
col.separator()
col = layout.column()
- col.label('CUDA Flags:')
+ col.label(text="CUDA Flags:")
col.prop(cscene, "debug_use_cuda_adaptive_compile")
col.prop(cscene, "debug_use_cuda_split_kernel")
col.separator()
col = layout.column()
- col.label('OpenCL Flags:')
+ col.label(text="OpenCL Flags:")
col.prop(cscene, "debug_opencl_kernel_type", text="Kernel")
col.prop(cscene, "debug_opencl_device_type", text="Device")
col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program")
@@ -1668,48 +1890,54 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
col.prop(cscene, "debug_bvh_type")
-class CYCLES_PARTICLE_PT_curve_settings(CyclesButtonsPanel, Panel):
- bl_label = "Cycles Hair Settings"
- bl_context = "particle"
+class CYCLES_RENDER_PT_simplify(CyclesButtonsPanel, Panel):
+ bl_label = "Simplify"
+ bl_context = "render"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
- @classmethod
- def poll(cls, context):
- scene = context.scene
- ccscene = scene.cycles_curves
- psys = context.particle_system
- use_curves = ccscene.use_curves and psys
- return CyclesButtonsPanel.poll(context) and use_curves and psys.settings.type == 'HAIR'
+ def draw_header(self, context):
+ rd = context.scene.render
+ self.layout.prop(rd, "use_simplify", text="")
def draw(self, context):
- layout = self.layout
+ pass
- psys = context.particle_settings
- cpsys = psys.cycles
- row = layout.row()
- row.prop(cpsys, "shape", text="Shape")
+class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
+ bl_label = "Viewport"
+ bl_context = "render"
+ bl_parent_id = "CYCLES_RENDER_PT_simplify"
+ COMPAT_ENGINES = {'CYCLES'}
- layout.label(text="Thickness:")
- row = layout.row()
- row.prop(cpsys, "root_width", text="Root")
- row.prop(cpsys, "tip_width", text="Tip")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- row = layout.row()
- row.prop(cpsys, "radius_scale", text="Scaling")
- row.prop(cpsys, "use_closetip", text="Close tip")
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
+ layout.active = rd.use_simplify
-class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel):
- bl_label = "Simplify"
- bl_context = "scene"
- COMPAT_ENGINES = {'CYCLES'}
+ col = layout.column()
+ col.prop(rd, "simplify_subdivision", text="Max Subdivision")
+ col.prop(rd, "simplify_child_particles", text="Child Particles")
+ col.prop(cscene, "texture_limit", text="Texture Limit")
+ col.prop(cscene, "ao_bounces", text="AO Bounces")
- def draw_header(self, context):
- rd = context.scene.render
- self.layout.prop(rd, "use_simplify", text="")
+
+class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel):
+ bl_label = "Render"
+ bl_context = "render"
+ bl_parent_id = "CYCLES_RENDER_PT_simplify"
+ COMPAT_ENGINES = {'CYCLES'}
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
scene = context.scene
rd = scene.render
@@ -1717,80 +1945,79 @@ class CYCLES_SCENE_PT_simplify(CyclesButtonsPanel, Panel):
layout.active = rd.use_simplify
- col = layout.column(align=True)
- col.label(text="Subdivision")
- row = col.row(align=True)
- row.prop(rd, "simplify_subdivision", text="Viewport")
- row.prop(rd, "simplify_subdivision_render", text="Render")
+ col = layout.column()
- col = layout.column(align=True)
- col.label(text="Child Particles")
- row = col.row(align=True)
- row.prop(rd, "simplify_child_particles", text="Viewport")
- row.prop(rd, "simplify_child_particles_render", text="Render")
+ col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
+ col.prop(rd, "simplify_child_particles_render", text="Child Particles")
+ col.prop(cscene, "texture_limit_render", text="Texture Limit")
+ col.prop(cscene, "ao_bounces_render", text="AO Bounces")
- col = layout.column(align=True)
- split = col.split()
- sub = split.column()
- sub.label(text="Texture Limit Viewport")
- sub.prop(cscene, "texture_limit", text="")
- sub = split.column()
- sub.label(text="Texture Limit Render")
- sub.prop(cscene, "texture_limit_render", text="")
- split = layout.split()
- col = split.column()
- col.prop(cscene, "use_camera_cull")
- row = col.row()
- row.active = cscene.use_camera_cull
- row.prop(cscene, "camera_cull_margin")
+class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
+ bl_label = "Culling"
+ bl_context = "render"
+ bl_parent_id = "CYCLES_RENDER_PT_simplify"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'CYCLES'}
- col = split.column()
- col.prop(cscene, "use_distance_cull")
- row = col.row()
- row.active = cscene.use_distance_cull
- row.prop(cscene, "distance_cull_margin", text="Distance")
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- split = layout.split()
- col = split.column()
- col.prop(cscene, "ao_bounces")
+ scene = context.scene
+ rd = scene.render
+ cscene = scene.cycles
- col = split.column()
- col.prop(cscene, "ao_bounces_render")
+ layout.active = rd.use_simplify
+
+ col = layout.column()
+ col.prop(cscene, "use_camera_cull")
+ sub = col.column()
+ sub.active = cscene.use_camera_cull
+ sub.prop(cscene, "camera_cull_margin")
+
+ col = layout.column()
+ col.prop(cscene, "use_distance_cull")
+ sub = col.column()
+ sub.active = cscene.use_distance_cull
+ sub.prop(cscene, "distance_cull_margin", text="Distance")
def draw_device(self, context):
scene = context.scene
layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
- if scene.render.engine == 'CYCLES':
+ if context.engine == 'CYCLES':
from . import engine
cscene = scene.cycles
- layout.prop(cscene, "feature_set")
+ col = layout.column()
+ col.prop(cscene, "feature_set")
- split = layout.split(percentage=1 / 3)
- split.label("Device:")
- row = split.row()
- row.active = show_device_active(context)
- row.prop(cscene, "device", text="")
+ scene = context.scene
+ col = layout.column()
+ col.active = show_device_active(context)
+ col.prop(cscene, "device")
+
+ from . import engine
if engine.with_osl() and use_cpu(context):
- layout.prop(cscene, "shading_system")
+ col.prop(cscene, "shading_system")
def draw_pause(self, context):
layout = self.layout
scene = context.scene
- if scene.render.engine == "CYCLES":
+ if context.engine == "CYCLES":
view = context.space_data
- if view.viewport_shade == 'RENDERED':
+ if view.shading.type == 'RENDERED':
cscene = scene.cycles
- layername = scene.render.layers.active.name
- layout.prop(cscene, "preview_pause", icon="PAUSE", text="")
- layout.prop(cscene, "preview_active_layer", icon="RENDERLAYERS", text=layername)
+ layout.prop(cscene, "preview_pause", icon='PAUSE', text="")
def get_panels():
@@ -1798,49 +2025,15 @@ def get_panels():
'DATA_PT_area',
'DATA_PT_camera_dof',
'DATA_PT_falloff_curve',
- 'DATA_PT_lamp',
+ 'DATA_PT_light',
'DATA_PT_preview',
- 'DATA_PT_shadow',
'DATA_PT_spot',
- 'DATA_PT_sunsky',
'MATERIAL_PT_context_material',
- 'MATERIAL_PT_diffuse',
- 'MATERIAL_PT_flare',
- 'MATERIAL_PT_halo',
- 'MATERIAL_PT_mirror',
- 'MATERIAL_PT_options',
- 'MATERIAL_PT_pipeline',
'MATERIAL_PT_preview',
- 'MATERIAL_PT_shading',
- 'MATERIAL_PT_shadow',
- 'MATERIAL_PT_specular',
- 'MATERIAL_PT_sss',
- 'MATERIAL_PT_strand',
- 'MATERIAL_PT_transp',
- 'MATERIAL_PT_volume_density',
- 'MATERIAL_PT_volume_integration',
- 'MATERIAL_PT_volume_lighting',
- 'MATERIAL_PT_volume_options',
- 'MATERIAL_PT_volume_shading',
- 'MATERIAL_PT_volume_transp',
- 'RENDERLAYER_PT_layer_options',
- 'RENDERLAYER_PT_layer_passes',
- 'RENDERLAYER_PT_views',
- 'RENDER_PT_antialiasing',
- 'RENDER_PT_bake',
- 'RENDER_PT_motion_blur',
- 'RENDER_PT_performance',
+ 'VIEWLAYER_PT_filter',
+ 'VIEWLAYER_PT_layer_passes',
'RENDER_PT_post_processing',
- 'RENDER_PT_shading',
- 'SCENE_PT_simplify',
- 'TEXTURE_PT_context_texture',
- 'WORLD_PT_ambient_occlusion',
- 'WORLD_PT_environment_lighting',
- 'WORLD_PT_gather',
- 'WORLD_PT_indirect_lighting',
- 'WORLD_PT_mist',
- 'WORLD_PT_preview',
- 'WORLD_PT_world'
+ 'RENDER_PT_simplify',
}
panels = []
@@ -1853,28 +2046,54 @@ def get_panels():
classes = (
- CYCLES_MT_sampling_presets,
- CYCLES_MT_integrator_presets,
+ CYCLES_PT_sampling_presets,
+ CYCLES_PT_integrator_presets,
CYCLES_RENDER_PT_sampling,
- CYCLES_RENDER_PT_geometry,
+ CYCLES_RENDER_PT_sampling_sub_samples,
+ CYCLES_RENDER_PT_sampling_advanced,
CYCLES_RENDER_PT_light_paths,
+ CYCLES_RENDER_PT_light_paths_max_bounces,
+ CYCLES_RENDER_PT_light_paths_clamping,
+ CYCLES_RENDER_PT_light_paths_caustics,
+ CYCLES_RENDER_PT_volumes,
+ CYCLES_RENDER_PT_subdivision,
+ CYCLES_RENDER_PT_hair,
+ CYCLES_RENDER_PT_simplify,
+ CYCLES_RENDER_PT_simplify_viewport,
+ CYCLES_RENDER_PT_simplify_render,
+ CYCLES_RENDER_PT_simplify_culling,
CYCLES_RENDER_PT_motion_blur,
+ CYCLES_RENDER_PT_motion_blur_curve,
CYCLES_RENDER_PT_film,
+ CYCLES_RENDER_PT_film_pixel_filter,
+ CYCLES_RENDER_PT_film_transparency,
CYCLES_RENDER_PT_performance,
- CYCLES_RENDER_PT_layer_options,
- CYCLES_RENDER_PT_layer_passes,
- CYCLES_RENDER_PT_views,
+ CYCLES_RENDER_PT_performance_threads,
+ CYCLES_RENDER_PT_performance_tiles,
+ CYCLES_RENDER_PT_performance_acceleration_structure,
+ CYCLES_RENDER_PT_performance_final_render,
+ CYCLES_RENDER_PT_performance_viewport,
+ CYCLES_RENDER_PT_filter,
+ CYCLES_RENDER_PT_passes,
+ CYCLES_RENDER_PT_passes_data,
+ CYCLES_RENDER_PT_passes_light,
+ CYCLES_RENDER_PT_passes_crypto,
+ CYCLES_RENDER_PT_passes_debug,
CYCLES_RENDER_PT_denoising,
CYCLES_PT_post_processing,
CYCLES_CAMERA_PT_dof,
+ CYCLES_CAMERA_PT_dof_aperture,
+ CYCLES_CAMERA_PT_dof_viewport,
CYCLES_PT_context_material,
CYCLES_OBJECT_PT_motion_blur,
CYCLES_OBJECT_PT_cycles_settings,
+ CYCLES_OBJECT_PT_cycles_settings_ray_visibility,
+ CYCLES_OBJECT_PT_cycles_settings_performance,
CYCLES_OT_use_shading_nodes,
- CYCLES_LAMP_PT_preview,
- CYCLES_LAMP_PT_lamp,
- CYCLES_LAMP_PT_nodes,
- CYCLES_LAMP_PT_spot,
+ CYCLES_LIGHT_PT_preview,
+ CYCLES_LIGHT_PT_light,
+ CYCLES_LIGHT_PT_nodes,
+ CYCLES_LIGHT_PT_spot,
CYCLES_WORLD_PT_preview,
CYCLES_WORLD_PT_surface,
CYCLES_WORLD_PT_volume,
@@ -1882,28 +2101,24 @@ classes = (
CYCLES_WORLD_PT_mist,
CYCLES_WORLD_PT_ray_visibility,
CYCLES_WORLD_PT_settings,
+ CYCLES_WORLD_PT_settings_surface,
+ CYCLES_WORLD_PT_settings_volume,
CYCLES_MATERIAL_PT_preview,
CYCLES_MATERIAL_PT_surface,
CYCLES_MATERIAL_PT_volume,
CYCLES_MATERIAL_PT_displacement,
CYCLES_MATERIAL_PT_settings,
- CYCLES_MATERIAL_PT_viewport,
- CYCLES_TEXTURE_PT_context,
- CYCLES_TEXTURE_PT_node,
- CYCLES_TEXTURE_PT_mapping,
- CYCLES_TEXTURE_PT_colors,
- CYCLES_PARTICLE_PT_textures,
+ CYCLES_MATERIAL_PT_settings_surface,
+ CYCLES_MATERIAL_PT_settings_volume,
CYCLES_RENDER_PT_bake,
CYCLES_RENDER_PT_debug,
- CYCLES_PARTICLE_PT_curve_settings,
- CYCLES_SCENE_PT_simplify,
)
def register():
from bpy.utils import register_class
- bpy.types.RENDER_PT_render.append(draw_device)
+ bpy.types.RENDER_PT_context.append(draw_device)
bpy.types.VIEW3D_HT_header.append(draw_pause)
for panel in get_panels():
@@ -1916,7 +2131,7 @@ def register():
def unregister():
from bpy.utils import unregister_class
- bpy.types.RENDER_PT_render.remove(draw_device)
+ bpy.types.RENDER_PT_context.remove(draw_device)
bpy.types.VIEW3D_HT_header.remove(draw_pause)
for panel in get_panels():
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index f14fe9abc3d..0564f2a7456 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -22,45 +22,6 @@ import math
from bpy.app.handlers import persistent
-def check_is_new_shading_ntree(node_tree):
- for node in node_tree.nodes:
- # If material has any node with ONLY new shading system
- # compatibility then it's considered a Cycles material
- # and versioning code would need to perform on it.
- #
- # We can not check for whether NEW_SHADING in compatibility
- # because some nodes could have compatibility with both old
- # and new shading system and they can't be used for any
- # decision here.
- if node.shading_compatibility == {'NEW_SHADING'}:
- return True
-
- # If node is only compatible with old shading system
- # then material can not be Cycles material and we
- # can stopiterating nodes now.
- if node.shading_compatibility == {'OLD_SHADING'}:
- return False
- return False
-
-
-def check_is_new_shading_material(material):
- if not material.node_tree:
- return False
- return check_is_new_shading_ntree(material.node_tree)
-
-
-def check_is_new_shading_world(world):
- if not world.node_tree:
- return False
- return check_is_new_shading_ntree(world.node_tree)
-
-
-def check_is_new_shading_lamp(lamp):
- if not lamp.node_tree:
- return False
- return check_is_new_shading_ntree(lamp.node_tree)
-
-
def foreach_notree_node(nodetree, callback, traversed):
if nodetree in traversed:
return
@@ -74,23 +35,23 @@ def foreach_notree_node(nodetree, callback, traversed):
def foreach_cycles_node(callback):
traversed = set()
for material in bpy.data.materials:
- if check_is_new_shading_material(material):
+ if material.node_tree:
foreach_notree_node(
material.node_tree,
callback,
traversed,
)
for world in bpy.data.worlds:
- if check_is_new_shading_world(world):
+ if world.node_tree:
foreach_notree_node(
world.node_tree,
callback,
traversed,
)
- for lamp in bpy.data.lamps:
- if check_is_new_shading_world(lamp):
+ for light in bpy.data.lights:
+ if light.node_tree:
foreach_notree_node(
- lamp.node_tree,
+ light.node_tree,
callback,
traversed,
)
@@ -109,10 +70,10 @@ def displacement_node_insert(material, nodetree, traversed):
displacement_links = []
for link in nodetree.links:
if (
- link.to_node.bl_idname == 'ShaderNodeOutputMaterial' and
- link.from_node.bl_idname != 'ShaderNodeDisplacement' and
- link.to_socket.identifier == 'Displacement'
- ):
+ link.to_node.bl_idname == 'ShaderNodeOutputMaterial' and
+ link.from_node.bl_idname != 'ShaderNodeDisplacement' and
+ link.to_socket.identifier == 'Displacement'
+ ):
displacement_links.append(link)
# Replace links with displacement node
@@ -137,7 +98,7 @@ def displacement_node_insert(material, nodetree, traversed):
def displacement_nodes_insert():
traversed = set()
for material in bpy.data.materials:
- if check_is_new_shading_material(material):
+ if material.node_tree:
displacement_node_insert(material, material.node_tree, traversed)
@@ -198,7 +159,7 @@ def square_roughness_node_insert(material, nodetree, traversed):
def square_roughness_nodes_insert():
traversed = set()
for material in bpy.data.materials:
- if check_is_new_shading_material(material):
+ if material.node_tree:
square_roughness_node_insert(material, material.node_tree, traversed)
@@ -314,7 +275,7 @@ def ambient_occlusion_node_relink(material, nodetree, traversed):
def ambient_occlusion_nodes_relink():
traversed = set()
for material in bpy.data.materials:
- if check_is_new_shading_material(material):
+ if material.node_tree:
ambient_occlusion_node_relink(material, material.node_tree, traversed)
@@ -348,11 +309,9 @@ def do_versions(self):
for scene in bpy.data.scenes:
cscene = scene.cycles
sample_clamp = cscene.get("sample_clamp", False)
- if (
- sample_clamp and
+ if (sample_clamp and
not cscene.is_property_set("sample_clamp_direct") and
- not cscene.is_property_set("sample_clamp_indirect")
- ):
+ not cscene.is_property_set("sample_clamp_indirect")):
cscene.sample_clamp_direct = sample_clamp
cscene.sample_clamp_indirect = sample_clamp
@@ -368,11 +327,10 @@ def do_versions(self):
if bpy.data.version <= (2, 72, 0):
for scene in bpy.data.scenes:
cscene = scene.cycles
- if (
- cscene.get("no_caustics", False) and
+ if (cscene.get("no_caustics", False) and
not cscene.is_property_set("caustics_reflective") and
- not cscene.is_property_set("caustics_refractive")
- ):
+ not cscene.is_property_set("caustics_refractive")):
+
cscene.caustics_reflective = False
cscene.caustics_refractive = False
@@ -409,12 +367,12 @@ def do_versions(self):
if not cscene.is_property_set("tile_order"):
cscene.tile_order = 'CENTER'
- for lamp in bpy.data.lamps:
- clamp = lamp.cycles
+ for light in bpy.data.lights:
+ clight = light.cycles
# MIS
- if not clamp.is_property_set("use_multiple_importance_sampling"):
- clamp.use_multiple_importance_sampling = False
+ if not clight.is_property_set("use_multiple_importance_sampling"):
+ clight.use_multiple_importance_sampling = False
for mat in bpy.data.materials:
cmat = mat.cycles
@@ -463,7 +421,8 @@ def do_versions(self):
if not cscene.is_property_set("sample_clamp_indirect"):
cscene.sample_clamp_indirect = 0.0
- if bpy.data.version <= (2, 79, 1):
+ if bpy.data.version <= (2, 79, 1) or \
+ (bpy.data.version >= (2, 80, 0) and bpy.data.version <= (2, 80, 3)):
displacement_nodes_insert()
if bpy.data.version <= (2, 79, 2):
@@ -474,11 +433,24 @@ def do_versions(self):
foreach_cycles_node(displacement_principled_nodes)
- if bpy.data.version <= (2, 79, 3):
+ if bpy.data.version <= (2, 79, 3) or \
+ (bpy.data.version >= (2, 80, 0) and bpy.data.version <= (2, 80, 4)):
# Switch to squared roughness convention
square_roughness_nodes_insert()
- if bpy.data.version <= (2, 79, 4):
+ if bpy.data.version <= (2, 80, 15):
+ # Copy cycles hair settings to internal settings
+ for part in bpy.data.particles:
+ cpart = part.get("cycles", None)
+ if cpart:
+ part.shape = cpart.get("shape", 0.0)
+ part.root_radius = cpart.get("root_width", 1.0)
+ part.tip_radius = cpart.get("tip_width", 0.0)
+ part.radius_scale = cpart.get("radius_scale", 0.01)
+ part.use_close_tip = cpart.get("use_closetip", True)
+
+ if bpy.data.version <= (2, 79, 4) or \
+ (bpy.data.version >= (2, 80, 0) and bpy.data.version <= (2, 80, 18)):
for world in bpy.data.worlds:
cworld = world.cycles
# World MIS
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 5a447a347a3..fc86094949f 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -95,8 +95,8 @@ static void blender_camera_init(BlenderCamera *bcam,
bcam->type = CAMERA_PERSPECTIVE;
bcam->zoom = 1.0f;
bcam->pixelaspect = make_float2(1.0f, 1.0f);
- bcam->sensor_width = 32.0f;
- bcam->sensor_height = 18.0f;
+ bcam->sensor_width = 36.0f;
+ bcam->sensor_height = 24.0f;
bcam->sensor_fit = BlenderCamera::AUTO;
bcam->shuttertime = 1.0f;
bcam->motion_position = Camera::MOTION_POSITION_CENTER;
@@ -232,7 +232,7 @@ static void blender_camera_from_object(BlenderCamera *bcam,
bcam->motion_steps = object_motion_steps(b_ob, b_ob);
}
else {
- /* from lamp not implemented yet */
+ /* from light not implemented yet */
}
}
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 5fd3455061d..5e4522af6e1 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -134,9 +134,9 @@ static bool ObtainCacheParticleData(Mesh *mesh,
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
int shader = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
- int draw_step = background ? b_part.render_step() : b_part.draw_step();
+ int display_step = background ? b_part.render_step() : b_part.display_step();
int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
+ int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
int totcurves = totchild;
if(b_part.child_type() == 0 || totchild == 0)
@@ -145,22 +145,20 @@ static bool ObtainCacheParticleData(Mesh *mesh,
if(totcurves == 0)
continue;
- int ren_step = (1 << draw_step) + 1;
+ int ren_step = (1 << display_step) + 1;
if(b_part.kink() == BL::ParticleSettings::kink_SPIRAL)
ren_step += b_part.kink_extra_steps();
- PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
-
CData->psys_firstcurve.push_back_slow(curvenum);
CData->psys_curvenum.push_back_slow(totcurves);
CData->psys_shader.push_back_slow(shader);
- float radius = get_float(cpsys, "radius_scale") * 0.5f;
+ float radius = b_part.radius_scale() * 0.5f;
- CData->psys_rootradius.push_back_slow(radius * get_float(cpsys, "root_width"));
- CData->psys_tipradius.push_back_slow(radius * get_float(cpsys, "tip_width"));
- CData->psys_shape.push_back_slow(get_float(cpsys, "shape"));
- CData->psys_closetip.push_back_slow(get_boolean(cpsys, "use_closetip"));
+ CData->psys_rootradius.push_back_slow(radius * b_part.root_radius());
+ CData->psys_tipradius.push_back_slow(radius * b_part.tip_radius());
+ CData->psys_shape.push_back_slow(b_part.shape());
+ CData->psys_closetip.push_back_slow(b_part.use_close_tip());
int pa_no = 0;
if(!(b_part.child_type() == 0) && totchild != 0)
@@ -229,7 +227,7 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
+ int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
int totcurves = totchild;
if(b_part.child_type() == 0 || totchild == 0)
@@ -249,11 +247,11 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
b_psys.particles.begin(b_pa);
for(; pa_no < totparts+totchild; pa_no++) {
/* Add UVs */
- BL::Mesh::tessface_uv_textures_iterator l;
- b_mesh->tessface_uv_textures.begin(l);
+ BL::Mesh::uv_layers_iterator l;
+ b_mesh->uv_layers.begin(l);
float3 uv = make_float3(0.0f, 0.0f, 0.0f);
- if(b_mesh->tessface_uv_textures.length())
+ if(b_mesh->uv_layers.length())
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
CData->curve_uv.push_back_slow(uv);
@@ -288,7 +286,7 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
int totparts = b_psys.particles.length();
- int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.draw_percentage() / 100.0f);
+ int totchild = background ? b_psys.child_particles.length() : (int)((float)b_psys.child_particles.length() * (float)b_part.display_percentage() / 100.0f);
int totcurves = totchild;
if(b_part.child_type() == 0 || totchild == 0)
@@ -308,11 +306,11 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
b_psys.particles.begin(b_pa);
for(; pa_no < totparts+totchild; pa_no++) {
/* Add vertex colors */
- BL::Mesh::tessface_vertex_colors_iterator l;
- b_mesh->tessface_vertex_colors.begin(l);
+ BL::Mesh::vertex_colors_iterator l;
+ b_mesh->vertex_colors.begin(l);
float3 vcol = make_float3(0.0f, 0.0f, 0.0f);
- if(b_mesh->tessface_vertex_colors.length())
+ if(b_mesh->vertex_colors.length())
b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
CData->curve_vcol.push_back_slow(vcol);
@@ -326,18 +324,6 @@ static bool ObtainCacheParticleVcol(Mesh *mesh,
return true;
}
-static void set_resolution(BL::BlendData *b_data, BL::Object *b_ob, BL::Scene *scene, bool render)
-{
- BL::Object::modifiers_iterator b_mod;
- for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && ((b_mod->show_viewport()) || (b_mod->show_render()))) {
- BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
- BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
- b_psys.set_resolution(*b_data, *scene, *b_ob, (render)? 2: 1);
- }
- }
-}
-
static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
float3 RotCam, bool is_ortho)
{
@@ -920,9 +906,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
ParticleCurveData CData;
- if(!preview)
- set_resolution(&b_data, &b_ob, &b_scene, true);
-
ObtainCacheParticleData(mesh, &b_mesh, &b_ob, &CData, !preview);
/* add hair geometry to mesh */
@@ -985,10 +968,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
/* create vertex color attributes */
if(!motion) {
- BL::Mesh::tessface_vertex_colors_iterator l;
+ BL::Mesh::vertex_colors_iterator l;
int vcol_num = 0;
- for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l, vcol_num++) {
+ for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l, vcol_num++) {
if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
continue;
@@ -1022,10 +1005,10 @@ void BlenderSync::sync_curves(Mesh *mesh,
/* create UV attributes */
if(!motion) {
- BL::Mesh::tessface_uv_textures_iterator l;
+ BL::Mesh::uv_layers_iterator l;
int uv_num = 0;
- for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l, uv_num++) {
+ for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, uv_num++) {
bool active_render = l->active_render();
AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring name = ustring(l->name().c_str());
@@ -1066,9 +1049,6 @@ void BlenderSync::sync_curves(Mesh *mesh,
}
}
- if(!preview)
- set_resolution(&b_data, &b_ob, &b_scene, false);
-
mesh->compute_bounds();
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 8d2ade1e30b..b97c250adf6 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -35,46 +35,6 @@
CCL_NAMESPACE_BEGIN
-/* Per-face bit flags. */
-enum {
- /* Face has no special flags. */
- FACE_FLAG_NONE = (0 << 0),
- /* Quad face was split using 1-3 diagonal. */
- FACE_FLAG_DIVIDE_13 = (1 << 0),
- /* Quad face was split using 2-4 diagonal. */
- FACE_FLAG_DIVIDE_24 = (1 << 1),
-};
-
-/* Get vertex indices to create triangles from a given face.
- *
- * Two triangles has vertex indices in the original Blender-side face.
- * If face is already a quad tri_b will not be initialized.
- */
-inline void face_split_tri_indices(const int face_flag,
- int tri_a[3],
- int tri_b[3])
-{
- if(face_flag & FACE_FLAG_DIVIDE_24) {
- tri_a[0] = 0;
- tri_a[1] = 1;
- tri_a[2] = 3;
-
- tri_b[0] = 2;
- tri_b[1] = 3;
- tri_b[2] = 1;
- }
- else {
- /* Quad with FACE_FLAG_DIVIDE_13 or single triangle. */
- tri_a[0] = 0;
- tri_a[1] = 1;
- tri_a[2] = 2;
-
- tri_b[0] = 0;
- tri_b[1] = 2;
- tri_b[2] = 3;
- }
-}
-
/* Tangent Space */
struct MikkUserData {
@@ -379,8 +339,6 @@ static void create_mesh_volume_attributes(Scene *scene,
static void attr_create_vertex_color(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
- const vector<int>& nverts,
- const vector<int>& face_flags,
bool subdivision)
{
if(subdivision) {
@@ -401,15 +359,15 @@ static void attr_create_vertex_color(Scene *scene,
int n = p->loop_total();
for(int i = 0; i < n; i++) {
float3 color = get_float3(l->data[p->loop_start() + i].color());
- /* Encode vertex color using the sRGB curve. */
+ /* Compress/encode vertex color using the sRGB curve. */
*(cdata++) = color_float_to_byte(color_srgb_to_linear_v3(color));
}
}
}
}
else {
- BL::Mesh::tessface_vertex_colors_iterator l;
- for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) {
+ BL::Mesh::vertex_colors_iterator l;
+ for(b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
continue;
@@ -417,35 +375,20 @@ static void attr_create_vertex_color(Scene *scene,
TypeDesc::TypeColor,
ATTR_ELEMENT_CORNER_BYTE);
- BL::MeshColorLayer::data_iterator c;
+ BL::Mesh::loop_triangles_iterator t;
uchar4 *cdata = attr->data_uchar4();
- size_t i = 0;
-
- for(l->data.begin(c); c != l->data.end(); ++c, ++i) {
- int tri_a[3], tri_b[3];
- face_split_tri_indices(face_flags[i], tri_a, tri_b);
-
- /* Encode vertex color using the sRGB curve. */
- uchar4 colors[4];
- colors[0] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color1())));
- colors[1] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color2())));
- colors[2] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color3())));
- if(nverts[i] == 4) {
- colors[3] = color_float_to_byte(color_srgb_to_linear_v3(get_float3(c->color4())));
- }
-
- cdata[0] = colors[tri_a[0]];
- cdata[1] = colors[tri_a[1]];
- cdata[2] = colors[tri_a[2]];
- if(nverts[i] == 4) {
- cdata[3] = colors[tri_b[0]];
- cdata[4] = colors[tri_b[1]];
- cdata[5] = colors[tri_b[2]];
- cdata += 6;
- }
- else
- cdata += 3;
+ for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ float3 c1 = get_float3(l->data[li[0]].color());
+ float3 c2 = get_float3(l->data[li[1]].color());
+ float3 c3 = get_float3(l->data[li[2]].color());
+
+ /* Compress/encode vertex color using the sRGB curve. */
+ cdata[0] = color_float_to_byte(color_srgb_to_linear_v3(c1));
+ cdata[1] = color_float_to_byte(color_srgb_to_linear_v3(c2));
+ cdata[2] = color_float_to_byte(color_srgb_to_linear_v3(c3));
+ cdata += 3;
}
}
}
@@ -454,14 +397,12 @@ static void attr_create_vertex_color(Scene *scene,
/* Create uv map attributes. */
static void attr_create_uv_map(Scene *scene,
Mesh *mesh,
- BL::Mesh& b_mesh,
- const vector<int>& nverts,
- const vector<int>& face_flags)
+ BL::Mesh& b_mesh)
{
- if(b_mesh.tessface_uv_textures.length() != 0) {
- BL::Mesh::tessface_uv_textures_iterator l;
+ if(b_mesh.uv_layers.length() != 0) {
+ BL::Mesh::uv_layers_iterator l;
- for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
+ for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
const bool active_render = l->active_render();
AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring uv_name = ustring(l->name().c_str());
@@ -493,33 +434,15 @@ static void attr_create_uv_map(Scene *scene,
ATTR_ELEMENT_CORNER);
}
- BL::MeshTextureFaceLayer::data_iterator t;
+ BL::Mesh::loop_triangles_iterator t;
float3 *fdata = uv_attr->data_float3();
- size_t i = 0;
-
- for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
- int tri_a[3], tri_b[3];
- face_split_tri_indices(face_flags[i], tri_a, tri_b);
-
- float3 uvs[4];
- uvs[0] = get_float3(t->uv1());
- uvs[1] = get_float3(t->uv2());
- uvs[2] = get_float3(t->uv3());
- if(nverts[i] == 4) {
- uvs[3] = get_float3(t->uv4());
- }
- fdata[0] = uvs[tri_a[0]];
- fdata[1] = uvs[tri_a[1]];
- fdata[2] = uvs[tri_a[2]];
+ for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
+ int3 li = get_int3(t->loops());
+ fdata[0] = get_float3(l->data[li[0]].uv());
+ fdata[1] = get_float3(l->data[li[1]].uv());
+ fdata[2] = get_float3(l->data[li[2]].uv());
fdata += 3;
-
- if(nverts[i] == 4) {
- fdata[0] = uvs[tri_b[0]];
- fdata[1] = uvs[tri_b[1]];
- fdata[2] = uvs[tri_b[2]];
- fdata += 3;
- }
}
}
@@ -563,7 +486,7 @@ static void attr_create_subd_uv_map(Scene *scene,
int i = 0;
for(b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l, ++i) {
- bool active_render = b_mesh.uv_textures[i].active_render();
+ bool active_render = l->active_render();
AttributeStandard uv_std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring uv_name = ustring(l->name().c_str());
AttributeStandard tangent_std = (active_render)? ATTR_STD_UV_TANGENT
@@ -822,7 +745,7 @@ static void create_mesh(Scene *scene,
{
/* count vertices and faces */
int numverts = b_mesh.vertices.length();
- int numfaces = (!subdivision) ? b_mesh.tessfaces.length() : b_mesh.polygons.length();
+ int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
int numtris = 0;
int numcorners = 0;
int numngons = 0;
@@ -834,14 +757,10 @@ static void create_mesh(Scene *scene,
}
BL::Mesh::vertices_iterator v;
- BL::Mesh::tessfaces_iterator f;
BL::Mesh::polygons_iterator p;
if(!subdivision) {
- for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f) {
- int4 vi = get_int4(f->vertices_raw());
- numtris += (vi[3] == 0)? 1: 2;
- }
+ numtris = numfaces;
}
else {
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
@@ -869,7 +788,7 @@ static void create_mesh(Scene *scene,
/* create generated coordinates from undeformed coordinates */
const bool need_default_tangent =
(subdivision == false) &&
- (b_mesh.tessface_uv_textures.length() == 0) &&
+ (b_mesh.uv_layers.length() == 0) &&
(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
if(mesh->need_attribute(scene, ATTR_STD_GENERATED) ||
need_default_tangent)
@@ -890,19 +809,21 @@ static void create_mesh(Scene *scene,
/* create faces */
vector<int> nverts(numfaces);
- vector<int> face_flags(numfaces, FACE_FLAG_NONE);
- int fi = 0;
if(!subdivision) {
- for(b_mesh.tessfaces.begin(f); f != b_mesh.tessfaces.end(); ++f, ++fi) {
- int4 vi = get_int4(f->vertices_raw());
- int n = (vi[3] == 0)? 3: 4;
- int shader = clamp(f->material_index(), 0, used_shaders.size()-1);
- bool smooth = f->use_smooth() || use_loop_normals;
+ BL::Mesh::loop_triangles_iterator t;
+ int ti = 0;
+
+ for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t, ++ti) {
+ BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
+ int3 vi = get_int3(t->vertices());
+
+ int shader = clamp(p.material_index(), 0, used_shaders.size()-1);
+ bool smooth = p.use_smooth() || use_loop_normals;
if(use_loop_normals) {
- BL::Array<float, 12> loop_normals = f->split_normals();
- for(int i = 0; i < n; i++) {
+ BL::Array<float, 9> loop_normals = t->split_normals();
+ for(int i = 0; i < 3; i++) {
N[vi[i]] = make_float3(loop_normals[i * 3],
loop_normals[i * 3 + 1],
loop_normals[i * 3 + 2]);
@@ -913,25 +834,8 @@ static void create_mesh(Scene *scene,
*
* NOTE: Autosmooth is already taken care about.
*/
- if(n == 4) {
- if(is_zero(cross(mesh->verts[vi[1]] - mesh->verts[vi[0]], mesh->verts[vi[2]] - mesh->verts[vi[0]])) ||
- is_zero(cross(mesh->verts[vi[2]] - mesh->verts[vi[0]], mesh->verts[vi[3]] - mesh->verts[vi[0]])))
- {
- mesh->add_triangle(vi[0], vi[1], vi[3], shader, smooth);
- mesh->add_triangle(vi[2], vi[3], vi[1], shader, smooth);
- face_flags[fi] |= FACE_FLAG_DIVIDE_24;
- }
- else {
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
- mesh->add_triangle(vi[0], vi[2], vi[3], shader, smooth);
- face_flags[fi] |= FACE_FLAG_DIVIDE_13;
- }
- }
- else {
- mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
- }
-
- nverts[fi] = n;
+ mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
+ nverts[ti] = 3;
}
}
else {
@@ -957,13 +861,13 @@ static void create_mesh(Scene *scene,
* The calculate functions will check whether they're needed or not.
*/
attr_create_pointiness(scene, mesh, b_mesh, subdivision);
- attr_create_vertex_color(scene, mesh, b_mesh, nverts, face_flags, subdivision);
+ attr_create_vertex_color(scene, mesh, b_mesh, subdivision);
if(subdivision) {
attr_create_subd_uv_map(scene, mesh, b_mesh, subdivide_uvs);
}
else {
- attr_create_uv_map(scene, mesh, b_mesh, nverts, face_flags);
+ attr_create_uv_map(scene, mesh, b_mesh);
}
/* for volume objects, create a matrix to transform from object space to
@@ -989,7 +893,7 @@ static void create_subd_mesh(Scene *scene,
int max_subdivisions)
{
BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length()-1]);
- bool subdivide_uvs = subsurf_mod.use_subsurf_uv();
+ bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE;
create_mesh(scene, mesh, b_mesh, used_shaders, true, subdivide_uvs);
@@ -1071,50 +975,35 @@ static void sync_mesh_fluid_motion(BL::Object& b_ob, Scene *scene, Mesh *mesh)
}
}
-Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
+Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
+ BL::Object& b_ob,
+ BL::Object& b_ob_instance,
bool object_updated,
bool hide_tris)
{
- /* When viewport display is not needed during render we can force some
- * caches to be releases from blender side in order to reduce peak memory
- * footprint during synchronization process.
- */
- const bool is_interface_locked = b_engine.render() &&
- b_engine.render().use_lock_interface();
- const bool can_free_caches = BlenderSession::headless || is_interface_locked;
-
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
- BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
- BL::Material material_override = render_layer.material_override;
+ BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data;
/* find shader indices */
vector<Shader*> used_shaders;
BL::Object::material_slots_iterator slot;
for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
- if(material_override) {
- find_shader(material_override, used_shaders, scene->default_surface);
- }
- else {
- BL::ID b_material(slot->material());
- find_shader(b_material, used_shaders, scene->default_surface);
- }
+ BL::ID b_material(slot->material());
+ find_shader(b_material, used_shaders, scene->default_surface);
}
if(used_shaders.size() == 0) {
- if(material_override)
- find_shader(material_override, used_shaders, scene->default_surface);
- else
- used_shaders.push_back(scene->default_surface);
+ used_shaders.push_back(scene->default_surface);
}
/* test if we need to sync */
int requested_geometry_flags = Mesh::GEOMETRY_NONE;
- if(render_layer.use_surfaces) {
+ if(view_layer.use_surfaces) {
requested_geometry_flags |= Mesh::GEOMETRY_TRIANGLES;
}
- if(render_layer.use_hair) {
+ if(view_layer.use_hair) {
requested_geometry_flags |= Mesh::GEOMETRY_CURVES;
}
Mesh *mesh;
@@ -1188,14 +1077,13 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
BL::Mesh b_mesh = object_to_mesh(b_data,
b_ob,
- b_scene,
- true,
- !preview,
+ b_depsgraph,
+ false,
need_undeformed,
mesh->subdivision_type);
if(b_mesh) {
- if(render_layer.use_surfaces && !hide_tris) {
+ if(view_layer.use_surfaces && !hide_tris) {
if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
dicing_rate, max_subdivisions);
@@ -1205,13 +1093,9 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
}
- if(render_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
+ if(view_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
sync_curves(mesh, b_mesh, b_ob, false);
- if(can_free_caches) {
- b_ob.cache_release();
- }
-
/* free derived mesh */
b_data.meshes.remove(b_mesh, false, true, false);
}
@@ -1233,7 +1117,8 @@ Mesh *BlenderSync::sync_mesh(BL::Object& b_ob,
return mesh;
}
-void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
+void BlenderSync::sync_mesh_motion(BL::Depsgraph& b_depsgraph,
+ BL::Object& b_ob,
Object *object,
float motion_time)
{
@@ -1276,9 +1161,8 @@ void BlenderSync::sync_mesh_motion(BL::Object& b_ob,
/* get derived mesh */
b_mesh = object_to_mesh(b_data,
b_ob,
- b_scene,
- true,
- !preview,
+ b_depsgraph,
+ false,
false,
Mesh::SUBDIVISION_NONE);
}
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index a05c982b367..dcadc735b8e 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -89,7 +89,7 @@ bool BlenderSync::object_is_light(BL::Object& b_ob)
{
BL::ID b_ob_data = b_ob.data();
- return (b_ob_data && b_ob_data.is_a(&RNA_Lamp));
+ return (b_ob_data && b_ob_data.is_a(&RNA_Light));
}
static uint object_ray_visibility(BL::Object& b_ob)
@@ -112,13 +112,14 @@ static uint object_ray_visibility(BL::Object& b_ob)
void BlenderSync::sync_light(BL::Object& b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
BL::Object& b_ob,
- BL::DupliObject& b_dupli_ob,
+ BL::Object& b_ob_instance,
+ int random_id,
Transform& tfm,
bool *use_portal)
{
/* test if we need to sync */
Light *light;
- ObjectKey key(b_parent, persistent_id, b_ob);
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
if(!light_map.sync(&light, b_ob, b_parent, key)) {
if(light->is_portal)
@@ -126,45 +127,59 @@ void BlenderSync::sync_light(BL::Object& b_parent,
return;
}
- BL::Lamp b_lamp(b_ob.data());
+ BL::Light b_light(b_ob.data());
/* type */
- switch(b_lamp.type()) {
- case BL::Lamp::type_POINT: {
- BL::PointLamp b_point_lamp(b_lamp);
- light->size = b_point_lamp.shadow_soft_size();
+ switch(b_light.type()) {
+ case BL::Light::type_POINT: {
+ BL::PointLight b_point_light(b_light);
+ light->size = b_point_light.shadow_soft_size();
light->type = LIGHT_POINT;
break;
}
- case BL::Lamp::type_SPOT: {
- BL::SpotLamp b_spot_lamp(b_lamp);
- light->size = b_spot_lamp.shadow_soft_size();
+ case BL::Light::type_SPOT: {
+ BL::SpotLight b_spot_light(b_light);
+ light->size = b_spot_light.shadow_soft_size();
light->type = LIGHT_SPOT;
- light->spot_angle = b_spot_lamp.spot_size();
- light->spot_smooth = b_spot_lamp.spot_blend();
+ light->spot_angle = b_spot_light.spot_size();
+ light->spot_smooth = b_spot_light.spot_blend();
break;
}
- case BL::Lamp::type_HEMI: {
+ case BL::Light::type_HEMI: {
light->type = LIGHT_DISTANT;
light->size = 0.0f;
break;
}
- case BL::Lamp::type_SUN: {
- BL::SunLamp b_sun_lamp(b_lamp);
- light->size = b_sun_lamp.shadow_soft_size();
+ case BL::Light::type_SUN: {
+ BL::SunLight b_sun_light(b_light);
+ light->size = b_sun_light.shadow_soft_size();
light->type = LIGHT_DISTANT;
break;
}
- case BL::Lamp::type_AREA: {
- BL::AreaLamp b_area_lamp(b_lamp);
+ case BL::Light::type_AREA: {
+ BL::AreaLight b_area_light(b_light);
light->size = 1.0f;
light->axisu = transform_get_column(&tfm, 0);
light->axisv = transform_get_column(&tfm, 1);
- light->sizeu = b_area_lamp.size();
- if(b_area_lamp.shape() == BL::AreaLamp::shape_RECTANGLE)
- light->sizev = b_area_lamp.size_y();
- else
- light->sizev = light->sizeu;
+ light->sizeu = b_area_light.size();
+ switch(b_area_light.shape()) {
+ case BL::AreaLight::shape_SQUARE:
+ light->sizev = light->sizeu;
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_RECTANGLE:
+ light->sizev = b_area_light.size_y();
+ light->round = false;
+ break;
+ case BL::AreaLight::shape_DISK:
+ light->sizev = light->sizeu;
+ light->round = true;
+ break;
+ case BL::AreaLight::shape_ELLIPSE:
+ light->sizev = b_area_light.size_y();
+ light->round = true;
+ break;
+ }
light->type = LIGHT_AREA;
break;
}
@@ -177,32 +192,32 @@ void BlenderSync::sync_light(BL::Object& b_parent,
/* shader */
vector<Shader*> used_shaders;
- find_shader(b_lamp, used_shaders, scene->default_light);
+ find_shader(b_light, used_shaders, scene->default_light);
light->shader = used_shaders[0];
/* shadow */
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
- light->cast_shadow = get_boolean(clamp, "cast_shadow");
- light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
+ PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
+ light->cast_shadow = get_boolean(clight, "cast_shadow");
+ light->use_mis = get_boolean(clight, "use_multiple_importance_sampling");
- int samples = get_int(clamp, "samples");
+ int samples = get_int(clight, "samples");
if(get_boolean(cscene, "use_square_samples"))
light->samples = samples * samples;
else
light->samples = samples;
- light->max_bounces = get_int(clamp, "max_bounces");
+ light->max_bounces = get_int(clight, "max_bounces");
- if(b_dupli_ob) {
- light->random_id = b_dupli_ob.random_id();
+ if(b_ob != b_ob_instance) {
+ light->random_id = random_id;
}
else {
light->random_id = hash_int_2d(hash_string(b_ob.name().c_str()), 0);
}
if(light->type == LIGHT_AREA)
- light->is_portal = get_boolean(clamp, "is_portal");
+ light->is_portal = get_boolean(clight, "is_portal");
else
light->is_portal = false;
@@ -275,24 +290,46 @@ void BlenderSync::sync_background_light(bool use_portal)
/* 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,
+Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
+ BL::ViewLayer& b_view_layer,
+ BL::DepsgraphObjectInstance& b_instance,
float motion_time,
bool hide_tris,
BlenderObjectCulling& culling,
bool *use_portal)
{
- BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
- bool motion = motion_time != 0.0f;
+ const bool is_instance = b_instance.is_instance();
+ BL::Object b_ob = b_instance.object();
+ BL::Object b_parent = is_instance ? b_instance.parent()
+ : b_instance.object();
+ BL::Object b_ob_instance = is_instance ? b_instance.instance_object()
+ : b_ob;
+ const bool motion = motion_time != 0.0f;
+ /*const*/ Transform tfm = get_transform(b_ob.matrix_world());
+ int *persistent_id = NULL;
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
+ if(is_instance) {
+ persistent_id_array = b_instance.persistent_id();
+ persistent_id = persistent_id_array.data;
+ }
/* light is handled separately */
- 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, b_dupli_ob, tfm, use_portal);
+ if(!motion && object_is_light(b_ob)) {
+ /* TODO: don't use lights for excluded layers used as mask layer,
+ * when dynamic overrides are back. */
+#if 0
+ if(!((layer_flag & view_layer.holdout_layer) &&
+ (layer_flag & view_layer.exclude_layer)))
+#endif
+ {
+ sync_light(b_parent,
+ persistent_id,
+ b_ob,
+ b_ob_instance,
+ is_instance ? b_instance.random_id() : 0,
+ tfm,
+ use_portal);
+ }
return NULL;
}
@@ -309,21 +346,24 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
/* Visibility flags for both parent and child. */
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
- bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0 ||
- get_boolean(cobject, "is_holdout");
+ bool use_holdout = get_boolean(cobject, "is_holdout") ||
+ b_parent.holdout_get(b_view_layer);
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
if(b_parent.ptr.data != b_ob.ptr.data) {
visibility &= object_ray_visibility(b_parent);
}
- /* Make holdout objects on excluded layer invisible for non-camera rays. */
- if(use_holdout && (layer_flag & render_layer.exclude_layer)) {
+ /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */
+#if 0
+ if(use_holdout && (layer_flag & view_layer.exclude_layer)) {
visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA);
}
+#endif
- /* Hide objects not on render layer from camera rays. */
- if(!(layer_flag & render_layer.layer)) {
+ /* Clear camera visibility for indirect only objects. */
+ bool use_indirect_only = b_parent.indirect_only_get(b_view_layer);
+ if(use_indirect_only) {
visibility &= ~PATH_RAY_CAMERA;
}
@@ -333,7 +373,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
}
/* key to lookup object */
- ObjectKey key(b_parent, persistent_id, b_ob);
+ ObjectKey key(b_parent, persistent_id, b_ob_instance);
Object *object;
/* motion vector case */
@@ -349,7 +389,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
/* mesh deformation */
if(object->mesh)
- sync_mesh_motion(b_ob, object, motion_time);
+ sync_mesh_motion(b_depsgraph, b_ob, object, motion_time);
}
return object;
@@ -362,7 +402,7 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
object_updated = true;
/* mesh sync */
- object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
+ object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, hide_tris);
/* special case not tracked by object update flags */
@@ -444,10 +484,13 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
}
/* dupli texture coordinates and random_id */
- if(b_dupli_ob) {
- object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f);
- object->dupli_uv = get_float2(b_dupli_ob.uv());
- object->random_id = b_dupli_ob.random_id();
+ if(is_instance) {
+ object->dupli_generated = 0.5f*get_float3(b_instance.orco()) - make_float3(0.5f, 0.5f, 0.5f);
+ object->dupli_uv = get_float2(b_instance.uv());
+ object->random_id = b_instance.random_id();
+
+ /* Sync possible particle data. */
+ sync_dupli_particle(b_ob, b_instance, object);
}
else {
object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
@@ -476,12 +519,14 @@ static bool object_render_hide_original(BL::Object::type_enum ob_type,
static bool object_render_hide(BL::Object& b_ob,
bool top_level,
bool parent_hide,
- bool& hide_triangles)
+ bool& hide_triangles,
+ BL::Depsgraph::mode_enum depsgraph_mode)
{
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
bool hair_present = false;
+ bool has_particles = false;
bool show_emitter = false;
bool hide_emitter = false;
bool hide_as_dupli_parent = false;
@@ -491,20 +536,22 @@ static bool object_render_hide(BL::Object& b_ob,
if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
hair_present = true;
-
- if(b_psys->settings().use_render_emitter())
- show_emitter = true;
- else
- hide_emitter = true;
+ has_particles = true;
}
- if(show_emitter)
- hide_emitter = false;
+ /* Both mode_PREVIEW and mode_VIEWPORT are treated the same here.*/
+ const bool show_duplicator = depsgraph_mode == BL::Depsgraph::mode_RENDER
+ ? b_ob.show_duplicator_for_render()
+ : b_ob.show_duplicator_for_viewport();
- /* duplicators hidden by default, except dupliframes which duplicate self */
- if(b_ob.is_duplicator())
- if(top_level || b_ob.dupli_type() != BL::Object::dupli_type_FRAMES)
+ if(has_particles) {
+ show_emitter = show_duplicator;
+ hide_emitter = !show_emitter;
+ } else if(b_ob.is_duplicator()) {
+ if(top_level || show_duplicator) {
hide_as_dupli_parent = true;
+ }
+ }
/* hide original object for duplis */
BL::Object parent = b_ob.parent();
@@ -533,19 +580,11 @@ static bool object_render_hide(BL::Object& b_ob,
}
}
-static bool object_render_hide_duplis(BL::Object& b_ob)
-{
- BL::Object parent = b_ob.parent();
-
- return (parent && object_render_hide_original(b_ob.type(), parent.dupli_type()));
-}
-
/* Object Loop */
-void BlenderSync::sync_objects(float motion_time)
+void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
{
/* layer data */
- uint scene_layer = render_layer.scene_layer;
bool motion = motion_time != 0.0f;
if(!motion) {
@@ -564,100 +603,40 @@ void BlenderSync::sync_objects(float motion_time)
BlenderObjectCulling culling(scene, b_scene);
/* object loop */
- BL::Scene::object_bases_iterator b_base;
- BL::Scene b_sce = b_scene;
- /* modifier result type (not exposed as enum in C++ API)
- * 1 : DAG_EVAL_PREVIEW
- * 2 : DAG_EVAL_RENDER
- */
- int dupli_settings = (render_layer.use_viewport_visibility) ? 1 : 2;
-
bool cancel = false;
bool use_portal = false;
- uint layer_override = get_layer(b_engine.layer_override());
- for(; b_sce && !cancel; b_sce = b_sce.background_set()) {
- /* Render layer's scene_layer is affected by local view already,
- * which is not a desired behavior here.
- */
- uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
- for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) {
- BL::Object b_ob = b_base->object();
- bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render();
- uint ob_layer = get_layer(b_base->layers(),
- b_base->layers_local_view(),
- object_is_light(b_ob),
- scene_layers);
- hide = hide || !(ob_layer & scene_layer);
-
- if(!hide) {
- progress.set_sync_status("Synchronizing object", b_ob.name());
-
- /* load per-object culling data */
- culling.init_object(scene, b_ob);
-
- if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) {
- /* dupli objects */
- b_ob.dupli_list_create(b_data, b_scene, dupli_settings);
-
- BL::Object::dupli_list_iterator b_dup;
-
- for(b_ob.dupli_list.begin(b_dup); b_dup != b_ob.dupli_list.end(); ++b_dup) {
- Transform tfm = get_transform(b_dup->matrix());
- BL::Object b_dup_ob = b_dup->object();
- bool dup_hide = (render_layer.use_viewport_visibility)? b_dup_ob.hide(): b_dup_ob.hide_render();
- bool in_dupli_group = (b_dup->type() == BL::DupliObject::type_GROUP);
- bool hide_tris;
-
- if(!(b_dup->hide() || dup_hide || object_render_hide(b_dup_ob, false, in_dupli_group, hide_tris))) {
- /* the persistent_id allows us to match dupli objects
- * between frames and updates */
- 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,
- culling,
- &use_portal);
-
- /* sync possible particle data, note particle_id
- * starts counting at 1, first is dummy particle */
- if(!motion && object) {
- sync_dupli_particle(b_ob, *b_dup, object);
- }
-
- }
- }
-
- b_ob.dupli_list_clear();
- }
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+ BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
- /* test if object needs to be hidden */
- bool hide_tris;
-
- if(!object_render_hide(b_ob, true, true, hide_tris)) {
- /* object itself */
- Transform tfm = get_transform(b_ob.matrix_world());
- BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
- sync_object(b_ob,
- NULL,
- b_empty_dupli_ob,
- tfm,
- ob_layer,
- motion_time,
- hide_tris,
- culling,
- &use_portal);
- }
- }
+ BL::Depsgraph::object_instances_iterator b_instance_iter;
+ for(b_depsgraph.object_instances.begin(b_instance_iter);
+ b_instance_iter != b_depsgraph.object_instances.end() && !cancel;
+ ++b_instance_iter)
+ {
+ BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
+ BL::Object b_ob = b_instance.object();
- cancel = progress.get_cancel();
- }
+ progress.set_sync_status("Synchronizing object", b_ob.name());
+
+ /* load per-object culling data */
+ culling.init_object(scene, b_ob);
+
+ /* test if object needs to be hidden */
+ bool hide_tris;
+
+ if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
+ /* object itself */
+ sync_object(b_depsgraph,
+ b_view_layer,
+ b_instance,
+ motion_time,
+ hide_tris,
+ culling,
+ &use_portal);
+ }
+
+ cancel = progress.get_cancel();
}
progress.set_sync_status("");
@@ -681,6 +660,7 @@ void BlenderSync::sync_objects(float motion_time)
}
void BlenderSync::sync_motion(BL::RenderSettings& b_render,
+ BL::Depsgraph& b_depsgraph,
BL::Object& b_override,
int width, int height,
void **python_thread_state)
@@ -710,6 +690,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
assert(scene->camera->motion_position == Camera::MOTION_POSITION_START);
frame_center_delta = shuttertime * 0.5f;
}
+
float time = frame_center + subframe_center + frame_center_delta;
int frame = (int)floorf(time);
float subframe = time - frame;
@@ -717,7 +698,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
b_engine.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
sync_camera_motion(b_render, b_cam, width, height, 0.0f);
- sync_objects(0.0f);
+ sync_objects(b_depsgraph, 0.0f);
}
/* always sample these times for camera motion */
@@ -756,7 +737,7 @@ void BlenderSync::sync_motion(BL::RenderSettings& b_render,
}
/* sync object */
- sync_objects(relative_time);
+ sync_objects(b_depsgraph, relative_time);
}
/* we need to set the python thread state again because this
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index 727d9acf729..a733a499826 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -28,11 +28,11 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
- BL::DupliObject& b_dup,
+ BL::DepsgraphObjectInstance& b_instance,
Object *object)
{
/* test if this dupli was generated from a particle sytem */
- BL::ParticleSystem b_psys = b_dup.particle_system();
+ BL::ParticleSystem b_psys = b_instance.particle_system();
if(!b_psys)
return false;
@@ -43,7 +43,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
return false;
/* don't handle child particles yet */
- BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup.persistent_id();
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_instance.persistent_id();
if(persistent_id[0] >= b_psys.particles.length())
return false;
@@ -53,7 +53,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object& b_ob,
ParticleSystem *psys;
bool first_use = !particle_system_map.is_used(key);
- bool need_update = particle_system_map.sync(&psys, b_ob, b_dup.object(), key);
+ bool need_update = particle_system_map.sync(&psys, b_ob, b_instance.object(), key);
/* no update needed? */
if(!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 997176f9d44..2a0a7895763 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -203,10 +203,10 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/)
static PyObject *create_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pyengine, *pyuserpref, *pydata, *pyscene, *pyregion, *pyv3d, *pyrv3d;
+ PyObject *pyengine, *pyuserpref, *pydata, *pyregion, *pyv3d, *pyrv3d;
int preview_osl;
- if(!PyArg_ParseTuple(args, "OOOOOOOi", &pyengine, &pyuserpref, &pydata, &pyscene,
+ if(!PyArg_ParseTuple(args, "OOOOOOi", &pyengine, &pyuserpref, &pydata,
&pyregion, &pyv3d, &pyrv3d, &preview_osl))
{
return NULL;
@@ -225,10 +225,6 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData data(dataptr);
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene scene(sceneptr);
-
PointerRNA regionptr;
RNA_pointer_create(NULL, &RNA_Region, pylong_as_voidptr_typesafe(pyregion), &regionptr);
BL::Region region(regionptr);
@@ -249,27 +245,13 @@ static PyObject *create_func(PyObject * /*self*/, PyObject *args)
int width = region.width();
int height = region.height();
- session = new BlenderSession(engine, userpref, data, scene, v3d, rv3d, width, height);
+ session = new BlenderSession(engine, userpref, data, v3d, rv3d, width, height);
}
else {
- /* override some settings for preview */
- if(engine.is_preview()) {
- PointerRNA cscene = RNA_pointer_get(&sceneptr, "cycles");
-
- RNA_boolean_set(&cscene, "shading_system", preview_osl);
- RNA_boolean_set(&cscene, "use_progressive_refine", true);
- }
-
/* offline session or preview render */
- session = new BlenderSession(engine, userpref, data, scene);
+ session = new BlenderSession(engine, userpref, data, preview_osl);
}
- python_thread_state_save(&session->python_thread_state);
-
- session->create();
-
- python_thread_state_restore(&session->python_thread_state);
-
return PyLong_FromVoidPtr(session);
}
@@ -280,13 +262,22 @@ static PyObject *free_func(PyObject * /*self*/, PyObject *value)
Py_RETURN_NONE;
}
-static PyObject *render_func(PyObject * /*self*/, PyObject *value)
+static PyObject *render_func(PyObject * /*self*/, PyObject *args)
{
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
+ PyObject *pysession, *pydepsgraph;
+
+ if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
+
+ BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, (ID*)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
python_thread_state_save(&session->python_thread_state);
- session->render();
+ session->render(b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
@@ -296,16 +287,20 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *value)
/* pixel_array and result passed as pointers */
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pyobject;
+ PyObject *pysession, *pydepsgraph, *pyobject;
PyObject *pypixel_array, *pyresult;
const char *pass_type;
int num_pixels, depth, object_id, pass_filter;
- if(!PyArg_ParseTuple(args, "OOsiiOiiO", &pysession, &pyobject, &pass_type, &pass_filter, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
+ if(!PyArg_ParseTuple(args, "OOOsiiOiiO", &pysession, &pydepsgraph, &pyobject, &pass_type, &pass_filter, &object_id, &pypixel_array, &num_pixels, &depth, &pyresult))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
+
PointerRNA objectptr;
RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyobject), &objectptr);
BL::Object b_object(objectptr);
@@ -318,7 +313,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
python_thread_state_save(&session->python_thread_state);
- session->bake(b_object, pass_type, pass_filter, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
+ session->bake(b_depsgraph, b_object, pass_type, pass_filter, object_id, b_bake_pixel, (size_t)num_pixels, depth, (float *)b_result);
python_thread_state_restore(&session->python_thread_state);
@@ -327,9 +322,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pyv3d, *pyrv3d;
+ PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pyv3d, &pyrv3d))
+ if(!PyArg_ParseTuple(args, "OOOO", &pysession, &pygraph, &pyv3d, &pyrv3d))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
@@ -347,9 +342,9 @@ static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
{
- PyObject *pysession, *pydata, *pyscene;
+ PyObject *pysession, *pydata, *pydepsgraph;
- if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pyscene))
+ if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pydepsgraph))
return NULL;
BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
@@ -358,26 +353,35 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
RNA_main_pointer_create((Main*)PyLong_AsVoidPtr(pydata), &dataptr);
BL::BlendData b_data(dataptr);
- PointerRNA sceneptr;
- RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
- BL::Scene b_scene(sceneptr);
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
python_thread_state_save(&session->python_thread_state);
- session->reset_session(b_data, b_scene);
+ session->reset_session(b_data, b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
Py_RETURN_NONE;
}
-static PyObject *sync_func(PyObject * /*self*/, PyObject *value)
+static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
{
- BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(value);
+ PyObject *pysession, *pydepsgraph;
+
+ if(!PyArg_ParseTuple(args, "OO", &pysession, &pydepsgraph))
+ return NULL;
+
+ BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA depsgraphptr;
+ RNA_pointer_create(NULL, &RNA_Depsgraph, PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
+ BL::Depsgraph b_depsgraph(depsgraphptr);
python_thread_state_save(&session->python_thread_state);
- session->synchronize();
+ session->synchronize(b_depsgraph);
python_thread_state_restore(&session->python_thread_state);
@@ -759,10 +763,10 @@ static PyMethodDef methods[] = {
{"exit", exit_func, METH_VARARGS, ""},
{"create", create_func, METH_VARARGS, ""},
{"free", free_func, METH_O, ""},
- {"render", render_func, METH_O, ""},
+ {"render", render_func, METH_VARARGS, ""},
{"bake", bake_func, METH_VARARGS, ""},
{"draw", draw_func, METH_VARARGS, ""},
- {"sync", sync_func, METH_O, ""},
+ {"sync", sync_func, METH_VARARGS, ""},
{"reset", reset_func, METH_VARARGS, ""},
#ifdef WITH_OSL
{"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 75c7dcee05e..b639dcc4b00 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -55,21 +55,23 @@ bool BlenderSession::print_render_stats = false;
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene)
-: b_engine(b_engine),
+ bool preview_osl)
+: session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
b_render(b_engine.render()),
- b_scene(b_scene),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
b_v3d(PointerRNA_NULL),
b_rv3d(PointerRNA_NULL),
+ width(0),
+ height(0),
+ preview_osl(preview_osl),
python_thread_state(NULL)
{
/* offline render */
-
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
-
background = true;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -79,23 +81,25 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height)
-: b_engine(b_engine),
+: session(NULL),
+ sync(NULL),
+ b_engine(b_engine),
b_userpref(b_userpref),
b_data(b_data),
- b_render(b_scene.render()),
- b_scene(b_scene),
+ b_render(b_engine.render()),
+ b_depsgraph(PointerRNA_NULL),
+ b_scene(PointerRNA_NULL),
b_v3d(b_v3d),
b_rv3d(b_rv3d),
width(width),
height(height),
+ preview_osl(false),
python_thread_state(NULL)
{
/* 3d view render */
-
background = false;
last_redraw_time = 0.0;
start_resize_time = 0.0;
@@ -144,26 +148,19 @@ void BlenderSession::create_session()
session->scene = scene;
+ /* There is no single depsgraph to use for the entire render.
+ * So we need to handle this differently.
+ *
+ * We could loop over the final render result render layers in pipeline and keep Cycles unaware of multiple layers,
+ * or perhaps move syncing further down in the pipeline.
+ */
/* create sync */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
BL::Object b_camera_override(b_engine.camera_override());
if(b_v3d) {
- if(session_pause == false) {
- /* full data sync */
- sync->sync_view(b_v3d, b_rv3d, width, height);
- sync->sync_data(b_render,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state,
- b_rlay_name.c_str());
- }
+ sync->sync_view(b_v3d, b_rv3d, width, height);
}
else {
- /* for final render we will do full data sync per render layer, only
- * do some basic syncing here, no objects or materials for speed */
- sync->sync_render_layers(b_v3d, NULL);
- sync->sync_integrator();
sync->sync_camera(b_render, b_camera_override, width, height, "");
}
@@ -176,18 +173,40 @@ void BlenderSession::create_session()
update_resumable_tile_manager(session_params.samples);
}
-void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
+void BlenderSession::reset_session(BL::BlendData& b_data, BL::Depsgraph& b_depsgraph)
{
- b_data = b_data_;
- b_render = b_engine.render();
- b_scene = b_scene_;
+ this->b_data = b_data;
+ this->b_depsgraph = b_depsgraph;
+ this->b_scene = b_depsgraph.scene_eval();
+
+ if (preview_osl) {
+ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+ RNA_boolean_set(&cscene, "shading_system", preview_osl);
+ }
+
+ if (b_v3d) {
+ this->b_render = b_scene.render();
+ }
+ else {
+ this->b_render = b_engine.render();
+ width = render_resolution_x(b_render);
+ height = render_resolution_y(b_render);
+ }
+
+ if (session == NULL) {
+ create();
+ }
+
+ if (b_v3d) {
+ /* NOTE: We need to create session, but all the code from below
+ * will make viewport render to stuck on initialization.
+ */
+ return;
+ }
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
- width = render_resolution_x(b_render);
- height = render_resolution_y(b_render);
-
if(scene->params.modified(scene_params) ||
session->params.modified(session_params) ||
!scene_params.persistent_data)
@@ -195,11 +214,8 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
/* if scene or session parameters changed, it's easier to simply re-create
* them rather than trying to distinguish which settings need to be updated
*/
-
- delete session;
-
+ free_session();
create_session();
-
return;
}
@@ -213,16 +229,12 @@ void BlenderSession::reset_session(BL::BlendData& b_data_, BL::Scene& b_scene_)
*/
session->stats.mem_peak = session->stats.mem_used;
+ /* There is no single depsgraph to use for the entire render.
+ * See note on create_session().
+ */
/* sync object should be re-created */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
- /* for final render we will do full data sync per render layer, only
- * do some basic syncing here, no objects or materials for speed */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_render_layers(b_v3d, NULL);
- sync->sync_integrator();
- sync->sync_camera(b_render, b_camera_override, width, height, "");
-
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render,
@@ -382,8 +394,10 @@ static void add_cryptomatte_layer(BL::RenderResult& b_rr, string name, string ma
render_add_metadata(b_rr, prefix+"manifest", manifest);
}
-void BlenderSession::render()
+void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
{
+ b_depsgraph = b_depsgraph_;
+
/* set callback to write out render results */
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2);
@@ -393,126 +407,91 @@ void BlenderSession::render()
BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_v3d, b_rv3d, scene->camera, width, height);
/* render each layer */
- BL::RenderSettings r = b_scene.render();
- BL::RenderSettings::layers_iterator b_layer_iter;
- BL::RenderResult::views_iterator b_view_iter;
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
/* We do some special meta attributes when we only have single layer. */
- const bool is_single_layer = (r.layers.length() == 1);
-
- for(r.layers.begin(b_layer_iter); b_layer_iter != r.layers.end(); ++b_layer_iter) {
- b_rlay_name = b_layer_iter->name();
+ const bool is_single_layer = (b_scene.view_layers.length() == 1);
- /* temporary render result to find needed passes and views */
- BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str(), NULL);
- BL::RenderResult::layers_iterator b_single_rlay;
- b_rr.layers.begin(b_single_rlay);
-
- /* layer will be missing if it was disabled in the UI */
- if(b_single_rlay == b_rr.layers.end()) {
- end_render_result(b_engine, b_rr, true, true, false);
- continue;
- }
-
- BL::RenderLayer b_rlay = *b_single_rlay;
-
- /* add passes */
- vector<Pass> passes = sync->sync_render_passes(b_rlay, *b_layer_iter, session_params);
- buffer_params.passes = passes;
-
- PointerRNA crl = RNA_pointer_get(&b_layer_iter->ptr, "cycles");
- bool use_denoising = get_boolean(crl, "use_denoising");
- bool denoising_passes = use_denoising || get_boolean(crl, "denoising_store_passes");
-
- session->tile_manager.schedule_denoising = use_denoising;
- buffer_params.denoising_data_pass = denoising_passes;
- buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
-
- session->params.use_denoising = use_denoising;
- session->params.denoising_passes = denoising_passes;
- session->params.denoising_radius = get_int(crl, "denoising_radius");
- session->params.denoising_strength = get_float(crl, "denoising_strength");
- session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength");
- session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca");
-
- scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
- scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
- scene->film->pass_alpha_threshold = b_layer_iter->pass_alpha_threshold();
- scene->film->tag_passes_update(scene, passes);
- scene->film->tag_update(scene);
- scene->integrator->tag_update(scene);
-
- int view_index = 0;
- for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
- b_rview_name = b_view_iter->name();
-
- /* set the current view */
- b_engine.active_view_set(b_rview_name.c_str());
-
- /* update scene */
- BL::Object b_camera_override(b_engine.camera_override());
- sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
- sync->sync_data(b_render,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state,
- b_rlay_name.c_str());
-
- /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
- if(view_index != 0) {
- scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
- scene->integrator->tag_update(scene);
- }
-
- /* Update number of samples per layer. */
- int samples = sync->get_layer_samples();
- bool bound_samples = sync->get_layer_bound_samples();
- int effective_layer_samples;
+ /* temporary render result to find needed passes and views */
+ BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_view_layer.name().c_str(), NULL);
+ BL::RenderResult::layers_iterator b_single_rlay;
+ b_rr.layers.begin(b_single_rlay);
+ BL::RenderLayer b_rlay = *b_single_rlay;
+ b_rlay_name = b_view_layer.name();
+
+ /* add passes */
+ vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer, session_params);
+ buffer_params.passes = passes;
+
+ PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
+ bool use_denoising = get_boolean(crl, "use_denoising");
+ bool denoising_passes = use_denoising || get_boolean(crl, "denoising_store_passes");
+
+ session->tile_manager.schedule_denoising = use_denoising;
+ buffer_params.denoising_data_pass = denoising_passes;
+ buffer_params.denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES);
+
+ session->params.use_denoising = use_denoising;
+ session->params.denoising_passes = denoising_passes;
+ session->params.denoising_radius = get_int(crl, "denoising_radius");
+ session->params.denoising_strength = get_float(crl, "denoising_strength");
+ session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength");
+ session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca");
+
+ scene->film->denoising_data_pass = buffer_params.denoising_data_pass;
+ scene->film->denoising_clean_pass = buffer_params.denoising_clean_pass;
+ session->params.denoising_radius = get_int(crl, "denoising_radius");
+ session->params.denoising_strength = get_float(crl, "denoising_strength");
+ session->params.denoising_feature_strength = get_float(crl, "denoising_feature_strength");
+ session->params.denoising_relative_pca = get_boolean(crl, "denoising_relative_pca");
+
+ scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold();
+ scene->film->tag_passes_update(scene, passes);
+ scene->film->tag_update(scene);
+ scene->integrator->tag_update(scene);
- if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
- effective_layer_samples = samples;
- else
- effective_layer_samples = session_params.samples;
+ BL::RenderResult::views_iterator b_view_iter;
+ int view_index = 0;
+ for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter, ++view_index) {
+ b_rview_name = b_view_iter->name();
- /* Update tile manager if we're doing resumable render. */
- update_resumable_tile_manager(effective_layer_samples);
+ /* set the current view */
+ b_engine.active_view_set(b_rview_name.c_str());
- /* Update session itself. */
- session->reset(buffer_params, effective_layer_samples);
+ /* update scene */
+ BL::Object b_camera_override(b_engine.camera_override());
+ sync->sync_camera(b_render, b_camera_override, width, height, b_rview_name.c_str());
+ sync->sync_data(b_render,
+ b_depsgraph,
+ b_v3d,
+ b_camera_override,
+ width, height,
+ &python_thread_state);
+ builtin_images_load();
+
+ /* Make sure all views have different noise patterns. - hardcoded value just to make it random */
+ if(view_index != 0) {
+ scene->integrator->seed += hash_int_2d(scene->integrator->seed, hash_int(view_index * 0xdeadbeef));
+ scene->integrator->tag_update(scene);
+ }
- /* render */
- session->start();
- session->wait();
+ int effective_layer_samples = session_params.samples;
- if(session->progress.get_cancel())
- break;
- }
+ /* TODO: Update number of samples per layer. */
+#if 0
+ if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
+ effective_layer_samples = samples;
+#endif
- BL::RenderResult b_full_rr = b_engine.get_result();
- if(is_single_layer) {
- string num_aa_samples = string_printf("%d", session->params.samples);
- render_add_metadata(b_full_rr, "Cycles Samples", num_aa_samples);
- /* TODO(sergey): Report whether we're doing resumable render
- * and also start/end sample if so.
- */
- }
+ /* Update tile manager if we're doing resumable render. */
+ update_resumable_tile_manager(effective_layer_samples);
- if(scene->film->cryptomatte_passes & CRYPT_OBJECT) {
- add_cryptomatte_layer(b_full_rr, b_rlay_name+".CryptoObject",
- scene->object_manager->get_cryptomatte_objects(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
- add_cryptomatte_layer(b_full_rr, b_rlay_name+".CryptoMaterial",
- scene->shader_manager->get_cryptomatte_materials(scene));
- }
- if(scene->film->cryptomatte_passes & CRYPT_ASSET) {
- add_cryptomatte_layer(b_full_rr, b_rlay_name+".CryptoAsset",
- scene->object_manager->get_cryptomatte_assets(scene));
- }
+ /* Update session itself. */
+ session->reset(buffer_params, effective_layer_samples);
- /* free result without merging */
- end_render_result(b_engine, b_rr, true, true, false);
+ /* render */
+ session->start();
+ session->wait();
if(!b_engine.is_preview() && background && print_render_stats) {
RenderStats stats;
@@ -524,6 +503,32 @@ void BlenderSession::render()
break;
}
+ if(is_single_layer) {
+ BL::RenderResult b_rr = b_engine.get_result();
+ string num_aa_samples = string_printf("%d", session->params.samples);
+ b_rr.stamp_data_add_field("Cycles Samples", num_aa_samples.c_str());
+ /* TODO(sergey): Report whether we're doing resumable render
+ * and also start/end sample if so.
+ */
+ }
+
+ /* Write cryptomatte metadata. */
+ if(scene->film->cryptomatte_passes & CRYPT_OBJECT) {
+ add_cryptomatte_layer(b_rr, b_rlay_name+".CryptoObject",
+ scene->object_manager->get_cryptomatte_objects(scene));
+ }
+ if(scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
+ add_cryptomatte_layer(b_rr, b_rlay_name+".CryptoMaterial",
+ scene->shader_manager->get_cryptomatte_materials(scene));
+ }
+ if(scene->film->cryptomatte_passes & CRYPT_ASSET) {
+ add_cryptomatte_layer(b_rr, b_rlay_name+".CryptoAsset",
+ scene->object_manager->get_cryptomatte_assets(scene));
+ }
+
+ /* free result without merging */
+ end_render_result(b_engine, b_rr, true, true, false);
+
double total_time, render_time;
session->progress.get_time(total_time, render_time);
VLOG(1) << "Total render time: " << total_time;
@@ -533,6 +538,8 @@ void BlenderSession::render()
session->write_render_tile_cb = function_null;
session->update_render_tile_cb = function_null;
+ /* TODO: find a way to clear this data for persistent data render */
+#if 0
/* free all memory used (host and device), so we wouldn't leave render
* engine with extra memory allocated
*/
@@ -541,6 +548,7 @@ void BlenderSession::render()
delete sync;
sync = NULL;
+#endif
}
static void populate_bake_data(BakeData *data, const
@@ -589,7 +597,8 @@ static int bake_pass_filter_get(const int pass_filter)
return flag;
}
-void BlenderSession::bake(BL::Object& b_object,
+void BlenderSession::bake(BL::Depsgraph& b_depsgraph_,
+ BL::Object& b_object,
const string& pass_type,
const int pass_filter,
const int object_id,
@@ -598,6 +607,8 @@ void BlenderSession::bake(BL::Object& b_object,
const int /*depth*/,
float result[])
{
+ b_depsgraph = b_depsgraph_;
+
ShaderEvalType shader_type = get_shader_type(pass_type);
/* Set baking flag in advance, so kernel loading can check if we need
@@ -630,11 +641,12 @@ void BlenderSession::bake(BL::Object& b_object,
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(b_render,
- b_v3d,
- b_camera_override,
- width, height,
- &python_thread_state,
- b_rlay_name.c_str());
+ b_depsgraph,
+ b_v3d,
+ b_camera_override,
+ width, height,
+ &python_thread_state);
+ builtin_images_load();
}
BakeData *bake_data = NULL;
@@ -768,7 +780,7 @@ void BlenderSession::update_render_result(BL::RenderResult& b_rr,
do_write_update_render_result(b_rr, b_rlay, rtile, true);
}
-void BlenderSession::synchronize()
+void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
{
/* only used for viewport render */
if(!b_v3d)
@@ -794,7 +806,7 @@ void BlenderSession::synchronize()
/* copy recalc flags, outside of mutex so we can decide to do the real
* synchronization at a later time to not block on running updates */
- sync->sync_recalc();
+ sync->sync_recalc(b_depsgraph_);
/* don't do synchronization if on pause */
if(session_pause) {
@@ -809,19 +821,23 @@ void BlenderSession::synchronize()
}
/* data and camera synchronize */
+ b_depsgraph = b_depsgraph_;
+
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_data(b_render,
+ b_depsgraph,
b_v3d,
b_camera_override,
width, height,
- &python_thread_state,
- b_rlay_name.c_str());
+ &python_thread_state);
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
sync->sync_camera(b_render, b_camera_override, width, height, "");
+ builtin_images_load();
+
/* unlock */
session->scene->mutex.unlock();
@@ -1329,6 +1345,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
}
else {
+ /* We originally were passing view_layer here but in reality we need a
+ * a depsgraph to pass to the RE_point_density_minmax() function.
+ */
/* TODO(sergey): Check we're indeed in shader node tree. */
PointerRNA ptr;
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
@@ -1336,14 +1355,23 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
if(b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
int length;
- int settings = background ? 1 : 0; /* 1 - render settings, 0 - vewport settings. */
- b_point_density_node.calc_point_density(b_scene, settings, &length, &pixels);
+ b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
}
}
return false;
}
+void BlenderSession::builtin_images_load()
+{
+ /* Force builtin images to be loaded along with Blender data sync. This
+ * is needed because we may be reading from depsgraph evaluated data which
+ * can be freed by Blender before Cycles reads it. */
+ ImageManager *manager = session->scene->image_manager;
+ Device *device = session->device;
+ manager->device_load_builtin(device, session->scene, session->progress);
+}
+
void BlenderSession::update_resumable_tile_manager(int num_samples)
{
const int num_resumable_chunks = BlenderSession::num_resumable_chunks,
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 540fa6a8a84..c83d3ee9aa3 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -37,12 +37,11 @@ public:
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene);
+ bool preview_osl);
BlenderSession(BL::RenderEngine& b_engine,
BL::UserPreferences& b_userpref,
BL::BlendData& b_data,
- BL::Scene& b_scene,
BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height);
@@ -56,12 +55,13 @@ public:
void free_session();
void reset_session(BL::BlendData& b_data,
- BL::Scene& b_scene);
+ BL::Depsgraph& b_depsgraph);
/* offline render */
- void render();
+ void render(BL::Depsgraph& b_depsgraph);
- void bake(BL::Object& b_object,
+ void bake(BL::Depsgraph& b_depsgrah,
+ BL::Object& b_object,
const string& pass_type,
const int custom_flag,
const int object_id,
@@ -83,7 +83,7 @@ public:
void update_render_tile(RenderTile& rtile, bool highlight);
/* interactive updates */
- void synchronize();
+ void synchronize(BL::Depsgraph& b_depsgraph);
/* drawing */
bool draw(int w, int h);
@@ -105,6 +105,7 @@ public:
BL::UserPreferences b_userpref;
BL::BlendData b_data;
BL::RenderSettings b_render;
+ BL::Depsgraph b_depsgraph;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
@@ -117,6 +118,7 @@ public:
double last_status_time;
int width, height;
+ bool preview_osl;
double start_resize_time;
void *python_thread_state;
@@ -166,6 +168,7 @@ protected:
float *pixels,
const size_t pixels_size,
const bool free_cache);
+ void builtin_images_load();
/* Update tile manager to reflect resumable render settings. */
void update_resumable_tile_manager(int num_samples);
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 3eefb92f6af..439f6bdd32e 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -231,18 +231,11 @@ static void get_tex_mapping(TextureMapping *mapping,
mapping->max = get_float3(b_mapping.max());
}
-static bool is_output_node(BL::Node& b_node)
-{
- return (b_node.is_a(&RNA_ShaderNodeOutputMaterial)
- || b_node.is_a(&RNA_ShaderNodeOutputWorld)
- || b_node.is_a(&RNA_ShaderNodeOutputLamp));
-}
-
static ShaderNode *add_node(Scene *scene,
BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
- const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree,
BL::ShaderNode& b_node)
@@ -677,7 +670,9 @@ static ShaderNode *add_node(Scene *scene,
image->animated = b_image_node.image_user().use_auto_refresh();
image->use_alpha = b_image.use_alpha();
+ /* TODO: restore */
/* TODO(sergey): Does not work properly when we change builtin type. */
+#if 0
if(b_image.is_updated()) {
scene->image_manager->tag_reload_image(
image->filename.string(),
@@ -686,6 +681,7 @@ static ShaderNode *add_node(Scene *scene,
get_image_extension(b_image_node),
image->use_alpha);
}
+#endif
}
image->color_space = (NodeImageColorSpace)b_image_node.color_space();
image->projection = (NodeImageProjection)b_image_node.projection();
@@ -725,7 +721,9 @@ static ShaderNode *add_node(Scene *scene,
env->animated = b_env_node.image_user().use_auto_refresh();
env->use_alpha = b_image.use_alpha();
+ /* TODO: restore */
/* TODO(sergey): Does not work properly when we change builtin type. */
+#if 0
if(b_image.is_updated()) {
scene->image_manager->tag_reload_image(
env->filename.string(),
@@ -734,6 +732,7 @@ static ShaderNode *add_node(Scene *scene,
EXTENSION_REPEAT,
env->use_alpha);
}
+#endif
}
env->color_space = (NodeImageColorSpace)b_env_node.color_space();
env->interpolation = get_image_interpolation(b_env_node);
@@ -876,13 +875,12 @@ static ShaderNode *add_node(Scene *scene,
point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
point_density->interpolation = get_image_interpolation(b_point_density_node);
point_density->builtin_data = b_point_density_node.ptr.data;
-
- /* 1 - render settings, 0 - vewport settings. */
- int settings = background ? 1 : 0;
+ point_density->image_manager = scene->image_manager;
/* TODO(sergey): Use more proper update flag. */
if(true) {
- b_point_density_node.cache_point_density(b_scene, settings);
+ point_density->add_image();
+ b_point_density_node.cache_point_density(b_depsgraph);
scene->image_manager->tag_reload_image(
point_density->filename.string(),
point_density->builtin_data,
@@ -900,9 +898,8 @@ static ShaderNode *add_node(Scene *scene,
BL::Object b_ob(b_point_density_node.object());
if(b_ob) {
float3 loc, size;
- point_density_texture_space(b_scene,
+ point_density_texture_space(b_depsgraph,
b_point_density_node,
- settings,
loc,
size);
point_density->tfm =
@@ -1015,8 +1012,8 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
static void add_nodes(Scene *scene,
BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
- const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree,
const ProxyMap &proxy_input_map,
@@ -1031,23 +1028,7 @@ static void add_nodes(Scene *scene,
BL::Node::outputs_iterator b_output;
/* find the node to use for output if there are multiple */
- bool found_active_output = false;
- BL::ShaderNode output_node(PointerRNA_NULL);
-
- for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(is_output_node(*b_node)) {
- BL::ShaderNodeOutputMaterial b_output_node(*b_node);
-
- if(b_output_node.is_active_output()) {
- output_node = b_output_node;
- found_active_output = true;
- break;
- }
- else if(!output_node.ptr.data && !found_active_output) {
- output_node = b_output_node;
- }
- }
- }
+ BL::ShaderNode output_node = b_ntree.get_output_node(BL::ShaderNodeOutputMaterial::target_CYCLES);
/* add nodes */
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
@@ -1117,8 +1098,8 @@ static void add_nodes(Scene *scene,
add_nodes(scene,
b_engine,
b_data,
+ b_depsgraph,
b_scene,
- background,
graph,
b_group_ntree,
group_proxy_input_map,
@@ -1156,18 +1137,16 @@ static void add_nodes(Scene *scene,
else {
ShaderNode *node = NULL;
- if(is_output_node(*b_node)) {
- if(b_node->ptr.data == output_node.ptr.data) {
- node = graph->output();
- }
+ if(b_node->ptr.data == output_node.ptr.data) {
+ node = graph->output();
}
else {
BL::ShaderNode b_shader_node(*b_node);
node = add_node(scene,
b_engine,
b_data,
+ b_depsgraph,
b_scene,
- background,
graph,
b_ntree,
b_shader_node);
@@ -1229,8 +1208,8 @@ static void add_nodes(Scene *scene,
static void add_nodes(Scene *scene,
BL::RenderEngine& b_engine,
BL::BlendData& b_data,
+ BL::Depsgraph& b_depsgraph,
BL::Scene& b_scene,
- const bool background,
ShaderGraph *graph,
BL::ShaderNodeTree& b_ntree)
{
@@ -1238,8 +1217,8 @@ static void add_nodes(Scene *scene,
add_nodes(scene,
b_engine,
b_data,
+ b_depsgraph,
b_scene,
- background,
graph,
b_ntree,
empty_proxy_map,
@@ -1248,35 +1227,39 @@ static void add_nodes(Scene *scene,
/* Sync Materials */
-void BlenderSync::sync_materials(bool update_all)
+void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
{
shader_map.set_default(scene->default_surface);
- /* material loop */
- BL::BlendData::materials_iterator b_mat;
-
TaskPool pool;
set<Shader*> updated_shaders;
- for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
+ BL::Depsgraph::ids_iterator b_id;
+ for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Material)) {
+ continue;
+ }
+
+ BL::Material b_mat(*b_id);
Shader *shader;
/* test if we need to sync */
- if(shader_map.sync(&shader, *b_mat) || update_all) {
+ if(shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
ShaderGraph *graph = new ShaderGraph();
- shader->name = b_mat->name().c_str();
- shader->pass_id = b_mat->pass_index();
+ shader->name = b_mat.name().c_str();
+ shader->pass_id = b_mat.pass_index();
+ shader->need_sync_object = false;
/* create nodes */
- if(b_mat->use_nodes() && b_mat->node_tree()) {
- BL::ShaderNodeTree b_ntree(b_mat->node_tree());
+ if(b_mat.use_nodes() && b_mat.node_tree()) {
+ BL::ShaderNodeTree b_ntree(b_mat.node_tree());
- add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
- diffuse->color = get_float3(b_mat->diffuse_color());
+ diffuse->color = get_float3(b_mat.diffuse_color());
graph->add(diffuse);
ShaderNode *out = graph->output();
@@ -1284,7 +1267,7 @@ void BlenderSync::sync_materials(bool update_all)
}
/* settings */
- PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
+ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
shader->use_mis = get_boolean(cmat, "sample_as_light");
shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
@@ -1328,7 +1311,7 @@ void BlenderSync::sync_materials(bool update_all)
/* Sync World */
-void BlenderSync::sync_world(bool update_all)
+void BlenderSync::sync_world(BL::Depsgraph& b_depsgraph, bool update_all)
{
Background *background = scene->background;
Background prevbackground = *background;
@@ -1343,7 +1326,7 @@ void BlenderSync::sync_world(bool update_all)
if(b_world && b_world.use_nodes() && b_world.node_tree()) {
BL::ShaderNodeTree b_ntree(b_world.node_tree());
- add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
/* volume */
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
@@ -1353,7 +1336,7 @@ void BlenderSync::sync_world(bool update_all)
}
else if(b_world) {
BackgroundNode *background = new BackgroundNode();
- background->color = get_float3(b_world.horizon_color());
+ background->color = get_float3(b_world.color());
graph->add(background);
ShaderNode *out = graph->output();
@@ -1411,49 +1394,52 @@ void BlenderSync::sync_world(bool update_all)
background->transparent_roughness_threshold = 0.0f;
}
- background->use_shader = render_layer.use_background_shader;
- background->use_ao = background->use_ao && render_layer.use_background_ao;
+ background->use_shader = view_layer.use_background_shader;
+ background->use_ao = background->use_ao && view_layer.use_background_ao;
if(background->modified(prevbackground))
background->tag_update(scene);
}
-/* Sync Lamps */
+/* Sync Lights */
-void BlenderSync::sync_lamps(bool update_all)
+void BlenderSync::sync_lights(BL::Depsgraph& b_depsgraph, bool update_all)
{
shader_map.set_default(scene->default_light);
- /* lamp loop */
- BL::BlendData::lamps_iterator b_lamp;
+ BL::Depsgraph::ids_iterator b_id;
+ for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+ if (!b_id->is_a(&RNA_Light)) {
+ continue;
+ }
- for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
+ BL::Light b_light(*b_id);
Shader *shader;
/* test if we need to sync */
- if(shader_map.sync(&shader, *b_lamp) || update_all) {
+ if(shader_map.sync(&shader, b_light) || update_all) {
ShaderGraph *graph = new ShaderGraph();
/* create nodes */
- if(b_lamp->use_nodes() && b_lamp->node_tree()) {
- shader->name = b_lamp->name().c_str();
+ if(b_light.use_nodes() && b_light.node_tree()) {
+ shader->name = b_light.name().c_str();
- BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
+ BL::ShaderNodeTree b_ntree(b_light.node_tree());
- add_nodes(scene, b_engine, b_data, b_scene, !preview, graph, b_ntree);
+ add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
}
else {
float strength = 1.0f;
- if(b_lamp->type() == BL::Lamp::type_POINT ||
- b_lamp->type() == BL::Lamp::type_SPOT ||
- b_lamp->type() == BL::Lamp::type_AREA)
+ if(b_light.type() == BL::Light::type_POINT ||
+ b_light.type() == BL::Light::type_SPOT ||
+ b_light.type() == BL::Light::type_AREA)
{
strength = 100.0f;
}
EmissionNode *emission = new EmissionNode();
- emission->color = get_float3(b_lamp->color());
+ emission->color = get_float3(b_light.color());
emission->strength = strength;
graph->add(emission);
@@ -1467,7 +1453,7 @@ void BlenderSync::sync_lamps(bool update_all)
}
}
-void BlenderSync::sync_shaders()
+void BlenderSync::sync_shaders(BL::Depsgraph& b_depsgraph)
{
/* for auto refresh images */
bool auto_refresh_update = false;
@@ -1480,9 +1466,9 @@ void BlenderSync::sync_shaders()
shader_map.pre_sync();
- sync_world(auto_refresh_update);
- sync_lamps(auto_refresh_update);
- sync_materials(auto_refresh_update);
+ sync_world(b_depsgraph, auto_refresh_update);
+ sync_lights(b_depsgraph, auto_refresh_update);
+ sync_materials(b_depsgraph, auto_refresh_update);
/* false = don't delete unused shaders, not supported */
shader_map.post_sync(false);
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 832847c179f..33c45de8d70 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -78,31 +78,12 @@ BlenderSync::~BlenderSync()
/* Sync */
-bool BlenderSync::sync_recalc()
+void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
{
- /* sync recalc flags from blender to cycles. actual update is done separate,
- * so we can do it later on if doing it immediate is not suitable */
-
- BL::BlendData::materials_iterator b_mat;
- bool has_updated_objects = b_data.objects.is_updated();
- for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
- if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) {
- shader_map.set_recalc(*b_mat);
- }
- else {
- Shader *shader = shader_map.find(*b_mat);
- if(has_updated_objects && shader != NULL && shader->has_object_dependency) {
- shader_map.set_recalc(*b_mat);
- }
- }
- }
-
- BL::BlendData::lamps_iterator b_lamp;
-
- for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp)
- if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated()))
- shader_map.set_recalc(*b_lamp);
+ /* Sync recalc flags from blender to cycles. Actual update is done separate,
+ * so we can do it later on if doing it immediate is not suitable. */
+ bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
bool dicing_prop_changed = false;
if(experimental) {
@@ -124,83 +105,92 @@ bool BlenderSync::sync_recalc()
}
}
- BL::BlendData::objects_iterator b_ob;
+ /* Iterate over all IDs in this depsgraph. */
+ BL::Depsgraph::updates_iterator b_update;
+ for(b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
+ BL::ID b_id(b_update->id());
- for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
- if(b_ob->is_updated()) {
- object_map.set_recalc(*b_ob);
- light_map.set_recalc(*b_ob);
+ /* Material */
+ if (b_id.is_a(&RNA_Material)) {
+ BL::Material b_mat(b_id);
+ shader_map.set_recalc(b_mat);
}
+ /* Light */
+ else if (b_id.is_a(&RNA_Light)) {
+ BL::Light b_light(b_id);
+ shader_map.set_recalc(b_light);
+ }
+ /* Object */
+ else if (b_id.is_a(&RNA_Object)) {
+ BL::Object b_ob(b_id);
+ const bool updated_geometry = !b_update->is_dirty_geometry();
+
+ if (!b_update->is_dirty_transform()) {
+ object_map.set_recalc(b_ob);
+ light_map.set_recalc(b_ob);
+ }
+
+ if(object_is_mesh(b_ob)) {
+ if(updated_geometry ||
+ (dicing_prop_changed && object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
+ {
+ BL::ID key = BKE_object_is_modified(b_ob)? b_ob: b_ob.data();
+ mesh_map.set_recalc(key);
+ }
+ }
+ else if(object_is_light(b_ob)) {
+ if(updated_geometry) {
+ light_map.set_recalc(b_ob);
+ }
+ }
- if(object_is_mesh(*b_ob)) {
- if(b_ob->is_updated_data() || b_ob->data().is_updated() ||
- (dicing_prop_changed && object_subdivision_type(*b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
- {
- BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
- mesh_map.set_recalc(key);
+ if(updated_geometry) {
+ BL::Object::particle_systems_iterator b_psys;
+ for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
+ particle_system_map.set_recalc(b_ob);
}
}
- else if(object_is_light(*b_ob)) {
- if(b_ob->is_updated_data() || b_ob->data().is_updated())
- light_map.set_recalc(*b_ob);
+ /* Mesh */
+ else if (b_id.is_a(&RNA_Mesh)) {
+ BL::Mesh b_mesh(b_id);
+ mesh_map.set_recalc(b_mesh);
}
-
- if(b_ob->is_updated_data()) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
- particle_system_map.set_recalc(*b_ob);
+ /* World */
+ else if (b_id.is_a(&RNA_World)) {
+ BL::World b_world(b_id);
+ if(world_map == b_world.ptr.data) {
+ world_recalc = true;
+ }
}
}
- BL::BlendData::meshes_iterator b_mesh;
-
- for(b_data.meshes.begin(b_mesh); b_mesh != b_data.meshes.end(); ++b_mesh) {
- if(b_mesh->is_updated()) {
- mesh_map.set_recalc(*b_mesh);
+ /* Updates shader with object dependency if objects changed. */
+ if (has_updated_objects) {
+ if(scene->default_background->has_object_dependency) {
+ world_recalc = true;
}
- }
-
- BL::BlendData::worlds_iterator b_world;
- for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) {
- if(world_map == b_world->ptr.data) {
- if(b_world->is_updated() ||
- (b_world->node_tree() && b_world->node_tree().is_updated()))
- {
- world_recalc = true;
- }
- else if(b_world->node_tree() && b_world->use_nodes()) {
- Shader *shader = scene->default_background;
- if(has_updated_objects && shader->has_object_dependency) {
- world_recalc = true;
- }
+ foreach(Shader *shader, scene->shaders) {
+ if (shader->has_object_dependency) {
+ shader->need_sync_object = true;
}
}
}
-
- bool recalc =
- shader_map.has_recalc() ||
- object_map.has_recalc() ||
- light_map.has_recalc() ||
- mesh_map.has_recalc() ||
- particle_system_map.has_recalc() ||
- BlendDataObjects_is_updated_get(&b_data.ptr) ||
- world_recalc;
-
- return recalc;
}
void BlenderSync::sync_data(BL::RenderSettings& b_render,
+ BL::Depsgraph& b_depsgraph,
BL::SpaceView3D& b_v3d,
BL::Object& b_override,
int width, int height,
- void **python_thread_state,
- const char *layer)
+ void **python_thread_state)
{
- sync_render_layers(b_v3d, layer);
+ BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
+
+ sync_view_layer(b_v3d, b_view_layer);
sync_integrator();
sync_film();
- sync_shaders();
+ sync_shaders(b_depsgraph);
sync_images();
sync_curve_settings();
@@ -210,14 +200,17 @@ void BlenderSync::sync_data(BL::RenderSettings& b_render,
scene->need_motion() == Scene::MOTION_NONE ||
scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
{
- sync_objects();
+ sync_objects(b_depsgraph);
}
sync_motion(b_render,
+ b_depsgraph,
b_override,
width, height,
python_thread_state);
mesh_synced.clear();
+
+ free_data_after_sync(b_depsgraph);
}
/* Integrator */
@@ -371,75 +364,14 @@ void BlenderSync::sync_film()
/* Render Layer */
-void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer)
+void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer)
{
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
- string layername;
-
- /* 3d view */
- if(b_v3d) {
- if(RNA_boolean_get(&cscene, "preview_active_layer")) {
- BL::RenderLayers layers(b_scene.render().ptr);
- layername = layers.active().name();
- layer = layername.c_str();
- }
- else {
- render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view());
- render_layer.layer = render_layer.scene_layer;
- render_layer.exclude_layer = 0;
- render_layer.holdout_layer = 0;
- render_layer.material_override = PointerRNA_NULL;
- render_layer.use_background_shader = true;
- render_layer.use_background_ao = true;
- render_layer.use_hair = true;
- render_layer.use_surfaces = true;
- render_layer.use_viewport_visibility = true;
- render_layer.samples = 0;
- render_layer.bound_samples = false;
- return;
- }
- }
-
/* render layer */
- BL::RenderSettings r = b_scene.render();
- BL::RenderSettings::layers_iterator b_rlay;
- int use_layer_samples = get_enum(cscene, "use_layer_samples");
- bool first_layer = true;
- uint layer_override = get_layer(b_engine.layer_override());
- uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
-
- for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) {
- if((!layer && first_layer) || (layer && b_rlay->name() == layer)) {
- render_layer.name = b_rlay->name();
-
- render_layer.holdout_layer = get_layer(b_rlay->layers_zmask());
- render_layer.exclude_layer = get_layer(b_rlay->layers_exclude());
-
- render_layer.scene_layer = scene_layers & ~render_layer.exclude_layer;
- render_layer.scene_layer |= render_layer.exclude_layer & render_layer.holdout_layer;
-
- render_layer.layer = get_layer(b_rlay->layers());
- render_layer.layer |= render_layer.holdout_layer;
-
- render_layer.material_override = b_rlay->material_override();
- render_layer.use_background_shader = b_rlay->use_sky();
- render_layer.use_background_ao = b_rlay->use_ao();
- render_layer.use_surfaces = b_rlay->use_solid();
- render_layer.use_hair = b_rlay->use_strand();
- render_layer.use_viewport_visibility = false;
-
- render_layer.bound_samples = (use_layer_samples == 1);
- if(use_layer_samples != 2) {
- int samples = b_rlay->samples();
- if(get_boolean(cscene, "use_square_samples"))
- render_layer.samples = samples * samples;
- else
- render_layer.samples = samples;
- }
- }
-
- first_layer = false;
- }
+ view_layer.name = b_view_layer.name();
+ view_layer.use_background_shader = b_view_layer.use_sky();
+ view_layer.use_background_ao = b_view_layer.use_ao();
+ view_layer.use_surfaces = b_view_layer.use_solid();
+ view_layer.use_hair = b_view_layer.use_strand();
}
/* Images */
@@ -555,7 +487,7 @@ int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass)
}
vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
- BL::SceneRenderLayer& b_srlay,
+ BL::ViewLayer& b_view_layer,
const SessionParams &session_params)
{
vector<Pass> passes;
@@ -578,7 +510,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
Pass::add(pass_type, passes);
}
- PointerRNA crp = RNA_pointer_get(&b_srlay.ptr, "cycles");
+ PointerRNA crp = RNA_pointer_get(&b_view_layer.ptr, "cycles");
bool use_denoising = get_boolean(crp, "use_denoising");
bool store_denoising_passes = get_boolean(crp, "denoising_store_passes");
scene->film->denoising_flags = 0;
@@ -593,52 +525,52 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
MAP_OPTION("denoising_subsurface_direct", DENOISING_CLEAN_SUBSURFACE_DIR);
MAP_OPTION("denoising_subsurface_indirect", DENOISING_CLEAN_SUBSURFACE_IND);
#undef MAP_OPTION
- b_engine.add_pass("Noisy Image", 4, "RGBA", b_srlay.name().c_str());
+ b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
}
if(store_denoising_passes) {
- b_engine.add_pass("Denoising Normal", 3, "XYZ", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Normal Variance", 3, "XYZ", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Albedo", 3, "RGB", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Albedo Variance", 3, "RGB", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Depth", 1, "Z", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Depth Variance", 1, "Z", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Shadow A", 3, "XYV", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Shadow B", 3, "XYV", b_srlay.name().c_str());
- b_engine.add_pass("Denoising Image Variance", 3, "RGB", b_srlay.name().c_str());
+ b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Normal Variance", 3, "XYZ", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Albedo Variance", 3, "RGB", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Depth Variance", 1, "Z", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Shadow A", 3, "XYV", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Shadow B", 3, "XYV", b_view_layer.name().c_str());
+ b_engine.add_pass("Denoising Image Variance", 3, "RGB", b_view_layer.name().c_str());
if(scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) {
- b_engine.add_pass("Denoising Clean", 3, "RGB", b_srlay.name().c_str());
+ b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
}
}
#ifdef __KERNEL_DEBUG__
if(get_boolean(crp, "pass_debug_bvh_traversed_nodes")) {
- b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_srlay.name().c_str());
+ b_engine.add_pass("Debug BVH Traversed Nodes", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_BVH_TRAVERSED_NODES, passes);
}
if(get_boolean(crp, "pass_debug_bvh_traversed_instances")) {
- b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_srlay.name().c_str());
+ b_engine.add_pass("Debug BVH Traversed Instances", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_BVH_TRAVERSED_INSTANCES, passes);
}
if(get_boolean(crp, "pass_debug_bvh_intersections")) {
- b_engine.add_pass("Debug BVH Intersections", 1, "X", b_srlay.name().c_str());
+ b_engine.add_pass("Debug BVH Intersections", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_BVH_INTERSECTIONS, passes);
}
if(get_boolean(crp, "pass_debug_ray_bounces")) {
- b_engine.add_pass("Debug Ray Bounces", 1, "X", b_srlay.name().c_str());
+ b_engine.add_pass("Debug Ray Bounces", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_RAY_BOUNCES, passes);
}
#endif
if(get_boolean(crp, "pass_debug_render_time")) {
- b_engine.add_pass("Debug Render Time", 1, "X", b_srlay.name().c_str());
+ b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
Pass::add(PASS_RENDER_TIME, passes);
}
if(get_boolean(crp, "use_pass_volume_direct")) {
- b_engine.add_pass("VolumeDir", 3, "RGB", b_srlay.name().c_str());
+ b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_DIRECT, passes);
}
if(get_boolean(crp, "use_pass_volume_indirect")) {
- b_engine.add_pass("VolumeInd", 3, "RGB", b_srlay.name().c_str());
+ b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
Pass::add(PASS_VOLUME_INDIRECT, passes);
}
@@ -650,7 +582,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
if(get_boolean(crp, "use_pass_crypto_object")) {
for(int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_srlay.name().c_str());
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
}
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_OBJECT);
@@ -658,7 +590,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
if(get_boolean(crp, "use_pass_crypto_material")) {
for(int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_srlay.name().c_str());
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
}
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_MATERIAL);
@@ -666,7 +598,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
if(get_boolean(crp, "use_pass_crypto_asset")) {
for(int i = 0; i < crypto_depth; ++i) {
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
- b_engine.add_pass(passname.c_str(), 4, "RGBA", b_srlay.name().c_str());
+ b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
}
scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | CRYPT_ASSET);
@@ -678,6 +610,30 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
return passes;
}
+void BlenderSync::free_data_after_sync(BL::Depsgraph& b_depsgraph)
+{
+ /* When viewport display is not needed during render we can force some
+ * caches to be releases from blender side in order to reduce peak memory
+ * footprint during synchronization process.
+ */
+ const bool is_interface_locked = b_engine.render() &&
+ b_engine.render().use_lock_interface();
+ const bool can_free_caches = BlenderSession::headless || is_interface_locked;
+ if (!can_free_caches) {
+ return;
+ }
+ /* TODO(sergey): We can actually remove the whole dependency graph,
+ * but that will need some API support first.
+ */
+ BL::Depsgraph::objects_iterator b_ob;
+ for(b_depsgraph.objects.begin(b_ob);
+ b_ob != b_depsgraph.objects.end();
+ ++b_ob)
+ {
+ b_ob->cache_release();
+ }
+}
+
/* Scene Parameters */
SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
@@ -907,13 +863,14 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
/* progressive refine */
- params.progressive_refine = get_boolean(cscene, "use_progressive_refine") &&
+ params.progressive_refine = (b_engine.is_preview() ||
+ get_boolean(cscene, "use_progressive_refine")) &&
!b_r.use_save_buffers();
if(params.progressive_refine) {
- BL::RenderSettings::layers_iterator b_rlay;
- for(b_r.layers.begin(b_rlay); b_rlay != b_r.layers.end(); ++b_rlay) {
- PointerRNA crl = RNA_pointer_get(&b_rlay->ptr, "cycles");
+ BL::Scene::view_layers_iterator b_view_layer;
+ for(b_scene.view_layers.begin(b_view_layer); b_view_layer != b_scene.view_layers.end(); ++b_view_layer) {
+ PointerRNA crl = RNA_pointer_get(&b_view_layer->ptr, "cycles");
if(get_boolean(crl, "use_denoising")) {
params.progressive_refine = false;
}
@@ -941,17 +898,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.shadingsystem = SHADINGSYSTEM_OSL;
/* color managagement */
-#ifdef GLEW_MX
- /* When using GLEW MX we need to check whether we've got an OpenGL
- * context for current window. This is because command line rendering
- * doesn't have OpenGL context actually.
- */
- if(glewGetContext() != NULL)
-#endif
- {
- params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
- b_engine.support_display_space_shader(b_scene);
- }
+ params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
if(b_engine.is_preview()) {
/* For preview rendering we're using same timeout as
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index eb84bedb118..d2b362be24d 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -43,6 +43,7 @@ class Mesh;
class Object;
class ParticleSystem;
class Scene;
+class ViewLayer;
class Shader;
class ShaderGraph;
class ShaderNode;
@@ -58,16 +59,16 @@ public:
~BlenderSync();
/* sync */
- bool sync_recalc();
+ void sync_recalc(BL::Depsgraph& b_depsgraph);
void sync_data(BL::RenderSettings& b_render,
+ BL::Depsgraph& b_depsgraph,
BL::SpaceView3D& b_v3d,
BL::Object& b_override,
int width, int height,
- void **python_thread_state,
- const char *layer = 0);
- void sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer);
- vector<Pass> sync_render_passes(BL::RenderLayer& b_rlay,
- BL::SceneRenderLayer& b_srlay,
+ void **python_thread_state);
+ void sync_view_layer(BL::SpaceView3D& b_v3d, BL::ViewLayer& b_view_layer);
+ vector<Pass> sync_render_passes(BL::RenderLayer& b_render_layer,
+ BL::ViewLayer& b_view_layer,
const SessionParams &session_params);
void sync_integrator();
void sync_camera(BL::RenderSettings& b_render,
@@ -77,8 +78,6 @@ public:
void sync_view(BL::SpaceView3D& b_v3d,
BL::RegionView3D& b_rv3d,
int width, int height);
- inline int get_layer_samples() { return render_layer.samples; }
- inline int get_layer_bound_samples() { return render_layer.bound_samples; }
/* get parameters */
static SceneParams get_scene_params(BL::Scene& b_scene,
@@ -99,31 +98,34 @@ public:
private:
/* sync */
- void sync_lamps(bool update_all);
- void sync_materials(bool update_all);
- void sync_objects(float motion_time = 0.0f);
+ void sync_lights(BL::Depsgraph& b_depsgraph, bool update_all);
+ void sync_materials(BL::Depsgraph& b_depsgraph, bool update_all);
+ void sync_objects(BL::Depsgraph& b_depsgraph, float motion_time = 0.0f);
void sync_motion(BL::RenderSettings& b_render,
+ BL::Depsgraph& b_depsgraph,
BL::Object& b_override,
int width, int height,
void **python_thread_state);
void sync_film();
void sync_view();
- void sync_world(bool update_all);
- void sync_shaders();
+ void sync_world(BL::Depsgraph& b_depsgraph, bool update_all);
+ void sync_shaders(BL::Depsgraph& b_depsgraph);
void sync_curve_settings();
void sync_nodes(Shader *shader, BL::ShaderNodeTree& b_ntree);
- Mesh *sync_mesh(BL::Object& b_ob, bool object_updated, bool hide_tris);
+ Mesh *sync_mesh(BL::Depsgraph& b_depsgrpah,
+ BL::Object& b_ob,
+ BL::Object& b_ob_instance,
+ bool object_updated,
+ bool hide_tris);
void sync_curves(Mesh *mesh,
BL::Mesh& b_mesh,
BL::Object& b_ob,
bool motion,
int motion_step = 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,
+ Object *sync_object(BL::Depsgraph& b_depsgraph,
+ BL::ViewLayer& b_view_layer,
+ BL::DepsgraphObjectInstance& b_instance,
float motion_time,
bool hide_tris,
BlenderObjectCulling& culling,
@@ -131,11 +133,13 @@ private:
void sync_light(BL::Object& b_parent,
int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
BL::Object& b_ob,
- BL::DupliObject& b_dupli_ob,
+ BL::Object& b_ob_instance,
+ int random_id,
Transform& tfm,
bool *use_portal);
void sync_background_light(bool use_portal);
- void sync_mesh_motion(BL::Object& b_ob,
+ void sync_mesh_motion(BL::Depsgraph& b_depsgraph,
+ BL::Object& b_ob,
Object *object,
float motion_time);
void sync_camera_motion(BL::RenderSettings& b_render,
@@ -145,12 +149,15 @@ private:
/* particles */
bool sync_dupli_particle(BL::Object& b_ob,
- BL::DupliObject& b_dup,
+ BL::DepsgraphObjectInstance& b_instance,
Object *object);
/* Images. */
void sync_images();
+ /* Early data free. */
+ void free_data_after_sync(BL::Depsgraph& b_depsgraph);
+
/* util */
void find_shader(BL::ID& id, vector<Shader*>& used_shaders, Shader *default_shader);
bool BKE_object_is_modified(BL::Object& b_ob);
@@ -182,31 +189,19 @@ private:
struct RenderLayerInfo {
RenderLayerInfo()
- : scene_layer(0), layer(0),
- holdout_layer(0), exclude_layer(0),
- material_override(PointerRNA_NULL),
- use_background_shader(true),
+ : use_background_shader(true),
use_background_ao(true),
use_surfaces(true),
- use_hair(true),
- use_viewport_visibility(false),
- samples(0), bound_samples(false)
+ use_hair(true)
{}
string name;
- uint scene_layer;
- uint layer;
- uint holdout_layer;
- uint exclude_layer;
- BL::Material material_override;
+ uint view_layer;
bool use_background_shader;
bool use_background_ao;
bool use_surfaces;
bool use_hair;
- bool use_viewport_visibility;
- int samples;
- bool bound_samples;
- } render_layer;
+ } view_layer;
Progress &progress;
};
diff --git a/intern/cycles/blender/blender_texture.cpp b/intern/cycles/blender/blender_texture.cpp
index b2e27b76189..a0371a7eed8 100644
--- a/intern/cycles/blender/blender_texture.cpp
+++ b/intern/cycles/blender/blender_texture.cpp
@@ -34,9 +34,8 @@ void density_texture_space_invert(float3& loc,
} /* namespace */
-void point_density_texture_space(BL::Scene& b_scene,
+void point_density_texture_space(BL::Depsgraph& b_depsgraph,
BL::ShaderNodeTexPointDensity& b_point_density_node,
- int settings,
float3& loc,
float3& size)
{
@@ -47,8 +46,7 @@ void point_density_texture_space(BL::Scene& b_scene,
return;
}
float3 min, max;
- b_point_density_node.calc_point_density_minmax(b_scene,
- settings,
+ b_point_density_node.calc_point_density_minmax(b_depsgraph,
&min[0],
&max[0]);
loc = (min + max) * 0.5f;
diff --git a/intern/cycles/blender/blender_texture.h b/intern/cycles/blender/blender_texture.h
index 734231a85ec..b4e166c5cdd 100644
--- a/intern/cycles/blender/blender_texture.h
+++ b/intern/cycles/blender/blender_texture.h
@@ -22,9 +22,8 @@
CCL_NAMESPACE_BEGIN
-void point_density_texture_space(BL::Scene& b_scene,
+void point_density_texture_space(BL::Depsgraph& b_depsgraph,
BL::ShaderNodeTexPointDensity& b_point_density_node,
- const int settings,
float3& loc,
float3& size);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 09ae9bea313..02e3c292349 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -32,7 +32,7 @@
extern "C" {
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxlen, double time_seconds);
-void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
+void BKE_image_user_frame_calc(void *iuser, int cfra);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
@@ -45,15 +45,15 @@ void python_thread_state_restore(void **python_thread_state);
static inline BL::Mesh object_to_mesh(BL::BlendData& data,
BL::Object& object,
- BL::Scene& scene,
+ BL::Depsgraph& depsgraph,
bool apply_modifiers,
- bool render,
bool calc_undeformed,
Mesh::SubdivisionType subdivision_type)
{
bool subsurf_mod_show_render = false;
bool subsurf_mod_show_viewport = false;
+ /* TODO: make this work with copy-on-write, modifiers are already evaluated. */
if(subdivision_type != Mesh::SUBDIVISION_NONE) {
BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
@@ -64,7 +64,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
subsurf_mod.show_viewport(false);
}
- BL::Mesh me = data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, false, calc_undeformed);
+ BL::Mesh me = data.meshes.new_from_object(depsgraph, object, apply_modifiers, calc_undeformed);
if(subdivision_type != Mesh::SUBDIVISION_NONE) {
BL::Modifier subsurf_mod = object.modifiers[object.modifiers.length()-1];
@@ -83,7 +83,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData& data,
}
}
if(subdivision_type == Mesh::SUBDIVISION_NONE) {
- me.calc_tessface(true);
+ me.calc_loop_triangles();
}
}
return me;
@@ -220,14 +220,14 @@ static inline string image_user_file_path(BL::ImageUser& iuser,
int cfra)
{
char filepath[1024];
- BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
return string(filepath);
}
static inline int image_user_frame_number(BL::ImageUser& iuser, int cfra)
{
- BKE_image_user_frame_calc(iuser.ptr.data, cfra, 0);
+ BKE_image_user_frame_calc(iuser.ptr.data, cfra);
return iuser.frame_current();
}
@@ -313,7 +313,7 @@ static inline uint get_layer(const BL::Array<bool, 20>& array)
static inline uint get_layer(const BL::Array<bool, 20>& array,
const BL::Array<bool, 8>& local_array,
bool is_light = false,
- uint scene_layers = (1 << 20) - 1)
+ uint view_layers = (1 << 20) - 1)
{
uint layer = 0;
@@ -325,7 +325,7 @@ static inline uint get_layer(const BL::Array<bool, 20>& array,
/* Consider light is visible if it was visible without layer
* override, which matches behavior of Blender Internal.
*/
- if(layer & scene_layers) {
+ if(layer & view_layers) {
for(uint i = 0; i < 8; i++)
layer |= (1 << (20+i));
}
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 7e20bb449c3..428cd4158bc 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -78,132 +78,275 @@ std::ostream& operator <<(std::ostream &os,
Device::~Device()
{
- if(!background && vertex_buffer != 0) {
- glDeleteBuffers(1, &vertex_buffer);
+ if(!background) {
+ if(vertex_buffer != 0) {
+ glDeleteBuffers(1, &vertex_buffer);
+ }
+ if(fallback_shader_program != 0) {
+ glDeleteProgram(fallback_shader_program);
+ }
}
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params)
+/* TODO move shaders to standalone .glsl file. */
+const char *FALLBACK_VERTEX_SHADER =
+"#version 330\n"
+"uniform vec2 fullscreen;\n"
+"in vec2 texCoord;\n"
+"in vec2 pos;\n"
+"out vec2 texCoord_interp;\n"
+"\n"
+"vec2 normalize_coordinates()\n"
+"{\n"
+" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
+"}\n"
+"\n"
+"void main()\n"
+"{\n"
+" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
+" texCoord_interp = texCoord;\n"
+"}\n\0";
+
+const char *FALLBACK_FRAGMENT_SHADER =
+"#version 330\n"
+"uniform sampler2D image_texture;\n"
+"in vec2 texCoord_interp;\n"
+"out vec4 fragColor;\n"
+"\n"
+"void main()\n"
+"{\n"
+" fragColor = texture(image_texture, texCoord_interp);\n"
+"}\n\0";
+
+static void shader_print_errors(const char *task, const char *log, const char *code)
{
- assert(rgba.type == MEM_PIXELS);
+ LOG(ERROR) << "Shader: " << task << " error:";
+ LOG(ERROR) << "===== shader string ====";
- mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
+ stringstream stream(code);
+ string partial;
- if(transparent) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ int line = 1;
+ while(getline(stream, partial, '\n')) {
+ if(line < 10) {
+ LOG(ERROR) << " " << line << " " << partial;
+ }
+ else {
+ LOG(ERROR) << line << " " << partial;
+ }
+ line++;
}
+ LOG(ERROR) << log;
+}
- glColor3f(1.0f, 1.0f, 1.0f);
+static int bind_fallback_shader(void)
+{
+ GLint status;
+ GLchar log[5000];
+ GLsizei length = 0;
+ GLuint program = 0;
- if(rgba.data_type == TYPE_HALF) {
- /* for multi devices, this assumes the inefficient method that we allocate
- * all pixels on the device even though we only render to a subset */
- GLhalf *host_pointer = (GLhalf*)rgba.host_pointer;
- float vbuffer[16], *basep;
- float *vp = NULL;
-
- host_pointer += 4*y*w;
-
- /* draw half float texture, GLSL shader for display transform assumed to be bound */
- GLuint texid;
- glGenTextures(1, &texid);
- glBindTexture(GL_TEXTURE_2D, texid);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGBA, GL_HALF_FLOAT, host_pointer);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glEnable(GL_TEXTURE_2D);
-
- if(draw_params.bind_display_space_shader_cb) {
- draw_params.bind_display_space_shader_cb();
+ struct Shader {
+ const char *source;
+ GLenum type;
+ } shaders[2] = {
+ {FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
+ {FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}
+ };
+
+ program = glCreateProgram();
+
+ for(int i = 0; i < 2; i++) {
+ GLuint shader = glCreateShader(shaders[i].type);
+
+ string source_str = shaders[i].source;
+ const char *c_str = source_str.c_str();
+
+ glShaderSource(shader, 1, &c_str, NULL);
+ glCompileShader(shader);
+
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+
+ if(!status) {
+ glGetShaderInfoLog(shader, sizeof(log), &length, log);
+ shader_print_errors("compile", log, c_str);
+ return 0;
}
- if(GLEW_VERSION_1_5) {
- if(!vertex_buffer)
- glGenBuffers(1, &vertex_buffer);
+ glAttachShader(program, shader);
+ }
+
+ /* Link output. */
+ glBindFragDataLocation(program, 0, "fragColor");
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
- /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
- glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+ /* Link and error check. */
+ glLinkProgram(program);
+
+ glGetProgramiv(program, GL_LINK_STATUS, &status);
+ if(!status) {
+ glGetShaderInfoLog(program, sizeof(log), &length, log);
+ shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
+ shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
+ return 0;
+ }
+
+ return program;
+}
+
+bool Device::bind_fallback_display_space_shader(const float width, const float height)
+{
+ if(fallback_status == FALLBACK_SHADER_STATUS_ERROR) {
+ return false;
+ }
- vp = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+ if(fallback_status == FALLBACK_SHADER_STATUS_NONE) {
+ fallback_shader_program = bind_fallback_shader();
+ fallback_status = FALLBACK_SHADER_STATUS_ERROR;
- basep = NULL;
+ if (fallback_shader_program == 0) {
+ return false;
}
- else {
- basep = vbuffer;
- vp = vbuffer;
+
+ glUseProgram(fallback_shader_program);
+ image_texture_location = glGetUniformLocation(fallback_shader_program, "image_texture");
+ if(image_texture_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'image_texture' uniform.";
+ return false;
}
- if(vp) {
- /* texture coordinate - vertex pair */
- vp[0] = 0.0f;
- vp[1] = 0.0f;
- vp[2] = dx;
- vp[3] = dy;
-
- vp[4] = 1.0f;
- vp[5] = 0.0f;
- vp[6] = (float)width + dx;
- vp[7] = dy;
-
- vp[8] = 1.0f;
- vp[9] = 1.0f;
- vp[10] = (float)width + dx;
- vp[11] = (float)height + dy;
-
- vp[12] = 0.0f;
- vp[13] = 1.0f;
- vp[14] = dx;
- vp[15] = (float)height + dy;
-
- if(vertex_buffer)
- glUnmapBuffer(GL_ARRAY_BUFFER);
+ fullscreen_location = glGetUniformLocation(fallback_shader_program, "fullscreen");
+ if(fullscreen_location < 0) {
+ LOG(ERROR) << "Shader doesn't containt the 'fullscreen' uniform.";
+ return false;
}
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), basep);
- glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), ((char *)basep) + 2 * sizeof(float));
+ fallback_status = FALLBACK_SHADER_STATUS_SUCCESS;
+ }
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ /* Run this every time. */
+ glUseProgram(fallback_shader_program);
+ glUniform1i(image_texture_location, 0);
+ glUniform2f(fullscreen_location, width, height);
+ return true;
+}
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+void Device::draw_pixels(
+ device_memory& rgba, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params)
+{
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ assert(rgba.type == MEM_PIXELS);
+ mem_copy_from(rgba, y, w, h, rgba.memory_elements_size(1));
- if(vertex_buffer) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- }
+ GLuint texid;
+ glGenTextures(1, &texid);
+ glBindTexture(GL_TEXTURE_2D, texid);
- if(draw_params.unbind_display_space_shader_cb) {
- draw_params.unbind_display_space_shader_cb();
- }
+ if(rgba.data_type == TYPE_HALF) {
+ GLhalf *data_pointer = (GLhalf*)rgba.host_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, data_pointer);
+ }
+ else {
+ uint8_t *data_pointer = (uint8_t*)rgba.host_pointer;
+ data_pointer += 4 * y * w;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data_pointer);
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ if(transparent) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ }
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
- glDeleteTextures(1, &texid);
+ GLint shader_program;
+ if(use_fallback_shader) {
+ if (!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
}
else {
- /* fallback for old graphics cards that don't support GLSL, half float,
- * and non-power-of-two textures */
- glPixelZoom((float)width/(float)w, (float)height/(float)h);
- glRasterPos2f(dx, dy);
+ draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
+ }
+
+ if(!vertex_buffer) {
+ glGenBuffers(1, &vertex_buffer);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+ /* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
+ glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
+
+ float *vpointer = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
- uint8_t *pixels = (uint8_t*)rgba.host_pointer;
+ if(vpointer) {
+ /* texture coordinate - vertex pair */
+ vpointer[0] = 0.0f;
+ vpointer[1] = 0.0f;
+ vpointer[2] = dx;
+ vpointer[3] = dy;
- pixels += 4*y*w;
+ vpointer[4] = 1.0f;
+ vpointer[5] = 0.0f;
+ vpointer[6] = (float)width + dx;
+ vpointer[7] = dy;
- glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ vpointer[8] = 1.0f;
+ vpointer[9] = 1.0f;
+ vpointer[10] = (float)width + dx;
+ vpointer[11] = (float)height + dy;
- glRasterPos2f(0.0f, 0.0f);
- glPixelZoom(1.0f, 1.0f);
+ vpointer[12] = 0.0f;
+ vpointer[13] = 1.0f;
+ vpointer[14] = dx;
+ vpointer[15] = (float)height + dy;
+
+ if(vertex_buffer) {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+ }
+ }
+
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
+
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
+
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
+
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
+
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if(vertex_buffer) {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- if(transparent)
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
+ draw_params.unbind_display_space_shader_cb();
+ }
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &texid);
+
+ if(transparent) {
glDisable(GL_BLEND);
+ }
}
Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 54a3ae1fe9f..b09843e9f12 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -247,13 +247,26 @@ struct DeviceDrawParams {
class Device {
friend class device_sub_ptr;
protected:
- Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background), vertex_buffer(0), info(info_), stats(stats_) {}
+ enum {
+ FALLBACK_SHADER_STATUS_NONE = 0,
+ FALLBACK_SHADER_STATUS_ERROR,
+ FALLBACK_SHADER_STATUS_SUCCESS,
+ };
+
+ Device(DeviceInfo& info_, Stats &stats_, bool background) : background(background),
+ vertex_buffer(0),
+ fallback_status(FALLBACK_SHADER_STATUS_NONE), fallback_shader_program(0),
+ info(info_), stats(stats_) {}
bool background;
string error_msg;
/* used for real time display */
unsigned int vertex_buffer;
+ int fallback_status, fallback_shader_program;
+ int image_texture_location, fullscreen_location;
+
+ bool bind_fallback_display_space_shader(const float width, const float height);
virtual device_ptr mem_alloc_sub_ptr(device_memory& /*mem*/, int /*offset*/, int /*size*/)
{
@@ -305,9 +318,10 @@ public:
virtual void task_cancel() = 0;
/* opengl drawing */
- virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params);
+ virtual void draw_pixels(device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params);
#ifdef WITH_NETWORK
/* networking */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index f0e58f22ad4..1c2d35061cc 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1864,7 +1864,7 @@ public:
glGenTextures(1, &pmem.cuTexId);
glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
if(mem.data_type == TYPE_HALF)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, pmem.w, pmem.h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, pmem.w, pmem.h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, pmem.w, pmem.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -1924,12 +1924,16 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
+ void draw_pixels(
+ device_memory& mem, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh, bool transparent,
const DeviceDrawParams &draw_params)
{
assert(mem.type == MEM_PIXELS);
if(!background) {
+ const bool use_fallback_shader = (draw_params.bind_display_space_shader_cb == NULL);
PixelMem pmem = pixel_mem_map[mem.device_pointer];
float *vpointer;
@@ -1946,27 +1950,34 @@ public:
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pmem.cuPBO);
glBindTexture(GL_TEXTURE_2D, pmem.cuTexId);
- if(mem.data_type == TYPE_HALF)
+ if(mem.data_type == TYPE_HALF) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_HALF_FLOAT, (void*)offset);
- else
+ }
+ else {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, (void*)offset);
+ }
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
- glEnable(GL_TEXTURE_2D);
-
if(transparent) {
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
}
- glColor3f(1.0f, 1.0f, 1.0f);
-
- if(draw_params.bind_display_space_shader_cb) {
+ GLint shader_program;
+ if(use_fallback_shader) {
+ if(!bind_fallback_display_space_shader(dw, dh)) {
+ return;
+ }
+ shader_program = fallback_shader_program;
+ }
+ else {
draw_params.bind_display_space_shader_cb();
+ glGetIntegerv(GL_CURRENT_PROGRAM, &shader_program);
}
- if(!vertex_buffer)
+ if(!vertex_buffer) {
glGenBuffers(1, &vertex_buffer);
+ }
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
/* invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered */
@@ -1999,33 +2010,40 @@ public:
glUnmapBuffer(GL_ARRAY_BUFFER);
}
- glTexCoordPointer(2, GL_FLOAT, 4 * sizeof(float), 0);
- glVertexPointer(2, GL_FLOAT, 4 * sizeof(float), (char *)NULL + 2 * sizeof(float));
+ GLuint vertex_array_object;
+ GLuint position_attribute, texcoord_attribute;
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glGenVertexArrays(1, &vertex_array_object);
+ glBindVertexArray(vertex_array_object);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ texcoord_attribute = glGetAttribLocation(shader_program, "texCoord");
+ position_attribute = glGetAttribLocation(shader_program, "pos");
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
+ glEnableVertexAttribArray(texcoord_attribute);
+ glEnableVertexAttribArray(position_attribute);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
+ glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)(sizeof(float) * 2));
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- if(draw_params.unbind_display_space_shader_cb) {
+ if(use_fallback_shader) {
+ glUseProgram(0);
+ }
+ else {
draw_params.unbind_display_space_shader_cb();
}
- if(transparent)
+ if(transparent) {
glDisable(GL_BLEND);
+ }
glBindTexture(GL_TEXTURE_2D, 0);
- glDisable(GL_TEXTURE_2D);
return;
}
- Device::draw_pixels(mem, y, w, h, dx, dy, width, height, transparent, draw_params);
+ Device::draw_pixels(mem, y, w, h, width, height, dx, dy, dw, dh, transparent, draw_params);
}
void thread_run(DeviceTask *task)
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 490ee3951c9..67f0f880287 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -224,8 +224,11 @@ public:
sub.device->const_copy_to(name, host, size);
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int dx, int dy, int width, int height, bool transparent,
- const DeviceDrawParams &draw_params)
+ void draw_pixels(
+ device_memory& rgba, int y,
+ int w, int h, int width, int height,
+ int dx, int dy, int dw, int dh,
+ bool transparent, const DeviceDrawParams &draw_params)
{
device_ptr key = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -239,7 +242,7 @@ public:
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[key];
- sub.device->draw_pixels(rgba, sy, w, sh, dx, sdy, width, sheight, transparent, draw_params);
+ sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, dx, sdy, dw, dh, transparent, draw_params);
i++;
}
diff --git a/intern/cycles/kernel/kernel_id_passes.h b/intern/cycles/kernel/kernel_id_passes.h
index 486c61d2ae5..8d092374d8b 100644
--- a/intern/cycles/kernel/kernel_id_passes.h
+++ b/intern/cycles/kernel/kernel_id_passes.h
@@ -22,7 +22,7 @@ ccl_device_inline void kernel_write_id_slots(ccl_global float *buffer, int num_s
if(weight == 0.0f) {
return;
}
-
+
for(int slot = 0; slot < num_slots; slot++) {
ccl_global float2 *id_buffer = (ccl_global float2*)buffer;
#ifdef __ATOMIC_PASS_WRITE__
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 2a300d3419e..262d7df1364 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -44,7 +44,7 @@ typedef struct LightSample {
*
* Note: light_p is modified when sample_coord is true.
*/
-ccl_device_inline float area_light_sample(float3 P,
+ccl_device_inline float rect_light_sample(float3 P,
float3 *light_p,
float3 axisu, float3 axisv,
float randu, float randv,
@@ -118,6 +118,60 @@ ccl_device_inline float area_light_sample(float3 P,
return 0.0f;
}
+ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float randv)
+{
+ to_unit_disk(&randu, &randv);
+ return ru*randu + rv*randv;
+}
+
+ccl_device float3 disk_light_sample(float3 v, float randu, float randv)
+{
+ float3 ru, rv;
+
+ make_orthonormals(v, &ru, &rv);
+
+ return ellipse_sample(ru, rv, randu, randv);
+}
+
+ccl_device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
+{
+ return normalize(D + disk_light_sample(D, randu, randv)*radius);
+}
+
+ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
+{
+ return disk_light_sample(normalize(P - center), randu, randv)*radius;
+}
+
+ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot_smooth, LightSample *ls)
+{
+ float3 I = ls->Ng;
+
+ float attenuation = dot(dir, I);
+
+ if(attenuation <= spot_angle) {
+ attenuation = 0.0f;
+ }
+ else {
+ float t = attenuation - spot_angle;
+
+ if(t < spot_smooth && spot_smooth != 0.0f)
+ attenuation *= smoothstepf(t/spot_smooth);
+ }
+
+ return attenuation;
+}
+
+ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
+{
+ float cos_pi = dot(Ng, I);
+
+ if(cos_pi <= 0.0f)
+ return 0.0f;
+
+ return t*t/cos_pi;
+}
+
/* Background Light */
#ifdef __BACKGROUND_MIS__
@@ -291,11 +345,19 @@ ccl_device_inline float background_portal_pdf(KernelGlobals *kg,
const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
+ bool is_round = (klight->area.invarea < 0.0f);
- if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL))
+ if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL, is_round))
continue;
- portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
+ if(is_round) {
+ float t;
+ float3 D = normalize_len(lightpos - P, &t);
+ portal_pdf += fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
+ }
+ else {
+ portal_pdf += rect_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false);
+ }
}
if(ignore_portal >= 0) {
@@ -345,15 +407,26 @@ ccl_device float3 background_portal_sample(KernelGlobals *kg,
const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, portal);
float3 axisu = make_float3(klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
float3 axisv = make_float3(klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
-
- *pdf = area_light_sample(P, &lightpos,
- axisu, axisv,
- randu, randv,
- true);
+ bool is_round = (klight->area.invarea < 0.0f);
+
+ float3 D;
+ if(is_round) {
+ lightpos += ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv);
+ float t;
+ D = normalize_len(lightpos - P, &t);
+ *pdf = fabsf(klight->area.invarea) * lamp_light_pdf(kg, dir, -D, t);
+ }
+ else {
+ *pdf = rect_light_sample(P, &lightpos,
+ axisu, axisv,
+ randu, randv,
+ true);
+ D = normalize(lightpos - P);
+ }
*pdf /= num_possible;
*sampled_portal = p;
- return normalize(lightpos - P);
+ return D;
}
portal--;
@@ -454,55 +527,6 @@ ccl_device float background_light_pdf(KernelGlobals *kg, float3 P, float3 direct
/* Regular Light */
-ccl_device float3 disk_light_sample(float3 v, float randu, float randv)
-{
- float3 ru, rv;
-
- make_orthonormals(v, &ru, &rv);
- to_unit_disk(&randu, &randv);
-
- return ru*randu + rv*randv;
-}
-
-ccl_device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
-{
- return normalize(D + disk_light_sample(D, randu, randv)*radius);
-}
-
-ccl_device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
-{
- return disk_light_sample(normalize(P - center), randu, randv)*radius;
-}
-
-ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot_smooth, LightSample *ls)
-{
- float3 I = ls->Ng;
-
- float attenuation = dot(dir, I);
-
- if(attenuation <= spot_angle) {
- attenuation = 0.0f;
- }
- else {
- float t = attenuation - spot_angle;
-
- if(t < spot_smooth && spot_smooth != 0.0f)
- attenuation *= smoothstepf(t/spot_smooth);
- }
-
- return attenuation;
-}
-
-ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
-{
- float cos_pi = dot(Ng, I);
-
- if(cos_pi <= 0.0f)
- return 0.0f;
-
- return t*t/cos_pi;
-}
-
ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
int lamp,
float randu, float randv,
@@ -597,26 +621,39 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg,
float3 D = make_float3(klight->area.dir[0],
klight->area.dir[1],
klight->area.dir[2]);
+ float invarea = fabsf(klight->area.invarea);
+ bool is_round = (klight->area.invarea < 0.0f);
if(dot(ls->P - P, D) > 0.0f) {
return false;
}
- float3 inplane = ls->P;
- ls->pdf = area_light_sample(P, &ls->P,
- axisu, axisv,
- randu, randv,
- true);
+ float3 inplane;
+
+ if(is_round) {
+ inplane = ellipse_sample(axisu*0.5f, axisv*0.5f, randu, randv);
+ ls->P += inplane;
+ ls->pdf = invarea;
+ }
+ else {
+ inplane = ls->P;
+ ls->pdf = rect_light_sample(P, &ls->P,
+ axisu, axisv,
+ randu, randv,
+ true);
+ inplane = ls->P - inplane;
+ }
- inplane = ls->P - inplane;
ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
ls->Ng = D;
ls->D = normalize_len(ls->P - P, &ls->t);
- float invarea = klight->area.invarea;
ls->eval_fac = 0.25f*invarea;
+ if(is_round) {
+ ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t);
+ }
}
}
@@ -727,7 +764,8 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
}
else if(type == LIGHT_AREA) {
/* area light */
- float invarea = klight->area.invarea;
+ float invarea = fabsf(klight->area.invarea);
+ bool is_round = (klight->area.invarea < 0.0f);
if(invarea == 0.0f)
return false;
@@ -750,14 +788,20 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
if(!ray_quad_intersect(P, D, 0.0f, t, light_P,
axisu, axisv, Ng,
&ls->P, &ls->t,
- &ls->u, &ls->v))
+ &ls->u, &ls->v,
+ is_round))
{
return false;
}
ls->D = D;
ls->Ng = Ng;
- ls->pdf = area_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
+ if(is_round) {
+ ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
+ }
+ else {
+ ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
+ }
ls->eval_fac = 0.25f*invarea;
}
else {
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index e256a1819ed..49a1b2c848e 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -200,7 +200,7 @@ ccl_device_inline size_t kernel_write_id_pass_cpu(float *buffer, size_t depth, f
return 0;
}
#else /* __KERNEL_CPU__ */
-#define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) kernel_write_id_slots_gpu(buffer, depth * 2, id, matte_weight)
+#define WRITE_ID_SLOT(buffer, depth, id, matte_weight, name) kernel_write_id_slots_gpu(buffer, depth * 2, id, matte_weight)
ccl_device_inline size_t kernel_write_id_slots_gpu(ccl_global float *buffer, size_t depth, float id, float matte_weight)
{
#endif /* __KERNEL_CPU__ */
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index f901885e679..b4e3c18e894 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -472,7 +472,11 @@ void DisplayBuffer::draw(Device *device, const DeviceDrawParams& draw_params)
device_memory& rgba = (half_float)? (device_memory&)rgba_half:
(device_memory&)rgba_byte;
- device->draw_pixels(rgba, 0, draw_width, draw_height, params.full_x, params.full_y, params.width, params.height, transparent, draw_params);
+ device->draw_pixels(
+ rgba, 0,
+ draw_width, draw_height, params.width, params.height,
+ params.full_x, params.full_y, params.full_width, params.full_height,
+ transparent, draw_params);
}
}
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index e6ef19cc3be..2865b0e5e97 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -1023,6 +1023,39 @@ void ImageManager::device_update_slot(Device *device,
}
}
+void ImageManager::device_load_builtin(Device *device,
+ Scene *scene,
+ Progress& progress)
+{
+ /* Load only builtin images, Blender needs this to load evaluated
+ * scene data from depsgraph before it is freed. */
+ if(!need_update) {
+ return;
+ }
+
+ TaskPool pool;
+ for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for(size_t slot = 0; slot < images[type].size(); slot++) {
+ if(!images[type][slot])
+ continue;
+
+ if(images[type][slot]->need_load) {
+ if(images[type][slot]->builtin_data) {
+ pool.push(function_bind(&ImageManager::device_load_image,
+ this,
+ device,
+ scene,
+ (ImageDataType)type,
+ slot,
+ &progress));
+ }
+ }
+ }
+ }
+
+ pool.wait_work();
+}
+
void ImageManager::device_free_builtin(Device *device)
{
for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index d94ebe564e3..0bf06c322d0 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -83,6 +83,10 @@ public:
int flat_slot,
Progress *progress);
void device_free(Device *device);
+
+ void device_load_builtin(Device *device,
+ Scene *scene,
+ Progress& progress);
void device_free_builtin(Device *device);
void set_osl_texture_system(void *texture_system);
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 3580f4a8eeb..a5854f022cd 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -118,6 +118,7 @@ NODE_DEFINE(Light)
SOCKET_FLOAT(sizeu, "Size U", 1.0f);
SOCKET_VECTOR(axisv, "Axis V", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_FLOAT(sizev, "Size V", 1.0f);
+ SOCKET_BOOLEAN(round, "Round", false);
SOCKET_INT(map_resolution, "Map Resolution", 0);
@@ -757,12 +758,15 @@ void LightManager::device_update_points(Device *,
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
float area = len(axisu)*len(axisv);
- float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+ if(light->round) {
+ area *= -M_PI_4_F;
+ }
+ float invarea = (area != 0.0f)? 1.0f/area: 1.0f;
float3 dir = light->dir;
dir = safe_normalize(dir);
- if(light->use_mis && area > 0.0f)
+ if(light->use_mis && area != 0.0f)
shader_id |= SHADER_USE_MIS;
klights[light_index].co[0] = co.x;
@@ -830,7 +834,10 @@ void LightManager::device_update_points(Device *,
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
float area = len(axisu)*len(axisv);
- float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+ if(light->round) {
+ area *= -M_PI_4_F;
+ }
+ float invarea = (area != 0.0f)? 1.0f/area: 1.0f;
float3 dir = light->dir;
dir = safe_normalize(dir);
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 32a911dc256..ec957c7cc68 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -51,6 +51,7 @@ public:
float sizeu;
float3 axisv;
float sizev;
+ bool round;
Transform tfm;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 1943f8c3e2b..06a2baa8a38 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1520,6 +1520,19 @@ void PointDensityTextureNode::attributes(Shader *shader,
ShaderNode::attributes(shader, attributes);
}
+void PointDensityTextureNode::add_image()
+{
+ if(slot == -1) {
+ ImageMetaData metadata;
+ slot = image_manager->add_image(filename.string(), builtin_data,
+ false, 0,
+ interpolation,
+ EXTENSION_CLIP,
+ true,
+ metadata);
+ }
+}
+
void PointDensityTextureNode::compile(SVMCompiler& compiler)
{
ShaderInput *vector_in = input("Vector");
@@ -1532,15 +1545,7 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
image_manager = compiler.image_manager;
if(use_density || use_color) {
- if(slot == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(), builtin_data,
- false, 0,
- interpolation,
- EXTENSION_CLIP,
- true,
- metadata);
- }
+ add_image();
if(slot != -1) {
compiler.stack_assign(vector_in);
@@ -1583,15 +1588,7 @@ void PointDensityTextureNode::compile(OSLCompiler& compiler)
image_manager = compiler.image_manager;
if(use_density || use_color) {
- if(slot == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(), builtin_data,
- false, 0,
- interpolation,
- EXTENSION_CLIP,
- true,
- metadata);
- }
+ add_image();
if(slot != -1) {
compiler.parameter("filename", string_printf("@i%d", slot).c_str());
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 28bbe2de05a..c2cf13ad020 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -267,6 +267,8 @@ public:
bool has_spatial_varying() { return true; }
bool has_object_dependency() { return true; }
+ void add_image();
+
ustring filename;
NodeTexVoxelSpace space;
InterpolationType interpolation;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index a827f611583..86860bbc8ac 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -208,6 +208,7 @@ Shader::Shader()
need_update = true;
need_update_mesh = true;
+ need_sync_object = false;
}
Shader::~Shader()
@@ -525,7 +526,7 @@ void ShaderManager::device_update_common(Device *device,
flag |= SD_HAS_CONSTANT_EMISSION;
uint32_t cryptomatte_id = util_murmur_hash3(shader->name.c_str(), shader->name.length(), 0);
-
+
/* regular shader */
kshader->flags = flag;
kshader->pass_id = shader->pass_id;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 80731384048..890208c4bf8 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -99,6 +99,7 @@ public:
/* synchronization */
bool need_update;
bool need_update_mesh;
+ bool need_sync_object;
/* If the shader has only volume components, the surface is assumed to
* be transparent.
diff --git a/intern/cycles/util/util_math_intersect.h b/intern/cycles/util/util_math_intersect.h
index b5fbb24091f..bc3dd1500a9 100644
--- a/intern/cycles/util/util_math_intersect.h
+++ b/intern/cycles/util/util_math_intersect.h
@@ -186,12 +186,17 @@ ccl_device_forceinline bool ray_triangle_intersect(
#undef dot3
}
+/* Tests for an intersection between a ray and a quad defined by
+ * its midpoint, normal and sides.
+ * If ellipse is true, hits outside the ellipse that's enclosed by the
+ * quad are rejected.
+ */
ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D,
float ray_mint, float ray_maxt,
float3 quad_P,
float3 quad_u, float3 quad_v, float3 quad_n,
float3 *isect_P, float *isect_t,
- float *isect_u, float *isect_v)
+ float *isect_u, float *isect_v, bool ellipse)
{
/* Perform intersection test. */
float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n);
@@ -200,20 +205,23 @@ ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D,
}
const float3 hit = ray_P + t*ray_D;
const float3 inplane = hit - quad_P;
- const float u = dot(inplane, quad_u) / dot(quad_u, quad_u) + 0.5f;
- if(u < 0.0f || u > 1.0f) {
+ const float u = dot(inplane, quad_u) / dot(quad_u, quad_u);
+ if(u < -0.5f || u > 0.5f) {
+ return false;
+ }
+ const float v = dot(inplane, quad_v) / dot(quad_v, quad_v);
+ if(v < -0.5f || v > 0.5f) {
return false;
}
- const float v = dot(inplane, quad_v) / dot(quad_v, quad_v) + 0.5f;
- if(v < 0.0f || v > 1.0f) {
+ if(ellipse && (u*u + v*v > 0.25f)) {
return false;
}
/* Store the result. */
/* TODO(sergey): Check whether we can avoid some checks here. */
if(isect_P != NULL) *isect_P = hit;
if(isect_t != NULL) *isect_t = t;
- if(isect_u != NULL) *isect_u = u;
- if(isect_v != NULL) *isect_v = v;
+ if(isect_u != NULL) *isect_u = u + 0.5f;
+ if(isect_v != NULL) *isect_v = v + 0.5f;
return true;
}
diff --git a/intern/cycles/util/util_opengl.h b/intern/cycles/util/util_opengl.h
index 0b5462e0a09..7a8d5eec1f9 100644
--- a/intern/cycles/util/util_opengl.h
+++ b/intern/cycles/util/util_opengl.h
@@ -20,12 +20,6 @@
/* OpenGL header includes, used everywhere we use OpenGL, to deal with
* platform differences in one central place. */
-#ifdef WITH_GLEW_MX
-# include "glew-mx.h"
-#else
-# include <GL/glew.h>
-# define mxCreateContext() glewInit()
-# define mxMakeCurrentContext(x) (x)
-#endif
+#include <GL/glew.h>
#endif /* __UTIL_OPENGL_H__ */
diff --git a/intern/cycles/util/util_view.cpp b/intern/cycles/util/util_view.cpp
index 3836cc86ee0..05094c7b327 100644
--- a/intern/cycles/util/util_view.cpp
+++ b/intern/cycles/util/util_view.cpp
@@ -252,7 +252,7 @@ void view_main_loop(const char *title, int width, int height,
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow(title);
- mxMakeCurrentContext(mxCreateContext());
+ glewInit();
view_reshape(width, height);