GafferHQ / gaffer

Gaffer is a node-based application for lookdev, lighting and automation
http://www.gafferhq.org
BSD 3-Clause "New" or "Revised" License
950 stars 205 forks source link

Cryptomatte from Blender 3.x/4.x is not Displayed in Viewer #5866

Closed aditiapratama closed 3 months ago

aditiapratama commented 3 months ago

Version: Gaffer 1.4.X.X-(linux, windows) Third-party tools: None Third-party modules: None

Description

I have EXR with cryptomatte generated from blender 3.6 LTS and also 4.1.1. Whenever I load it and put cryptomatte node, the Viewer will stay black. However I have another EXR with crypto from blender 2.93 LTS, it will load just fine.

I attached both exr and blend files.

image image

Steps to reproduce

  1. Download EXR files from here https://1drv.ms/f/s!AipTDeE9i3xFh8401PPddxldrzu5Sw?e=XE6EDa
  2. drag and drop into Gaffer
  3. add cryptomatte node to both of the files
  4. try change layer selection
  5. notice that Viewer will stay black if using exr generated from blender 3 and above

Debug log

Click to Expand

``` ```

johnhaddon commented 3 months ago

To me it looks like there are a few different things going on here :

If you copy-paste the script below into Gaffer, you should see that things can be made to work if those problems are corrected.

