Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Renderman support for sample and display filters #4003

Merged
merged 26 commits into from
Jan 27, 2023

Conversation

moonyuet
Copy link
Member

@moonyuet moonyuet commented Oct 19, 2022

Brief description

User can set up both sample and display filters in Openpype settings if they are using Renderman as renderer.

Description

You can preset which sample and display filters for renderman , including the cryptomatte renderpass, in Openpype settings. Once you select which filters to be included in openpype settings and then create render instance for your camera in maya, it would automatically tell the system to generate your selected filters in render settings.

The place you can find for setting up the filters: Maya > Render Settings > Renderman Renderer > Display Filters/ Sample Filters

image

image

Additional info

I also edit the image_prefix for this ticket so that to unify the render settings a little bit.
I set up the Image prefix template in the setting as if other renderers does. (see the screenshot of Openpype settings above)

@moonyuet moonyuet self-assigned this Oct 19, 2022
@ynbot
Copy link
Contributor

ynbot commented Oct 19, 2022

@github-actions github-actions bot added this to the next-patch milestone Oct 26, 2022
@mkolar mkolar marked this pull request as ready for review November 7, 2022 14:56
@jakubjezek001 jakubjezek001 removed this from the next-patch milestone Nov 10, 2022
Copy link
Member

@antirotor antirotor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid that this is not complete yet - what it is missing is actually support for output of these filters. They need to be recognized by lib_renderproducts - for example:

adding PxrCryptomatte filter will add output (with it's own image prefix!) - by default <imagedir>cryptomatte.<f4>.exr - this needs to be added to render products so it is then collected and published.

Another thing is that image prefix you've added - that unfortunately works differently in Renderman than in other renderers. You see, Renderman has split image dir and image prefixes itself - setting this image prefix that holds dirs will result in doubling of the structure. THat's why renderman image prefixes are handled in OP somewhat differently.

@moonyuet
Copy link
Member Author

moonyuet commented Nov 29, 2022

I have updated the PR request and I find out that the incorrect image prefix and image output directory are the main reason why the layers aren't being rendered correctly(They can't really find the related path!).
The updated PR would add the correct directories for all the maps, including Cryptomatte. I also aligned the name similar to images prefix of other renderers, e.g. Main_beauty.exr.
I am not quite sure about the usage of watermark and image display. it would be great if there're any suggestions for the path of these two filters. (Is It better just leave it blank?)
image

image

Copy link
Member

@antirotor antirotor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I've got to this after while. Setting of the render settings work great, but I think we still need to tweak how the Display and Sample filters are collected in render products. See this scenarion:

image

Simple scene, just one render layer, beauty and cryptomatte. Only beauty is collected though. This will result in correct render, but publishing script won't see cryptomattes.

I guess we need to add logic here to collect and process Display and Sample filter nodes?

class RenderProductsRenderman(ARenderProducts):
"""Expected files for Renderman renderer.
Warning:
This is very rudimentary and needs more love and testing.
"""
renderer = "renderman"
def get_render_products(self):
"""Get all AOVs.
See Also:
:func:`ARenderProducts.get_render_products()`
"""
from rfm2.api.displays import get_displays # noqa
cameras = [
self.sanitize_camera_name(c)
for c in self.get_renderable_cameras()
]
if not cameras:
cameras = [
self.sanitize_camera_name(
self.get_renderable_cameras()[0])
]
products = []
# NOTE: This is guessing extensions from renderman display types.
# Some of them are just framebuffers, d_texture format can be
# set in display setting. We set those now to None, but it
# should be handled more gracefully.
display_types = {
"d_deepexr": "exr",
"d_it": None,
"d_null": None,
"d_openexr": "exr",
"d_png": "png",
"d_pointcloud": "ptc",
"d_targa": "tga",
"d_texture": None,
"d_tiff": "tif"
}
displays = get_displays(override_dst="render")["displays"]
for name, display in displays.items():
enabled = display["params"]["enable"]["value"]
if not enabled:
continue
# Skip display types not producing any file output.
# Is there a better way to do it?
if not display_types.get(display["driverNode"]["type"]):
continue
aov_name = name
if aov_name == "rmanDefaultDisplay":
aov_name = "beauty"
extensions = display_types.get(
display["driverNode"]["type"], "exr")
for camera in cameras:
# Create render product and set it as multipart only on
# display types supporting it. In all other cases, Renderman
# will create separate output per channel.
if display["driverNode"]["type"] in ["d_openexr", "d_deepexr", "d_tiff"]: # noqa
product = RenderProduct(
productName=aov_name,
ext=extensions,
camera=camera,
multipart=True
)
else:
# this code should handle the case where no multipart
# capable format is selected. But since it involves
# shady logic to determine what channel become what
# lets not do that as all productions will use exr anyway.
"""
for channel in display['params']['displayChannels']['value']: # noqa
product = RenderProduct(
productName="{}_{}".format(aov_name, channel),
ext=extensions,
camera=camera,
multipart=False
)
"""
raise UnsupportedImageFormatException(
"Only exr, deep exr and tiff formats are supported.")
products.append(product)
return products

