Skip to content

Commit

Permalink
fixup! IECoreArnold : Support NODE * shader parameters
Browse files Browse the repository at this point in the history
In batch renders, the `refCount()` on the shaders in the cache will always be 1, because we don't keep a hold of the ObjectInterfacePtr for the objects referencing the shaders. This meant we weren't updating NodeParameters at all during batch renders.
  • Loading branch information
johnhaddon committed Nov 14, 2023
1 parent 62c70e5 commit 8aeb91e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
41 changes: 40 additions & 1 deletion python/IECoreArnoldTest/RendererTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4237,7 +4237,7 @@ def testDiffuseAndSpecularDepthDefaults( self ) :
self.assertEqual( arnold.AiNodeGetInt( options, "GI_diffuse_depth" ), 2 )
self.assertEqual( arnold.AiNodeGetInt( options, "GI_specular_depth" ), 2 )

def testNodeParameters( self ) :
def testInteractiveNodeParameters( self ) :

# Make renderer with two cameras

Expand Down Expand Up @@ -4357,6 +4357,45 @@ def assertCameraParameter( renderer, cameraName ) :
del camera1, cameraAttributes, plane
del renderer

def testBatchNodeParameters( self ) :

# Render a camera projection setup to an ASS file.

renderer = GafferScene.Private.IECoreScenePreview.Renderer.create(
"Arnold",
GafferScene.Private.IECoreScenePreview.Renderer.RenderType.SceneDescription,
str( self.temporaryDirectory() / "test.ass" )
)

renderer.camera( "/camera", IECoreScene.Camera(), renderer.attributes( IECore.CompoundObject() ) )

shaderNetwork = IECoreScene.ShaderNetwork(
shaders = {
"output" : IECoreScene.Shader(
"camera_projection", "ai:surface",
{ "camera" : IECore.StringData( "/camera" ) }
)
},
output = ( "output", "" )
)

renderer.object(
"/plane",
IECoreScene.MeshPrimitive.createPlane( imath.Box2f( imath.V2f( -1 ), imath.V2f( 1 ) ) ),
renderer.attributes( IECore.CompoundObject( { "ai:surface" : shaderNetwork } ) )
)
renderer.render()

# Check we got what we wanted.

with IECoreArnold.UniverseBlock( writable = True ) as universe :

arnold.AiSceneLoad( universe, str( self.temporaryDirectory() / "test.ass" ), None )
planeNode = arnold.AiNodeLookUpByName( universe, "/plane" )
planeShader = arnold.AiNodeGetPtr( planeNode, "shader" )
cameraNode = arnold.AiNodeGetPtr( planeShader, "camera" )
self.assertEqual( arnold.AiNodeGetName( cameraNode ), "/camera" )

@staticmethod
def __m44f( m ) :

Expand Down
17 changes: 10 additions & 7 deletions src/IECoreArnold/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,15 +869,16 @@ class ShaderCache : public IECore::RefCounted
return writeAccessor->second;
}

// _Must_ be called before `render()` launches Arnold, and must not be called concurrently with anything.
// This removed shaders that are no longer in use, and ensures all `ShaderNetworkAlgo::NodeParameters`
// are updated appropriately.
void preRender()
// _Must_ be called before `render()` launches Arnold, and must not be
// called concurrently with anything. This removed shaders that are no
// longer in use during interactive renders, and ensures all
// `ShaderNetworkAlgo::NodeParameters` are updated appropriately.
void preRender( IECoreScenePreview::Renderer::RenderType renderType )
{
vector<IECore::MurmurHash> toErase;
for( Cache::iterator it = m_cache.begin(), eIt = m_cache.end(); it != eIt; ++it )
{
if( it->second->refCount() == 1 )
if( renderType == IECoreScenePreview::Renderer::RenderType::Interactive && it->second->refCount() == 1 )
{
// Only one reference - this is ours, so
// nothing outside of the cache is using the
Expand Down Expand Up @@ -3273,6 +3274,8 @@ class ArnoldGlobals

AtUniverse *universe() { return m_universeBlock->universe(); }

IECoreScenePreview::Renderer::RenderType renderType() const { return m_renderType; }

void option( const IECore::InternedString &name, const IECore::Object *value )
{
AtNode *options = AiUniverseGetOptions( m_universeBlock->universe() );
Expand Down Expand Up @@ -3707,7 +3710,7 @@ class ArnoldGlobals
AiNodeResetParameter( options, g_subdivDicingCameraString );
}

m_shaderCache->preRender();
m_shaderCache->preRender( m_renderType );

// Do the appropriate render based on
// m_renderType.
Expand Down Expand Up @@ -4335,7 +4338,7 @@ class ArnoldRenderer final : public ArnoldRendererBase
{
const IECore::MessageHandler::Scope s( m_messageHandler.get() );

m_shaderCache->preRender();
m_shaderCache->preRender( m_globals->renderType() );
m_instanceCache->clearUnused();
m_globals->render();
}
Expand Down

0 comments on commit 8aeb91e

Please sign in to comment.