diff --git a/Changes.md b/Changes.md index 9405c818d48..4c3aba7bc6d 100644 --- a/Changes.md +++ b/Changes.md @@ -34,6 +34,7 @@ Improvements - Improved numerical accuracy. - Improved performance. - VectorDataPlugValueWidget : Computation errors are now reflected by a red background colour. +- Cycles : Added OpenImageDenoise support. Fixes ----- diff --git a/SConstruct b/SConstruct index 69658ea2377..21ac05d3f0d 100644 --- a/SConstruct +++ b/SConstruct @@ -1275,7 +1275,7 @@ libraries = { "cycles_session", "cycles_scene", "cycles_graph", "cycles_bvh", "cycles_device", "cycles_kernel", "cycles_kernel_osl", "cycles_integrator", "cycles_util", "cycles_subd", "extern_sky", "OpenImageIO$OIIO_LIB_SUFFIX", "OpenImageIO_Util$OIIO_LIB_SUFFIX", "oslexec$OSL_LIB_SUFFIX", "oslquery$OSL_LIB_SUFFIX", - "openvdb$VDB_LIB_SUFFIX", "Alembic", "osdCPU", "OpenColorIO$OCIO_LIB_SUFFIX", "embree3", "Iex", "openpgl", + "openvdb$VDB_LIB_SUFFIX", "Alembic", "osdCPU", "OpenColorIO$OCIO_LIB_SUFFIX", "embree3", "Iex", "openpgl", "OpenImageDenoise", ], "CXXFLAGS" : [ systemIncludeArgument, "$CYCLES_ROOT/include" ], "CPPDEFINES" : [ @@ -1283,6 +1283,7 @@ libraries = { ( "CCL_NAMESPACE_END", "}" ), ( "WITH_OSL", "1" ), ( "WITH_CYCLES_PATH_GUIDING", "1" ), + ( "WITH_OPENIMAGEDENOISE", "1" ), ], "FRAMEWORKS" : [ "Foundation", "Metal", "IOKit" ], }, @@ -1293,13 +1294,14 @@ libraries = { "cycles_session", "cycles_scene", "cycles_graph", "cycles_bvh", "cycles_device", "cycles_kernel", "cycles_kernel_osl", "cycles_integrator", "cycles_util", "cycles_subd", "extern_sky", "OpenImageIO$OIIO_LIB_SUFFIX", "OpenImageIO_Util$OIIO_LIB_SUFFIX", "oslexec$OSL_LIB_SUFFIX", "openvdb$VDB_LIB_SUFFIX", - "oslquery$OSL_LIB_SUFFIX", "Alembic", "osdCPU", "OpenColorIO$OCIO_LIB_SUFFIX", "embree3", "Iex", "openpgl", + "oslquery$OSL_LIB_SUFFIX", "Alembic", "osdCPU", "OpenColorIO$OCIO_LIB_SUFFIX", "embree3", "Iex", "openpgl", "OpenImageDenoise", ], "CXXFLAGS" : [ systemIncludeArgument, "$CYCLES_ROOT/include" ], "CPPDEFINES" : [ ( "CCL_NAMESPACE_BEGIN", "namespace ccl {" ), ( "CCL_NAMESPACE_END", "}" ), ( "WITH_CYCLES_PATH_GUIDING", "1" ), + ( "WITH_OPENIMAGEDENOISE", "1" ), ], }, "requiredOptions" : [ "CYCLES_ROOT" ], diff --git a/python/GafferCyclesUI/CyclesOptionsUI.py b/python/GafferCyclesUI/CyclesOptionsUI.py index d911b457bd8..d8ac22dc662 100644 --- a/python/GafferCyclesUI/CyclesOptionsUI.py +++ b/python/GafferCyclesUI/CyclesOptionsUI.py @@ -246,6 +246,9 @@ def __denoisingSummary( plug ) : info = [] + if plug["useDenoise"]["enabled"].getValue() : + info.append( "Use Denoising {}".format( plug["useDenoise"]["value"].getValue() ) ) + if plug["denoiserType"]["enabled"].getValue() : info.append( "Denoise Type {}".format( plug["denoiserType"]["value"].getValue() ) ) @@ -1370,6 +1373,18 @@ def __devicesPreset() : # Denoising + "options.useDenoise" : [ + + "description", + """ + Enable the Denoiser. + """, + + "layout:section", "Denoising", + "label", "Use Denoising", + + ], + "options.denoiserType" : [ "description", diff --git a/src/GafferCycles/CyclesOptions.cpp b/src/GafferCycles/CyclesOptions.cpp index 78577b1a309..bf5edf79d31 100644 --- a/src/GafferCycles/CyclesOptions.cpp +++ b/src/GafferCycles/CyclesOptions.cpp @@ -116,6 +116,7 @@ CyclesOptions::CyclesOptions( const std::string &name ) options->addChild( new Gaffer::NameValuePlug( "cycles:integrator:sampling_pattern", new IECore::StringData( "sobol" ), false, "samplingPattern" ) ); + options->addChild( new Gaffer::NameValuePlug( "cycles:integrator:use_denoise", new IECore::BoolData( false ), false, "useDenoise" ) ); options->addChild( new Gaffer::NameValuePlug( "cycles:integrator:denoiser_type", new IECore::StringData( "openimagedenoise" ), false, "denoiserType" ) ); options->addChild( new Gaffer::NameValuePlug( "cycles:integrator:denoise_start_sample", new IECore::IntData( 0 ), false, "denoiseStartSample" ) ); options->addChild( new Gaffer::NameValuePlug( "cycles:integrator:use_denoise_pass_albedo", new IECore::BoolData( true ), false, "useDenoisePassAlbedo" ) ); diff --git a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp index fed5a8aba6c..e6191d76c1e 100644 --- a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp @@ -293,7 +293,7 @@ class CyclesOutput : public IECore::RefCounted public : CyclesOutput( const ccl::Session *session, const IECore::InternedString &name, const IECoreScene::Output *output ) - : m_passType( ccl::PASS_NONE ), m_denoise( false ), m_interactive( false ), m_lightgroup( false ) + : m_passType( ccl::PASS_NONE ), m_denoise( false ), m_interactive( false ), m_viewport( false ), m_lightgroup( false ) { m_parameters = output->parametersData()->copy(); CompoundDataMap &p = m_parameters->writable(); @@ -301,10 +301,9 @@ class CyclesOutput : public IECore::RefCounted p["path"] = new StringData( output->getName() ); p["driver"] = new StringData( output->getType() ); - if( output->getType() == "ieDisplay" ) - m_interactive = true; - + m_interactive = output->getType() == "ieDisplay" ? true : false; m_denoise = parameter( output->parameters(), "denoise", false ); + m_viewport = parameter( output->parameters(), "driverType", "" ) == "OutputBuffer::DisplayDriver" ? true : false; const ccl::NodeEnum &typeEnum = *ccl::Pass::get_type_enum(); ccl::ustring passType; @@ -385,6 +384,7 @@ class CyclesOutput : public IECore::RefCounted std::string m_data; bool m_denoise; bool m_interactive; + bool m_viewport; bool m_lightgroup; }; @@ -2477,6 +2477,7 @@ IECore::InternedString g_backgroundShaderOptionName( "cycles:background:shader" // IECore::InternedString g_useFrameAsSeedOptionName( "cycles:integrator:useFrameAsSeed" ); IECore::InternedString g_seedOptionName( "cycles:integrator:seed" ); +IECore::InternedString g_useDenoiseOptionName( "cycles:integrator:use_denoise" ); ccl::PathRayFlag nameToRayType( const std::string &name ) { @@ -3055,6 +3056,12 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer { integrator->set_default_value( *input ); } + + if( name == g_useDenoiseOptionName ) + { + m_outputsChanged = true; + } + return; } else if( boost::starts_with( name.string(), "cycles:" ) ) @@ -3528,7 +3535,6 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer InternedString cryptoObject; InternedString cryptoMaterial; bool hasShadowCatcher = false; - bool hasDenoise = false; for( auto &coutput : m_outputs ) { if( ( m_renderType != Interactive && coutput.second->m_interactive ) || @@ -3569,12 +3575,20 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer } bool denoise = coutput.second->m_denoise; - hasDenoise |= denoise; std::string name = denoise ? ccl::string_printf( "%s_denoised", coutput.second->m_data.c_str() ) : coutput.second->m_data; ccl::Pass *pass = m_scene->create_node(); pass->set_type( passType ); pass->set_name( ccl::ustring( name ) ); - pass->set_mode( denoise ? ccl::PassMode::DENOISED : ccl::PassMode::NOISY ); + + // Allow the viewport to have a denoiser applied to default rgba pass. + if( m_scene->integrator->get_use_denoise() && passType == ccl::PASS_COMBINED && coutput.second->m_viewport ) + { + pass->set_mode( ccl::PassMode::DENOISED ); + } + else + { + pass->set_mode( denoise ? ccl::PassMode::DENOISED : ccl::PassMode::NOISY ); + } const IECore::CompoundDataPtr layer = coutput.second->m_parameters->copy(); layersData->writable()[name] = layer; @@ -3655,7 +3669,6 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer continue; bool denoise = coutput.second->m_denoise; - hasDenoise |= denoise; std::string name = denoise ? ccl::string_printf( "%s_denoised", coutput.second->m_data.c_str() ) : coutput.second->m_data; ccl::Pass *pass = m_scene->create_node(); pass->set_type( passType ); @@ -3681,7 +3694,6 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer film->set_cryptomatte_passes( crypto ); film->set_use_approximate_shadow_catcher( !hasShadowCatcher ); - m_scene->integrator->set_use_denoise( hasDenoise ); if( m_renderType == Interactive ) m_session->set_output_driver( ccl::make_unique( displayWindow, dataWindow, paramData ) ); else diff --git a/startup/gui/cyclesViewerSettings.gfr b/startup/gui/cyclesViewerSettings.gfr index e374e0c5b48..f31ff48f260 100644 --- a/startup/gui/cyclesViewerSettings.gfr +++ b/startup/gui/cyclesViewerSettings.gfr @@ -8,7 +8,7 @@ import imath Gaffer.Metadata.registerValue( parent, "serialiser:milestoneVersion", 1, persistent=False ) Gaffer.Metadata.registerValue( parent, "serialiser:majorVersion", 1, persistent=False ) -Gaffer.Metadata.registerValue( parent, "serialiser:minorVersion", 0, persistent=False ) +Gaffer.Metadata.registerValue( parent, "serialiser:minorVersion", 2, persistent=False ) Gaffer.Metadata.registerValue( parent, "serialiser:patchVersion", 0, persistent=False ) __children = {} @@ -113,7 +113,12 @@ __children["ViewerSettings"]["convert_float_to_vector"].addChild( Gaffer.V2fPlug __children["ViewerSettings"].addChild( GafferCycles.CyclesShader( "attribute" ) ) __children["ViewerSettings"]["attribute"].loadShader( "attribute" ) __children["ViewerSettings"]["attribute"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) -parent["variables"]["imageCataloguePort"]["value"].setValue( 46035 ) +__children["ViewerSettings"].addChild( Gaffer.NameValuePlug( "cycles:session:samples", Gaffer.IntPlug( "value", defaultValue = 64, ), False, "options_samples", Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) +__children["ViewerSettings"].addChild( GafferCycles.CyclesOptions( "DenoiseOptions" ) ) +__children["ViewerSettings"]["DenoiseOptions"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) +__children["ViewerSettings"].addChild( Gaffer.NameValuePlug( "cycles:integrator:denoise_start_sample", Gaffer.IntPlug( "value", defaultValue = 8, ), False, "options_denoiseStartSample", Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic ) ) +__children["ViewerSettings"].addChild( Gaffer.BoolPlug( "EnableDenoiser", defaultValue = False, flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) +parent["variables"]["imageCataloguePort"]["value"].setValue( 43867 ) Gaffer.Metadata.registerValue( parent["variables"]["imageCataloguePort"], 'readOnly', True ) Gaffer.Metadata.registerValue( parent["variables"]["projectName"]["name"], 'readOnly', True ) Gaffer.Metadata.registerValue( parent["variables"]["projectRootDirectory"]["name"], 'readOnly', True ) @@ -123,7 +128,7 @@ Gaffer.Metadata.registerValue( __children["ViewerSettings"], 'noduleLayout:custo Gaffer.Metadata.registerValue( __children["ViewerSettings"], 'noduleLayout:customGadget:addButtonRight:visible', False ) Gaffer.Metadata.registerValue( __children["ViewerSettings"], 'uiEditor:emptySections', IECore.StringVectorData( [ ] ) ) Gaffer.Metadata.registerValue( __children["ViewerSettings"], 'uiEditor:emptySectionIndices', IECore.IntVectorData( [ ] ) ) -__children["ViewerSettings"]["__uiPosition"].setValue( imath.V2f( -8.1733408, 7.41429186 ) ) +__children["ViewerSettings"]["__uiPosition"].setValue( imath.V2f( -7.47334099, 11.5142927 ) ) __children["ViewerSettings"]["BoxIn"]["__in"].setInput( __children["ViewerSettings"]["in"] ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["BoxIn"]["__in"], 'nodule:color', imath.Color3f( 0.240099996, 0.339399993, 0.485000014 ) ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["BoxIn"]["__in"], 'layout:section', 'Settings' ) @@ -227,13 +232,12 @@ __children["ViewerSettings"]["DisableDisplacement"]["__uiPosition"].setValue( im __children["ViewerSettings"]["Expression3"]["__in"]["p0"].setInput( __children["ViewerSettings"]["enableDisplacement"] ) __children["ViewerSettings"]["Expression3"]["__uiPosition"].setValue( imath.V2f( -16.1448822, -112.487854 ) ) __children["ViewerSettings"]["SamplingOptions"]["in"].setInput( __children["ViewerSettings"]["DisableDisplacement"]["out"] ) -__children["ViewerSettings"]["SamplingOptions"]["options"]["samples"]["value"].setValue( 64 ) -__children["ViewerSettings"]["SamplingOptions"]["options"]["samples"]["enabled"].setValue( True ) __children["ViewerSettings"]["SamplingOptions"]["options"]["causticsReflective"]["value"].setValue( False ) __children["ViewerSettings"]["SamplingOptions"]["options"]["causticsReflective"]["enabled"].setValue( True ) __children["ViewerSettings"]["SamplingOptions"]["options"]["causticsRefractive"]["value"].setValue( False ) __children["ViewerSettings"]["SamplingOptions"]["options"]["causticsRefractive"]["enabled"].setValue( True ) __children["ViewerSettings"]["SamplingOptions"]["options"]["useAdaptiveSampling"]["enabled"].setValue( True ) +__children["ViewerSettings"]["SamplingOptions"]["options"]["samples"].setInput( __children["ViewerSettings"]["options_samples"] ) __children["ViewerSettings"]["SamplingOptions"]["__uiPosition"].setValue( imath.V2f( -4.19273949, -124.976883 ) ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["DisableSubdivision"], 'annotation:user:text', 'For now subdivision is always disabled as Cycles out of the box only can support adaptive, Blender normally supplies an already uniform subdivided model from a modifier.' ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["DisableSubdivision"], 'annotation:user:color', imath.Color3f( 0.150000006, 0.25999999, 0.25999999 ) ) @@ -256,7 +260,9 @@ Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'n Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'plugValueWidget:type', 'GafferUI.PresetsPlugValueWidget' ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'preset:OSL', 'OSL' ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'preset:SVM', 'SVM' ) -__children["ViewerSettings"]["CyclesOptions"]["in"].setInput( __children["ViewerSettings"]["ShadingSystem"]["out"] ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'layout:section', 'Settings' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["shadingSystem"], 'layout:index', 5 ) +__children["ViewerSettings"]["CyclesOptions"]["in"].setInput( __children["ViewerSettings"]["DenoiseOptions"]["out"] ) __children["ViewerSettings"]["CyclesOptions"]["options"]["textureLimit"]["enabled"].setValue( True ) __children["ViewerSettings"]["CyclesOptions"]["options"]["textureLimit"]["value"].setInput( __children["ViewerSettings"]["Expression5"]["__out"]["p0"] ) __children["ViewerSettings"]["CyclesOptions"]["__uiPosition"].setValue( imath.V2f( -4.19273949, -151.521561 ) ) @@ -272,6 +278,8 @@ Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], 'preset:2048', 5 ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], 'preset:4096', 6 ) Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], 'preset:8192', 7 ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], 'layout:section', 'Settings' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["textureSizeLimit"], 'layout:index', 6 ) __children["ViewerSettings"]["object_info"]["__uiPosition"].setValue( imath.V2f( -69.403717, 17.8482647 ) ) __children["ViewerSettings"]["diffuse_bsdf"]["parameters"]["color"].setInput( __children["ViewerSettings"]["object_info"]["out"]["color"] ) __children["ViewerSettings"]["diffuse_bsdf"]["__uiPosition"].setValue( imath.V2f( 17.4492283, 17.8482647 ) ) @@ -296,6 +304,42 @@ __children["ViewerSettings"]["convert_float_to_vector"]["parameters"]["value_flo __children["ViewerSettings"]["convert_float_to_vector"]["__uiPosition"].setValue( imath.V2f( -72.9163971, -6.86891985 ) ) __children["ViewerSettings"]["attribute"]["parameters"]["attribute"].setValue( 'Cs' ) __children["ViewerSettings"]["attribute"]["__uiPosition"].setValue( imath.V2f( -69.4365692, 27.8806839 ) ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'spreadsheet:plugMenu:includeAsAncestor', True ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'spreadsheet:plugMenu:ancestorLabel', 'Value and Switch' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'spreadsheet:columnName', 'samples' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'nameValuePlugPlugValueWidget:ignoreNamePlug', True ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'description', 'Number of samples to render for each pixel. This is for the\npath integrator, use the other sampling parameters for the\nbranched-path integrator.' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'label', 'Samples' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'deletable', False ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'layout:section', 'Settings' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"], 'layout:index', 7 ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"]["value"], 'spreadsheet:columnName', 'samplesValue' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_samples"]["enabled"], 'spreadsheet:columnName', 'samplesEnabled' ) +__children["ViewerSettings"]["DenoiseOptions"]["enabled"].setInput( __children["ViewerSettings"]["EnableDenoiser"] ) +__children["ViewerSettings"]["DenoiseOptions"]["in"].setInput( __children["ViewerSettings"]["ShadingSystem"]["out"] ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["useDenoise"]["value"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["useDenoise"]["enabled"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["denoiserType"]["enabled"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["useDenoisePassAlbedo"]["enabled"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["useDenoisePassNormal"]["enabled"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["denoiserPrefilter"]["value"].setValue( 'fast' ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["denoiserPrefilter"]["enabled"].setValue( True ) +__children["ViewerSettings"]["DenoiseOptions"]["options"]["denoiseStartSample"].setInput( __children["ViewerSettings"]["options_denoiseStartSample"] ) +__children["ViewerSettings"]["DenoiseOptions"]["__uiPosition"].setValue( imath.V2f( -4.19273949, -143.357498 ) ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'spreadsheet:plugMenu:includeAsAncestor', True ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'spreadsheet:plugMenu:ancestorLabel', 'Value and Switch' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'spreadsheet:columnName', 'denoiseStartSample' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'nameValuePlugPlugValueWidget:ignoreNamePlug', True ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'description', 'Sample to start denoising the preview at.' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'label', 'Denoising Start Sample' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'deletable', False ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'layout:section', 'Settings' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"], 'layout:index', 9 ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"]["value"], 'spreadsheet:columnName', 'denoiseStartSampleValue' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["options_denoiseStartSample"]["enabled"], 'spreadsheet:columnName', 'denoiseStartSampleEnabled' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["EnableDenoiser"], 'nodule:type', '' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["EnableDenoiser"], 'layout:section', 'Settings' ) +Gaffer.Metadata.registerValue( __children["ViewerSettings"]["EnableDenoiser"], 'layout:index', 8 ) __children["ViewerSettings"]["Expression3"]["__engine"].setValue( 'OSL' ) __children["ViewerSettings"]["Expression3"]["__expression"].setValue( 'parent.__out.p0 = !parent.__in.p0;' ) __children["ViewerSettings"]["Expression5"]["__engine"].setValue( 'OSL' )