Skip to content

Commit

Permalink
TestLight : Use shader as source of parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
ericmehl committed May 9, 2024
1 parent 71cfbcc commit 56fe9e2
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 34 deletions.
16 changes: 16 additions & 0 deletions include/GafferSceneTest/TestLight.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@
#pragma once

#include "GafferSceneTest/Export.h"
#include "GafferSceneTest/TestShader.h"
#include "GafferSceneTest/TypeIds.h"

#include "GafferScene/Light.h"
#include "GafferScene/ShaderPlug.h"

namespace GafferSceneTest
{
Expand All @@ -54,11 +56,25 @@ class GAFFERSCENETEST_API TestLight : public GafferScene::Light

GAFFER_NODE_DECLARE_TYPE( GafferSceneTest::TestLight, TestLightTypeId, GafferScene::Light );

void affects( const Gaffer::Plug *input, AffectedPlugsContainer &outputs ) const override;

void loadShader( const std::string &shaderName );

protected :

void hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const override;
IECoreScene::ConstShaderNetworkPtr computeLight( const Gaffer::Context *context ) const override;

private :

TestShader *shaderNode();
const TestShader *shaderNode() const;

GafferScene::ShaderPlug *shaderInPlug();
const GafferScene::ShaderPlug *shaderInPlug() const;

static size_t g_firstPlugIndex;

};

} // namespace GafferSceneTest
10 changes: 5 additions & 5 deletions python/GafferSceneTest/SceneAlgoTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1564,11 +1564,11 @@ def testParameterHistoryWithShaderTweaks( self ) :
history = GafferScene.SceneAlgo.history( tweaks["out"]["attributes"], "/group/light" )
attributeHistory = GafferScene.SceneAlgo.attributeHistory( history, "light" )

self.__assertParameterHistory( attributeHistory, [], tweaks["out"], "/group/light", "light", "light", "exposure", 2.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0 ], tweaks["in"], "/group/light", "light", "light", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0 ], group["out"], "/group/light", "light", "light", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0, 0 ], group["in"][0], "/light", "light", "light", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0, 0, 0 ], testLight["out"], "/light", "light", "light", "exposure", 0.0, 0 )
self.__assertParameterHistory( attributeHistory, [], tweaks["out"], "/group/light", "light", "__shader", "exposure", 2.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0 ], tweaks["in"], "/group/light", "light", "__shader", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0 ], group["out"], "/group/light", "light", "__shader", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0, 0 ], group["in"][0], "/light", "light", "__shader", "exposure", 0.0, 1 )
self.__assertParameterHistory( attributeHistory, [ 0, 0, 0, 0 ], testLight["out"], "/light", "light", "__shader", "exposure", 0.0, 0 )

def testAttributeHistoryWithMissingAttribute( self ) :

Expand Down
4 changes: 2 additions & 2 deletions python/GafferSceneTest/SceneReaderTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,12 +616,12 @@ def testExplicitUSDDefaultLights( self ) :

light1 = GafferSceneTest.TestLight()
light1["name"].setValue( "light1" )
light1["lightShaderName"].setValue( "SphereLight" ) # USDScene requires valid USD light type
light1.loadShader( "SphereLight" ) # USDScene requires valid USD light type
light1["parameters"]["intensity"] = Gaffer.FloatPlug( defaultValue = 1 ) # USD expects float, not colour
light1["defaultLight"].setValue( False )

light2 = GafferSceneTest.TestLight()
light2["lightShaderName"].setValue( "SphereLight" )
light2.loadShader( "SphereLight" )
light2["parameters"]["intensity"] = Gaffer.FloatPlug( defaultValue = 1 )
light2["name"].setValue( "light2" )

Expand Down
84 changes: 58 additions & 26 deletions src/GafferSceneTest/TestLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,54 +42,86 @@
#include "IECoreScene/Shader.h"

using namespace Gaffer;
using namespace GafferScene;
using namespace GafferSceneTest;

GAFFER_NODE_DEFINE_TYPE( TestLight )

size_t TestLight::g_firstPlugIndex = 0;