``` import Gaffer import GafferImage import GafferScene import IECore import imath Gaffer.Metadata.registerValue( parent, "serialiser:milestoneVersion", 1, persistent=False ) Gaffer.Metadata.registerValue( parent, "serialiser:majorVersion", 4, persistent=False ) Gaffer.Metadata.registerValue( parent, "serialiser:minorVersion", 3, persistent=False ) Gaffer.Metadata.registerValue( parent, "serialiser:patchVersion", 0, persistent=False ) __children = {} __children["with_z_b41_0001"] = GafferImage.ImageReader( "with_z_b41_0001" ) parent.addChild( __children["with_z_b41_0001"] ) __children["with_z_b41_0001"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["Cryptomatte"] = GafferScene.Cryptomatte( "Cryptomatte" ) parent.addChild( __children["Cryptomatte"] ) __children["Cryptomatte"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["Shuffle"] = GafferImage.Shuffle( "Shuffle" ) parent.addChild( __children["Shuffle"] ) __children["Shuffle"]["shuffles"].addChild( Gaffer.ShufflePlug( "shuffle0", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["Shuffle"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["Expression"] = Gaffer.Expression( "Expression" ) parent.addChild( __children["Expression"] ) __children["Expression"]["__out"].addChild( Gaffer.StringPlug( "p0", direction = Gaffer.Plug.Direction.Out, defaultValue = '', flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, substitutions = IECore.StringAlgo.Substitutions.NoSubstitutions ) ) __children["Expression"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["Constant"] = GafferImage.Constant( "Constant" ) parent.addChild( __children["Constant"] ) __children["Constant"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["CopyChannels"] = GafferImage.CopyChannels( "CopyChannels" ) parent.addChild( __children["CopyChannels"] ) __children["CopyChannels"]["in"].addChild( GafferImage.ImagePlug( "in2", flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["CopyChannels"].addChild( Gaffer.V2fPlug( "__uiPosition", defaultValue = imath.V2f( 0, 0 ), flags = Gaffer.Plug.Flags.Default | Gaffer.Plug.Flags.Dynamic, ) ) __children["with_z_b41_0001"]["fileName"].setValue( '/home/john/Downloads/cryptomatte/with_z_b41_0001.exr' ) __children["with_z_b41_0001"]["__uiPosition"].setValue( imath.V2f( 18.1511688, 33.2099152 ) ) Gaffer.Metadata.registerValue( __children["Cryptomatte"], 'annotation:user:text', 'With all those fixes applied, the Cryptomatte node can recognise the input and generate a matte appropriately.' ) Gaffer.Metadata.registerValue( __children["Cryptomatte"], 'annotation:user:color', imath.Color3f( 0.150000006, 0.25999999, 0.25999999 ) ) __children["Cryptomatte"]["in"].setInput( __children["CopyChannels"]["out"] ) __children["Cryptomatte"]["layer"].setValue( 'ViewLayer.CryptoObject' ) __children["Cryptomatte"]["matteNames"].setValue( IECore.StringVectorData( [ '/Cube', '' ] ) ) __children["Cryptomatte"]["__uiPosition"].setValue( imath.V2f( 21.1511688, 2.11772776 ) ) Gaffer.Metadata.registerValue( __children["Shuffle"], 'annotation:user:text', 'The EXR from Blender is malformed, with channels using lower-case names `r`, `g`, `b` etc instead of the expected upper-case names `R`, `G`, `B`. The Shuffle node fixes that.' ) Gaffer.Metadata.registerValue( __children["Shuffle"], 'annotation:user:color', imath.Color3f( 0.150000006, 0.25999999, 0.25999999 ) ) __children["Shuffle"]["in"].setInput( __children["with_z_b41_0001"]["out"] ) __children["Shuffle"]["shuffles"]["shuffle0"]["source"].setValue( '*.[rgba]' ) __children["Shuffle"]["shuffles"]["shuffle0"]["deleteSource"].setValue( True ) Gaffer.Metadata.registerValue( __children["Shuffle"]["shuffles"]["shuffle0"]["source"], 'channelPlugValueWidget:isCustom', True ) __children["Shuffle"]["shuffles"]["shuffle0"]["destination"].setInput( __children["Expression"]["__out"]["p0"] ) Gaffer.Metadata.registerValue( __children["Shuffle"]["shuffles"]["shuffle0"]["destination"], 'channelPlugValueWidget:isCustom', True ) __children["Shuffle"]["__uiPosition"].setValue( imath.V2f( 18.1511688, 25.0458527 ) ) __children["Expression"]["__uiPosition"].setValue( imath.V2f( 7.6503315, 25.0460129 ) ) __children["Constant"]["__uiPosition"].setValue( imath.V2f( 36.8500023, 18.4458523 ) ) Gaffer.Metadata.registerValue( __children["CopyChannels"], 'annotation:user:text', 'The Cryptomatte node seems to have a bug triggered by not having RGBA channels in the input. Copy in some channels to keep it happy.' ) Gaffer.Metadata.registerValue( __children["CopyChannels"], 'annotation:user:color', imath.Color3f( 0.150000006, 0.25999999, 0.25999999 ) ) __children["CopyChannels"]["in"][0].setInput( __children["Shuffle"]["out"] ) __children["CopyChannels"]["in"][1].setInput( __children["Constant"]["out"] ) __children["CopyChannels"]["channels"].setValue( '*' ) __children["CopyChannels"]["__uiPosition"].setValue( imath.V2f( 21.1511688, 10.2817898 ) ) __children["Expression"]["__engine"].setValue( 'python' ) __children["Expression"]["__expression"].setValue( 'source = context.get( "source", "" )\ndest = source.replace( ".r", ".R" )\ndest = dest.replace( ".g", ".G" )\ndest = dest.replace( ".b", ".B" )\ndest = dest.replace( ".a", ".A" )\n\nparent["__out"]["p0"] = dest' ) del __children ```

I think it's probably worth us tweaking the ImageReader so that it can conform the non-standard lowercase channels automatically - we already have loads of heuristics for dealing with dodgy EXRs from other sources. And we should fix the Cryptomatte problem too. But ideally you'd be able to get the output from Blender formatted in a more standard way as well...

johnhaddon commented 3 months ago

The EXR file out of Blender has non-standard channel names, with lowercase .r, .g etc where there should be uppercase .R, .B etc.

Actually, I see now that the Cryptomatte specification says lowercase, but that conflicts with the EXR specification, which says uppercase... :shrug:

johnhaddon commented 3 months ago

I've opened PR #5867 with the Cryptomatte fix, and #5868 with a workaround for lowercase names not conforming to the EXR spec.

aditiapratama commented 3 months ago

Thank you @johnhaddon ,

Anyway I tried to run the python script but it complained about parent not defined...so I set parent = root and it works, but not sure if it's the correct way .

Also I tried using shuffle and copied your python expression, but it's not working as well.

I tried using the plugs and it works if manually setup.

johnhaddon commented 3 months ago

Anyway I tried to run the python script but it complained about parent not defined

If you paste it directly into the Graph Editor it should work.

aditiapratama commented 3 months ago

Ah yes..it's working image

Thank you @johnhaddon