Skip to content

Commit

Permalink
Simplifies AOV implementation so we can easily add more in the future #…
Browse files Browse the repository at this point in the history
  • Loading branch information
osiriswrecks committed Jul 31, 2022
1 parent 2f8d130 commit a1e592c
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 87 deletions.
34 changes: 11 additions & 23 deletions btoa/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,46 +74,34 @@ def export(self, engine, depsgraph, prefs, context=None):
if depsgraph.scene.world.arnold.node_tree:
WorldExporter(self).export(depsgraph.scene.world)

# Everything else
# AOVs
scene = self.cache.scene
aovs = bpy.context.view_layer.arnold.passes
aovs = bpy.context.view_layer.arnold.aovs
enabled_aovs = [aovs.beauty] if self.is_interactive else aovs.enabled_aovs

default_filter = ArnoldNode(scene["filter_type"])
default_filter.set_string("name", "btoa_image_filter")
default_filter.set_string("name", "btoa_default_filter")
default_filter.set_float("width", scene["filter_width"])

if self.is_interactive:
# Force only RGBA aov
active_aovs = ['RGBA']
else:
active_aovs = [aov[9:] for aov in aovs.__annotations__.keys() if getattr(aovs, aov)]
active_aovs = list(map(lambda x: x.replace("beauty", "RGBA"), active_aovs))
active_aovs = list(map(lambda x: x.replace("z", "Z"), active_aovs))

outputs = ArnoldArray()
outputs.allocate(len(active_aovs), 1, 'STRING')
outputs.allocate(len(enabled_aovs), 1, 'STRING')

for aov in active_aovs:
pixel_type = 'RGB'
image_filter = "btoa_image_filter"

if aov == 'Z':
pixel_type = 'FLOAT'
for aov in enabled_aovs:
filter_type = "btoa_default_filter"

if aov.name == 'Z':
closest_filter = ArnoldNode("closest_filter")
closest_filter.set_string("name", "btoa_closest_filter")
closest_filter.set_float("width", scene["filter_width"])

image_filter = 'btoa_closest_filter'
elif aov == 'RGBA':
pixel_type = 'RGBA'
filter_type = "btoa_closest_filter"

outputs.set_string(active_aovs.index(aov), f"{aov} {pixel_type} {image_filter} btoa_driver")
outputs.set_string(enabled_aovs.index(aov), f"{aov.ainame} {aov.pixel_type} {filter_type} btoa_driver")

options.set_array("outputs", outputs)

arnold.AiRenderAddInteractiveOutput(None, 0)

# Color management
color_manager = ArnoldColorManager()

if 'OCIO' in os.environ:
Expand Down
40 changes: 13 additions & 27 deletions engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ def update_render_result(buffer):
engine.end_result(result)
engine.session.free_buffer(buffer)

engine.update_result(result)

# Update progress counter
engine.progress += engine._progress_increment
engine.update_progress(engine.progress)
Expand All @@ -195,21 +197,13 @@ def update_render_result(buffer):
driver.set_pointer("callback", cb)

# Set up custom render passes
aovs = depsgraph.view_layer.arnold.passes

for aov in aovs.__annotations__.keys():
if not getattr(aovs, aov):
continue
aovs = depsgraph.view_layer.arnold.aovs

aov_name = "Z" if aov[9:] == 'z' else aov[9:]

if aov_name == 'beauty':
for aov in aovs.enabled_aovs:
if aov.name == "Beauty":
continue

if aov_name == "Z":
self.add_pass(aov_name, 1, "Z")
else:
self.add_pass(aov_name, 3, "RGB")

self.add_pass(aov.ainame, aov.channels, aov.chan_id)

# Calculate progress increment
(width, height) = options.get_render_resolution()
Expand Down Expand Up @@ -387,21 +381,13 @@ def view_draw(self, context, depsgraph):
def update_render_passes(self, scene=None, renderlayer=None):
self.register_pass(scene, renderlayer, "Combined", 4, "RGBA", 'COLOR')

aovs = renderlayer.arnold.passes
aovs = renderlayer.arnold.aovs

for aov in aovs.__annotations__.keys():
if not getattr(aovs, aov):
continue

aov_name = "Z" if aov[9:] == 'z' else aov[9:]

if aov_name == 'beauty':
continue

if aov_name == "Z":
self.register_pass(scene, renderlayer, "Z", 1, "Z", "VALUE")
else:
self.register_pass(scene, renderlayer, aov_name, 3, "RGB", "COLOR")
for aov in aovs.enabled_aovs:
if aov.name == "Beauty":
continue

self.register_pass(scene, renderlayer, aov.ainame, aov.channels, aov.chan_id, aov.pass_type)