TestLight::TestLight( const std::string &name )
: Light( name )
{
addChild( new StringPlug( "lightShaderName", Plug::In, "testLight" ) );
storeIndexOfNextChild( g_firstPlugIndex );

addChild( new TestShader( "__shader" ) );
addChild( new ShaderPlug( "__shaderIn", Plug::In, Plug::Default & ~Plug::Serialisable ) );

shaderNode()->loadShader( "lightTests" );

// We need to match the plugs already in `testShader::parametersPlug()` in order to
// connect the `shaderNode()` parameters and our parameters. Subsequent calls to `loadShader()`
// will properly remove and replace our parameters because plugs are modified on the `source()`
// of `parametersPlug()`.
parametersPlug()->addChild( new Color3fPlug( "intensity" ) );
parametersPlug()->addChild( new FloatPlug( "exposure" ) );
parametersPlug()->addChild( new BoolPlug( "__areaLight" ) );

shaderNode()->typePlug()->setValue( "light" );
shaderNode()->parametersPlug()->setFlags( Plug::AcceptsInputs, true );
shaderNode()->parametersPlug()->setInput( parametersPlug() );

shaderInPlug()->setInput( shaderNode()->outPlug() );
}

TestLight::~TestLight()
{
}

void TestLight::hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const
TestShader *TestLight::shaderNode()
{
for( ValuePlug::Iterator it( parametersPlug() ); !it.done(); ++it )
{
(*it)->hash( h );
}
return getChild<TestShader>( g_firstPlugIndex );
}

IECoreScene::ConstShaderNetworkPtr TestLight::computeLight( const Gaffer::Context *context ) const
const TestShader *TestLight::shaderNode() const
{
IECoreScene::ShaderPtr shader = new IECoreScene::Shader( getChild<StringPlug>( "lightShaderName" )->getValue(), "light" );
return getChild<TestShader>( g_firstPlugIndex );
}

for( const auto &c : ValuePlug::Range( *parametersPlug() ) )
ShaderPlug *TestLight::shaderInPlug()
{
return getChild<ShaderPlug>( g_firstPlugIndex + 1 );
}

const ShaderPlug *TestLight::shaderInPlug() const
{
return getChild<ShaderPlug>( g_firstPlugIndex + 1 );
}

void TestLight::loadShader( const std::string &shaderName )
{
shaderNode()->loadShader( shaderName );
shaderNode()->typePlug()->setValue( "light" );
shaderInPlug()->setInput( shaderNode()->outPlug() );
}

void TestLight::affects( const Plug *input, AffectedPlugsContainer &outputs ) const
{
Light::affects( input, outputs );

if( input == shaderInPlug() )
{
IECore::DataPtr data = PlugAlgo::getValueAsData( c.get() );
if( auto compoundData = IECore::runTimeCast<IECore::CompoundData>( data.get() ) )
{
auto enabledData = compoundData->member<IECore::BoolData>( "enabled" );
if( enabledData && enabledData->readable() )
{
shader->parameters()[ c->getName() ] = compoundData->member( "value" );
}
}
else
{
shader->parameters()[ c->getName() ] = data;
}
outputs.push_back( outPlug()->attributesPlug() );
}
}

IECoreScene::ShaderNetworkPtr network = new IECoreScene::ShaderNetwork();
network->addShader( "light", std::move( shader ) );
network->setOutput( { "light" } );
return network;
void TestLight::hashLight( const Gaffer::Context *context, IECore::MurmurHash &h ) const
{
h.append( shaderInPlug()->attributesHash() );
}

IECoreScene::ConstShaderNetworkPtr TestLight::computeLight( const Gaffer::Context *context ) const
{
IECore::ConstCompoundObjectPtr shaderAttributes = shaderInPlug()->attributes();
return shaderAttributes->member<const IECoreScene::ShaderNetwork>( "light" );
}
4 changes: 3 additions & 1 deletion src/GafferSceneTestModule/GafferSceneTestModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ BOOST_PYTHON_MODULE( _GafferSceneTest )

GafferBindings::DependencyNodeClass<CompoundObjectSource>();
GafferBindings::NodeClass<TestShader>();
GafferBindings::NodeClass<TestLight>();
GafferBindings::NodeClass<TestLight>()
.def( "loadShader", (void (TestLight::*)(const std::string & ) )&TestLight::loadShader )
;
GafferBindings::NodeClass<TestLightFilter>();

def( "traverseScene", &traverseSceneWrapper );
Expand Down

0 comments on commit 56fe9e2

Please sign in to comment.