Skip to content

Commit

Permalink
IECoreUSD::ShaderAlgo : Round-trip ColorSpace data on shader parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Fuller committed Feb 28, 2025
1 parent 0b88aa4 commit 4682aff
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
10.5.x.x (relative to 10.5.13.0)
========

Features
--------

- IECoreUSD::ShaderAlgo : Round-trip ColorSpace data that is stored on USD Attributes by storing an additional parameter with the `_colorspace` suffix.

10.5.13.0 (relative to 10.5.12.0)
=========
Expand Down
28 changes: 28 additions & 0 deletions contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( valueAttribute ) ) )
{
parameters[fromUSDParameterName( i.GetBaseName() )] = d;
// If there's colorspace data on the parameter, we can store this as
// `<name>_colorspace`, this is how MaterialX stores colorspace on
// generated OSL nodes so we match here the same behaviour.
if( pxr::UsdAttribute( valueAttribute ).HasColorSpace() )
{
const IECore::InternedString colorSpace = pxr::UsdAttribute( valueAttribute ).GetColorSpace().GetString();
const IECore::InternedString paramName =
( boost::format( "%s_colorspace" ) % fromUSDParameterName( i.GetBaseName() ).string() ).str();
parameters[paramName] = colorSpace;
}
}
}

Expand Down Expand Up @@ -334,6 +344,13 @@ void writeShaderParameterValues( const IECoreScene::Shader *shader, pxr::UsdShad
continue;
}

// Skip colorspace parameters, these will be set using SetColorSpace() on the
// USD attribue that it corresponds to.
if( boost::ends_with( p.first.string(), "_colorspace" ) )
{
continue;
}

const pxr::TfToken usdParameterName = toUSDParameterName( p.first );
pxr::UsdShadeInput input = usdShader.GetInput( usdParameterName );
if( !input )
Expand Down Expand Up @@ -364,6 +381,17 @@ void writeShaderParameterValues( const IECoreScene::Shader *shader, pxr::UsdShad
}
}
input.Set( IECoreUSD::DataAlgo::toUSD( p.second.get() ) );

// Make sure to set any colorspace parameters onto the attribute
// if any exist.
auto it = shader->parameters().find( ( boost::format( "%s_colorspace" ) % p.first.string() ).str() );
if( it != shader->parameters().end() )
{
if( auto *s = IECore::runTimeCast<IECore::InternedStringData>( it->second.get() ) )
{
pxr::UsdAttribute( input ).SetColorSpace( pxr::TfToken( s->readable().string() ) );
}
}
}

if( shader->blindData()->readable().size() )
Expand Down
12 changes: 12 additions & 0 deletions contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2877,6 +2877,7 @@ def testShaders( self ) :

texture = IECoreScene.Shader( "texture", "ai:shader" )
texture.parameters["filename"] = IECore.StringData( "sometexture.tx" )
texture.parameters["filename_colorspace"] = IECore.InternedStringData( "ACEScg" )

oneShaderNetwork = IECoreScene.ShaderNetwork()
oneShaderNetwork.addShader( "foo", surface )
Expand Down Expand Up @@ -3064,6 +3065,8 @@ def testShaders( self ) :
textureUsd = pxr.UsdShade.Shader( add1Source[0].GetPrim() )
self.assertEqual( textureUsd.GetShaderId(), "arnold:texture" )
self.assertEqual( textureUsd.GetInput( "filename" ).Get(), "sometexture.tx" )
self.assertEqual( add1Source[0].GetPrim().GetAttribute( "inputs:filename" ).GetColorSpace(), "ACEScg" )
self.assertIsNone( textureUsd.GetInput( "filename_colorspace" ) )


# Read via SceneInterface, and check that we've round-tripped successfully.
Expand Down Expand Up @@ -3340,6 +3343,15 @@ def testTextureParameters( self ) :
os.path.normcase( os.path.normpath( network.getShader( "udimTexture" ).parameters["file"].value ) ),
os.path.normcase( os.path.normpath( "/full/path/to/myTexture.<UDIM>.tx" ) )
)
self.assertEqual(
network.getShader( "relativeTexture" ).parameters["file_colorspace"].value, "ACEScg"
)
self.assertEqual(
network.getShader( "relativeUDIMTexture" ).parameters["file_colorspace"].value, "lin_rec709_scene"
)
self.assertEqual(
network.getShader( "udimTexture" ).parameters["file_colorspace"].value, "srgb_rec709_scene"
)

def testExposedShaderInput( self ) :

Expand Down
12 changes: 9 additions & 3 deletions contrib/IECoreUSD/test/IECoreUSD/data/textureParameters.usda
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,28 @@ def "model"
def Shader "relativeTexture"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @../myTexture.tx@
asset inputs:file = @../myTexture.tx@ (
colorSpace = "ACEScg"
)
vector3f outputs:rgb
}

def Shader "relativeUDIMTexture"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @../myTexture.<UDIM>.tx@
asset inputs:file = @../myTexture.<UDIM>.tx@ (
colorSpace = "lin_rec709_scene"
)
vector3f outputs:rgb

}

def Shader "udimTexture"
{
uniform token info:id = "UsdUVTexture"
asset inputs:file = @/full/path/to/myTexture.<UDIM>.tx@
asset inputs:file = @/full/path/to/myTexture.<UDIM>.tx@ (
colorSpace = "srgb_rec709_scene"
)
float outputs:r
}
}
Expand Down

0 comments on commit 4682aff

Please sign in to comment.