@moonyuet moonyuet force-pushed the OP-3572/Renderman-support-for-Sample-and-Display branch from dbc34cc to 92e3d10 Compare January 17, 2023 10:27
@moonyuet
Copy link
Member Author

moonyuet commented Jan 17, 2023

Sorry I've got to this after while. Setting of the render settings work great, but I think we still need to tweak how the Display and Sample filters are collected in render products. See this scenarion:

image

Simple scene, just one render layer, beauty and cryptomatte. Only beauty is collected though. This will result in correct render, but publishing script won't see cryptomattes.

I guess we need to add logic here to collect and process Display and Sample filter nodes?

class RenderProductsRenderman(ARenderProducts):
"""Expected files for Renderman renderer.
Warning:
This is very rudimentary and needs more love and testing.
"""
renderer = "renderman"
def get_render_products(self):
"""Get all AOVs.
See Also:
:func:`ARenderProducts.get_render_products()`
"""
from rfm2.api.displays import get_displays # noqa
cameras = [
self.sanitize_camera_name(c)
for c in self.get_renderable_cameras()
]
if not cameras:
cameras = [
self.sanitize_camera_name(
self.get_renderable_cameras()[0])
]
products = []
# NOTE: This is guessing extensions from renderman display types.
# Some of them are just framebuffers, d_texture format can be
# set in display setting. We set those now to None, but it
# should be handled more gracefully.
display_types = {
"d_deepexr": "exr",
"d_it": None,
"d_null": None,
"d_openexr": "exr",
"d_png": "png",
"d_pointcloud": "ptc",
"d_targa": "tga",
"d_texture": None,
"d_tiff": "tif"
}
displays = get_displays(override_dst="render")["displays"]
for name, display in displays.items():
enabled = display["params"]["enable"]["value"]
if not enabled:
continue
# Skip display types not producing any file output.
# Is there a better way to do it?
if not display_types.get(display["driverNode"]["type"]):
continue
aov_name = name
if aov_name == "rmanDefaultDisplay":
aov_name = "beauty"
extensions = display_types.get(
display["driverNode"]["type"], "exr")
for camera in cameras:
# Create render product and set it as multipart only on
# display types supporting it. In all other cases, Renderman
# will create separate output per channel.
if display["driverNode"]["type"] in ["d_openexr", "d_deepexr", "d_tiff"]: # noqa
product = RenderProduct(
productName=aov_name,
ext=extensions,
camera=camera,
multipart=True
)
else:
# this code should handle the case where no multipart
# capable format is selected. But since it involves
# shady logic to determine what channel become what
# lets not do that as all productions will use exr anyway.
"""
for channel in display['params']['displayChannels']['value']: # noqa
product = RenderProduct(
productName="{}_{}".format(aov_name, channel),
ext=extensions,
camera=camera,
multipart=False
)
"""
raise UnsupportedImageFormatException(
"Only exr, deep exr and tiff formats are supported.")
products.append(product)
return products

I have added cryptomatte and it is included in the collect render layer in the updated PR

Copy link
Member

@antirotor antirotor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it works! There is a little issue that cryptomattes are still processed by review for some reason but this is not part of this PR

@antirotor antirotor merged commit dd4f5a2 into develop Jan 27, 2023
@antirotor antirotor deleted the OP-3572/Renderman-support-for-Sample-and-Display branch January 27, 2023 15:21
@github-actions github-actions bot added this to the next-patch milestone Jan 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants