Skip to content

Commit 9c4b8e5

Browse files
author
Alex Fuller
committed
IECoreUSD::ShaderAlgo : Round-trip ColorSpace data on shader parameters.
1 parent 0b88aa4 commit 9c4b8e5

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

Changes

+3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
10.5.x.x (relative to 10.5.13.0)
22
========
33

4+
Features
5+
--------
46

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

69
10.5.13.0 (relative to 10.5.12.0)
710
=========

contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,16 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
244244
if( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD( pxr::UsdAttribute( valueAttribute ) ) )
245245
{
246246
parameters[fromUSDParameterName( i.GetBaseName() )] = d;
247+
// If there's colorspace data on the parameter, we can store this as
248+
// `<name>_colorspace`, this is how MaterialX stores colorspace on
249+
// generated OSL nodes so we match here the same behaviour.
250+
if( pxr::UsdAttribute( valueAttribute ).HasColorSpace() )
251+
{
252+
const IECore::InternedString colorSpace( pxr::UsdAttribute( valueAttribute ).GetColorSpace().GetString() );
253+
const IECore::InternedString paramName(
254+
( boost::format( "%s_colorspace" ) % fromUSDParameterName( i.GetBaseName() ).string() ).str() );
255+
parameters[paramName] = new IECore::InternedStringData( colorSpace );
256+
}
247257
}
248258
}
249259

@@ -334,6 +344,13 @@ void writeShaderParameterValues( const IECoreScene::Shader *shader, pxr::UsdShad
334344
continue;
335345
}
336346

347+
// Skip colorspace parameters, these will be set using SetColorSpace() on the
348+
// USD attribue that it corresponds to.
349+
if( boost::ends_with( p.first.string(), "_colorspace" ) )
350+
{
351+
continue;
352+
}
353+
337354
const pxr::TfToken usdParameterName = toUSDParameterName( p.first );
338355
pxr::UsdShadeInput input = usdShader.GetInput( usdParameterName );
339356
if( !input )
@@ -364,6 +381,17 @@ void writeShaderParameterValues( const IECoreScene::Shader *shader, pxr::UsdShad
364381
}
365382
}
366383
input.Set( IECoreUSD::DataAlgo::toUSD( p.second.get() ) );
384+
385+
// Make sure to set any colorspace parameters onto the attribute
386+
// if any exist.
387+
auto it = shader->parameters().find( ( boost::format( "%s_colorspace" ) % p.first.string() ).str() );
388+
if( it != shader->parameters().end() )
389+
{
390+
if( auto *s = IECore::runTimeCast<IECore::InternedStringData>( it->second.get() ) )
391+
{
392+
pxr::UsdAttribute( input ).SetColorSpace( pxr::TfToken( s->readable().string() ) );
393+
}
394+
}
367395
}
368396

369397
if( shader->blindData()->readable().size() )

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

+12
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,7 @@ def testShaders( self ) :
28772877

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

28812882
oneShaderNetwork = IECoreScene.ShaderNetwork()
28822883
oneShaderNetwork.addShader( "foo", surface )
@@ -3064,6 +3065,8 @@ def testShaders( self ) :
30643065
textureUsd = pxr.UsdShade.Shader( add1Source[0].GetPrim() )
30653066
self.assertEqual( textureUsd.GetShaderId(), "arnold:texture" )
30663067
self.assertEqual( textureUsd.GetInput( "filename" ).Get(), "sometexture.tx" )
3068+
self.assertEqual( add1Source[0].GetPrim().GetAttribute( "inputs:filename" ).GetColorSpace(), "ACEScg" )
3069+
self.assertEqual( add1Source[0].GetPrim().HasAttribute( "inputs:filename_colorspace", False ) )
30673070

30683071

30693072
# Read via SceneInterface, and check that we've round-tripped successfully.
@@ -3340,6 +3343,15 @@ def testTextureParameters( self ) :
33403343
os.path.normcase( os.path.normpath( network.getShader( "udimTexture" ).parameters["file"].value ) ),
33413344
os.path.normcase( os.path.normpath( "/full/path/to/myTexture.<UDIM>.tx" ) )
33423345
)
3346+
self.assertEqual(
3347+
network.getShader( "relativeTexture" ).parameters["file_colorspace"].value, "ACEScg"
3348+
)
3349+
self.assertEqual(
3350+
network.getShader( "relativeUDIMTexture" ).parameters["file_colorspace"].value, "lin_rec709_scene"
3351+
)
3352+
self.assertEqual(
3353+
network.getShader( "udimTexture" ).parameters["file_colorspace"].value, "srgb_rec709_scene"
3354+
)
33433355

33443356
def testExposedShaderInput( self ) :
33453357

contrib/IECoreUSD/test/IECoreUSD/data/textureParameters.usda

+9-3
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,28 @@ def "model"
2929
def Shader "relativeTexture"
3030
{
3131
uniform token info:id = "UsdUVTexture"
32-
asset inputs:file = @../myTexture.tx@
32+
asset inputs:file = @../myTexture.tx@ (
33+
colorSpace = "ACEScg"
34+
)
3335
vector3f outputs:rgb
3436
}
3537

3638
def Shader "relativeUDIMTexture"
3739
{
3840
uniform token info:id = "UsdUVTexture"
39-
asset inputs:file = @../myTexture.<UDIM>.tx@
41+
asset inputs:file = @../myTexture.<UDIM>.tx@ (
42+
colorSpace = "lin_rec709_scene"
43+
)
4044
vector3f outputs:rgb
4145

4246
}
4347

4448
def Shader "udimTexture"
4549
{
4650
uniform token info:id = "UsdUVTexture"
47-
asset inputs:file = @/full/path/to/myTexture.<UDIM>.tx@
51+
asset inputs:file = @/full/path/to/myTexture.<UDIM>.tx@ (
52+
colorSpace = "srgb_rec709_scene"
53+
)
4854
float outputs:r
4955
}
5056
}

0 commit comments

Comments
 (0)