Skip to content

Commit 8234549

Browse files
Merge pull request #1507 from johnhaddon/shaderNetworkRenderAdaptors
ShaderNetworkAlgo : Add render adaptor API
2 parents 4ea418e + 20dc146 commit 8234549

File tree

4 files changed

+127
-3
lines changed

4 files changed

+127
-3
lines changed

Changes

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
10.6.x.x (relative to 10.6.2.2)
22
========
33

4+
Improvements
5+
------------
6+
7+
- ShaderNetworkAlgo : Added render adaptor API, allowing just-in-time modifications to
8+
ShaderNetworks during translation for rendering.
9+
410
10.6.2.2
511
========
612

SConstruct

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,12 @@
4141
#
4242
##########################################################################
4343

44-
import SCons
45-
import shutil
4644
import glob
4745
import sys
4846
import os
4947
import re
5048
import subprocess
5149
import platform
52-
import distutils
5350

5451
EnsureSConsVersion( 3, 0, 2 ) # Substfile is a default builder as of 3.0.2
5552
SConsignFile()

include/IECoreScene/ShaderNetworkAlgo.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,38 @@ IECORESCENE_API IECore::ConstCompoundDataPtr collapseSplineParameters( const IEC
156156
/// different spline conventions for different renderers' shader libraries
157157
IECORESCENE_API IECore::ConstCompoundDataPtr expandSplineParameters( const IECore::ConstCompoundDataPtr& parametersData );
158158

159+
/// Render Adaptors
160+
/// ===============
161+
///
162+
/// Render adaptors are functions called to make "just in time" modifications to
163+
/// shader networks prior to rendering. They have access to a fully resolved
164+
/// attribute state, which can be used to drive the modifications. There is currently
165+
/// a single built-in adaptor, which uses `ShaderNetworkAlgo::applySubstitutions()`
166+
/// to allow strings such as texture paths to be substituted in from attributes that
167+
/// define them.
168+
///
169+
/// Adaptors are performance critical, so are deliberately not available via
170+
/// the Python API. They must be implemented in C++ only.
171+
172+
/// A function that adapts the shader network for rendering, given the full
173+
/// inherited `attributes` for an object. Must be threadsafe.
174+
using RenderAdaptorFunction = void (*)( ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes );
175+
/// A function that appends to `hash` to uniquely identify the work that will be
176+
/// performed by an AdaptorFunction. Particular attention must be paid to
177+
/// the performance of any such function, as it will be called frequently. If an
178+
/// adaptor will be a no-op, then nothing should be appended to the hash.
179+
/// Must be threadsafe.
180+
using RenderAdaptorHashFunction = void (*)( const ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash );
181+
182+
/// Registers an adaptor.
183+
IECORESCENE_API void registerRenderAdaptor( const std::string &name, RenderAdaptorHashFunction hashFunction, RenderAdaptorFunction adaptorFunction );
184+
/// Removes a previously registered adaptor with the specified name.
185+
IECORESCENE_API void deregisterRenderAdaptor( const std::string &name );
186+
187+
/// Hashes all the currently registered adaptors for `shaderNetwork`.
188+
IECORESCENE_API void hashRenderAdaptors( const ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash );
189+
/// Applies all the currently registered adaptors to `shaderNetwork`.
190+
IECORESCENE_API void applyRenderAdaptors( ShaderNetwork *shaderNetwork, IECore::InternedString attributeName, const IECore::CompoundObject *attributes );
159191

160192
} // namespace ShaderNetworkAlgo
161193

src/IECoreScene/ShaderNetworkAlgo.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,3 +1472,92 @@ IECore::ConstCompoundDataPtr ShaderNetworkAlgo::expandSplineParameters( const IE
14721472
return parametersData;
14731473
}
14741474
}
1475+
1476+
1477+
//////////////////////////////////////////////////////////////////////////
1478+
// Render Adaptors
1479+
//////////////////////////////////////////////////////////////////////////
1480+
1481+
namespace
1482+
{
1483+
1484+
struct RenderAdaptor
1485+
{
1486+
std::string name;
1487+
IECoreScene::ShaderNetworkAlgo::RenderAdaptorHashFunction hash;
1488+
IECoreScene::ShaderNetworkAlgo::RenderAdaptorFunction apply;
1489+
};
1490+
1491+
using RenderAdaptors = std::vector<RenderAdaptor>;
1492+
RenderAdaptors &renderAdaptors()
1493+
{
1494+
static RenderAdaptors g_renderAdaptors;
1495+
return g_renderAdaptors;
1496+
}
1497+
1498+
bool g_stringSubstitutionsRegistration = [] () {
1499+
1500+
IECoreScene::ShaderNetworkAlgo::registerRenderAdaptor(
1501+
"stringSubstitution",
1502+
// Hash
1503+
[] ( const IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash ) {
1504+
shaderNetwork->hashSubstitutions( attributes, hash );
1505+
},
1506+
// Apply
1507+
[] ( IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes ) {
1508+
shaderNetwork->applySubstitutions( attributes );
1509+
}
1510+
);
1511+
1512+
return true;
1513+
} ();
1514+
1515+
} // namespace
1516+
1517+
void ShaderNetworkAlgo::registerRenderAdaptor( const std::string &name, RenderAdaptorHashFunction hashFunction, RenderAdaptorFunction adaptorFunction )
1518+
{
1519+
// Replace existing adaptor if it exists.
1520+
RenderAdaptors &a = renderAdaptors();
1521+
for( auto &x : a )
1522+
{
1523+
if( x.name == name )
1524+
{
1525+
x.hash = hashFunction;
1526+
x.apply = adaptorFunction;
1527+
return;
1528+
}
1529+
}
1530+
// Otherwise add new adaptor.
1531+
a.push_back( { name, hashFunction, adaptorFunction } );
1532+
}
1533+
1534+
void ShaderNetworkAlgo::deregisterRenderAdaptor( const std::string &name )
1535+
{
1536+
RenderAdaptors &a = renderAdaptors();
1537+
a.erase(
1538+
std::remove_if(
1539+
a.begin(),
1540+
a.end(),
1541+
[&] ( const RenderAdaptor &x ) {
1542+
return x.name == name;
1543+
}
1544+
),
1545+
a.end()
1546+
);
1547+
}
1548+
1549+
void ShaderNetworkAlgo::hashRenderAdaptors( const IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes, IECore::MurmurHash &hash )
1550+
{
1551+
for( const auto &x : renderAdaptors() )
1552+
{
1553+
x.hash( shaderNetwork, attributeName, attributes, hash );
1554+
}
1555+
}
1556+
1557+
void ShaderNetworkAlgo::applyRenderAdaptors( IECoreScene::ShaderNetwork *shaderNetwork, InternedString attributeName, const IECore::CompoundObject *attributes )
1558+
{
1559+
for( const auto &x : renderAdaptors() )
1560+
{
1561+
x.apply( shaderNetwork, attributeName, attributes );
1562+
}
1563+
}

0 commit comments

Comments
 (0)