def get_panels():
exclude_panels = {
Expand Down
123 changes: 89 additions & 34 deletions props/view_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,98 @@
from bpy.props import *
from .. import utils

'''
RenderPassConfig is a simple helper class to manage AOV data
differences between Blender and Arnold.
'''
class RenderPassConfig:
def __init__(self, name, ainame, channels, chan_id, pixel_type):
self.name = name # label in UI
self.ainame = ainame # Arnold-specific name
self.channels = channels # Number of channels
self.chan_id = chan_id # Channel names, one character per channel
self.pixel_type = pixel_type # Arnold-specific pixel type (FLOAT, RGB, RGBA, etc)

# For compositor
# Enum in ['VALUE', 'VECTOR', 'COLOR']
if pixel_type == 'FLOAT':
self.pass_type = 'VALUE'
elif 'RGB' in pixel_type:
self.pass_type = 'COLOR'

class RenderPassConfigGroup:
data = (
RenderPassConfig("Beauty", "RGBA", 4, "RGBA", "RGBA"),
RenderPassConfig("Z", "Z", 1, "Z", "FLOAT"),
RenderPassConfig("Direct", "direct", 3, "RGB", "RGB"),
RenderPassConfig("Indirect", "indirect", 3, "RGB", "RGB"),
RenderPassConfig("Emission", "emission", 3, "RGB", "RGB"),
RenderPassConfig("Background", "background", 3, "RGB", "RGB"),
RenderPassConfig("Diffuse", "diffuse", 3, "RGB", "RGB"),
RenderPassConfig("Specular", "specular", 3, "RGB", "RGB"),
RenderPassConfig("Coat", "coat", 3, "RGB", "RGB"),
RenderPassConfig("Transmission", "transmission", 3, "RGB", "RGB"),
RenderPassConfig("SSS", "sss", 3, "RGB", "RGB"),
RenderPassConfig("Volume", "volume", 3, "RGB", "RGB"),
RenderPassConfig("Albedo", "albedo", 3, "RGB", "RGB"),
RenderPassConfig("Light Groups", "light_groups", 3, "RGB", "RGB"),
RenderPassConfig("Motion Vectors", "motionvector", 3, "RGB", "RGB"), # this pixel type is probably wrong
)

light = (
RenderPassConfig("Diffuse Direct", "diffuse_direct", 3, "RGB", "RGB"),
RenderPassConfig("Diffuse Indirect", "diffuse_indirect", 3, "RGB", "RGB"),
RenderPassConfig("Diffuse Albedo", "diffuse_albedo", 3, "RGB", "RGB"),
RenderPassConfig("Specular Direct", "specular_direct", 3, "RGB", "RGB"),
RenderPassConfig("Specular Indirect", "specular_indirect", 3, "RGB", "RGB"),
RenderPassConfig("Specular Albedo", "specular_albedo", 3, "RGB", "RGB"),
RenderPassConfig("Coat Direct", "coat_direct", 3, "RGB", "RGB"),
RenderPassConfig("Coat Indirect", "coat_indirect", 3, "RGB", "RGB"),
RenderPassConfig("Coat Albedo", "coat_albedo", 3, "RGB", "RGB"),
RenderPassConfig("Transmission Direct", "transmission_direct", 3, "RGB", "RGB"),
RenderPassConfig("Transmission Indirect", "transmission_indirect", 3, "RGB", "RGB"),
RenderPassConfig("Transmission Albedo", "transmission_albedo", 3, "RGB", "RGB"),
RenderPassConfig("SSS Direct", "sss_direct", 3, "RGB", "RGB"),
RenderPassConfig("SSS Indirect", "sss_indirect", 3, "RGB", "RGB"),
RenderPassConfig("SSS Albedo", "sss_albedo", 3, "RGB", "RGB"),
RenderPassConfig("Volume Direct", "volume_direct", 3, "RGB", "RGB"),
RenderPassConfig("Volume Indirect", "volume_indirect", 3, "RGB", "RGB"),
RenderPassConfig("Volume Albedo", "volume_albedo", 3, "RGB", "RGB"),
)

class ArnoldRenderPasses(PropertyGroup):
use_pass_beauty: BoolProperty(name="Beauty", default=True)
use_pass_z: BoolProperty(name="Z", default=True)
use_pass_direct: BoolProperty(name="Direct")
use_pass_indirect: BoolProperty(name="Indirect")
use_pass_emission: BoolProperty(name="Emission")
use_pass_background: BoolProperty(name="Background")
use_pass_diffuse: BoolProperty(name="Diffuse")
use_pass_specular: BoolProperty(name="Specular")
use_pass_coat: BoolProperty(name="Coat")
use_pass_transmission: BoolProperty(name="Transmission")
use_pass_sss: BoolProperty(name="SSS")
use_pass_volume: BoolProperty(name="Volume")
use_pass_albedo: BoolProperty(name="Albedo")
use_pass_diffuse_direct: BoolProperty(name="Diffuse Direct")
use_pass_diffuse_indirect: BoolProperty(name="Diffuse Indirect")
use_pass_diffuse_albedo: BoolProperty(name="Diffuse Albedo")
use_pass_specular_direct: BoolProperty(name="Specular Direct")
use_pass_specular_indirect: BoolProperty(name="Specular Indirect")
use_pass_specular_albedo: BoolProperty(name="Specular Albedo")
use_pass_coat_direct: BoolProperty(name="Coat Direct")
use_pass_coat_indirect: BoolProperty(name="Coat Indirect")
use_pass_coat_albedo: BoolProperty(name="Coat Albedo")
use_pass_transmission_direct: BoolProperty(name="Transmission Direct")
use_pass_transmission_indirect: BoolProperty(name="Transmission Indirect")
use_pass_transmission_albedo: BoolProperty(name="Transmission Albedo")
use_pass_sss_direct: BoolProperty(name="SSS Direct")
use_pass_sss_indirect: BoolProperty(name="SSS Indirect")
use_pass_sss_albedo: BoolProperty(name="SSS Albedo")
use_pass_volume_direct: BoolProperty(name="Volume Direct")
use_pass_volume_indirect: BoolProperty(name="Volume Indirect")
use_pass_volume_albedo: BoolProperty(name="Volume Albedo")
use_pass_light_groups: BoolProperty(name="Light Groups")
use_pass_motionvector: BoolProperty(name="Motion Vectors")
config = RenderPassConfigGroup()

def update_render_passes(self, context):
context.view_layer.update_render_passes()

enabled_data_aovs: BoolVectorProperty(
name="Data AOVs",
size=len(config.data),
default=tuple(aov.name in {"Beauty", "Z"} for aov in config.data),
update=update_render_passes
)

enabled_light_aovs: BoolVectorProperty(
name="Light AOVs",
size=len(config.light),
default=tuple(False for i in range(len(config.light))),
update=update_render_passes
)

@property
def beauty(self):
return self.config.data[0]

@property
def enabled_aovs(self):
result = [aov for aov in self.config.data if self.enabled_data_aovs[self.config.data.index(aov)]]
result += [aov for aov in self.config.light if self.enabled_light_aovs[self.config.light.index(aov)]]

return result

class ArnoldRenderLayer(PropertyGroup):
passes: PointerProperty(type=ArnoldRenderPasses)
aovs: PointerProperty(type=ArnoldRenderPasses)

classes = (
ArnoldRenderPasses,
Expand Down
44 changes: 41 additions & 3 deletions ui/view_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,47 @@ def draw(self, context):
layout.use_property_split = True
layout.use_property_decorate = False

arnold_view_layer = context.view_layer.arnold
aovs = context.view_layer.arnold.aovs

for i in range(len(aovs.enabled_data_aovs)):
aov = aovs.config.data[i]
layout.prop(aovs, "enabled_data_aovs", index=i, text=aov.name)

class ARNOLD_RENDER_PT_aovs_light(ArnoldViewLayerPanel):
bl_label = "Light"
bl_parent_id = "ARNOLD_RENDER_PT_aovs"

def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False

aovs = context.view_layer.arnold.aovs

for i in range(len(aovs.enabled_light_aovs)):
aov = aovs.config.light[i]
label = aov.name.split()

if i % 3 == 0:
col = layout.column(heading=label[0])

col.prop(aovs, "enabled_light_aovs", index=i, text=" ".join(label[1:]))

class ARNOLD_RENDER_PT_aovs_cryptomatte(ArnoldViewLayerPanel):
bl_label = "Cryptomatte"
bl_parent_id = "ARNOLD_RENDER_PT_aovs"

def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False

view_layer = context.view_layer

col = layout.column()
for annotation in arnold_view_layer.passes.__annotations__.keys():
col.prop(arnold_view_layer.passes, annotation)
col.prop(view_layer, "use_pass_cryptomatte_asset")
col.prop(view_layer, "use_pass_cryptomatte_material")
col.prop(view_layer, "use_pass_cryptomatte_object")

class ARNOLD_RENDER_PT_override(ArnoldViewLayerPanel):
bl_label = "Override"
Expand All @@ -45,6 +81,8 @@ def draw(self, context):
classes = (
ARNOLD_RENDER_PT_aovs,
ARNOLD_RENDER_PT_aovs_data,
ARNOLD_RENDER_PT_aovs_light,
#ARNOLD_RENDER_PT_aovs_cryptomatte,
ARNOLD_RENDER_PT_override,
)

Expand Down

0 comments on commit a1e592c

Please sign in to comment.