Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend ShaderParam system to support textures #1310

Merged
merged 16 commits into from
Feb 9, 2022
Merged
40 changes: 10 additions & 30 deletions examples/worlds/shader_param.sdf
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ ShaderParam visual plugin over time.
<scene>
<ambient>1.0 1.0 1.0</ambient>
<background>0.8 0.8 0.8</background>
<sky></sky>
<grid>false</grid>
</scene>

<light type="directional" name="sun">
Expand All @@ -177,43 +179,21 @@ ShaderParam visual plugin over time.
<direction>-0.5 0.1 -0.9</direction>
</light>

<model name="ground_plane">
<static>true</static>
<link name="link">
<collision name="collision">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
</collision>
<visual name="visual">
<geometry>
<plane>
<normal>0 0 1</normal>
<size>100 100</size>
</plane>
</geometry>
<material>
<ambient>0.8 0.8 0.8 1</ambient>
<diffuse>0.8 0.8 0.8 1</diffuse>
<specular>0.8 0.8 0.8 1</specular>
</material>
</visual>
</link>
</model>

<include>
<pose>0 0.0 0.5 0 0 0</pose>
<name>deformable_sphere</name>
<pose>3 0 0 0 0 0</pose>
<pose>0 0 1.5 0 0 0</pose>
<uri>https://fuel.ignitionrobotics.org/1.0/openrobotics/models/deformable_sphere</uri>
</include>

<include>
<name>waves</name>
<pose>0 0 0 0 0 0</pose>
<uri>https://fuel.ignitionrobotics.org/1.0/openrobotics/models/waves</uri>
</include>

<model name="camera">
<static>true</static>
<pose>2.5 0 0.5 0 0.0 3.14</pose>
<pose>2.5 0 1.5 0 0.0 3.14</pose>
<link name="link">
<pose>0.05 0.05 0.05 0 0 0</pose>
<collision name="collision">
Expand Down
104 changes: 74 additions & 30 deletions src/systems/shader_param/ShaderParam.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,18 @@ class ignition::gazebo::systems::ShaderParamPrivate
/// \brief shader type: vertex or fragment
public: std::string shader;

/// \brief variable type: int, float, float_array, int_array
/// \todo(anyone) support samplers
/// \brief variable type: int, float, float_array, int_array,
/// texture, texture_cube
public: std::string type;

/// \brief variable name of param
public: std::string name;

/// \brief param value
public: std::string value;

/// \brief Any additional arguments
public: std::vector<std::string> args;
};

/// \brief Path to vertex shader
Expand Down Expand Up @@ -98,6 +101,9 @@ class ignition::gazebo::systems::ShaderParamPrivate
/// \brief Current sim time
public: std::chrono::steady_clock::duration currentSimTime;

/// \brief Path to model
public: std::string modelPath;

/// \brief All rendering operations must happen within this call
public: void OnUpdate();
};
Expand Down Expand Up @@ -149,11 +155,29 @@ void ShaderParam::Configure(const Entity &_entity,
spv.name = paramName;
spv.value = value;
spv.type = type;

if (paramElem->HasElement("arg"))
{
sdf::ElementPtr argElem = paramElem->GetElement("arg");
while (argElem)
{
spv.args.push_back(argElem->Get<std::string>());
argElem = argElem->GetNextElement("arg");
}
}

this->dataPtr->shaderParams.push_back(spv);
paramElem = paramElem->GetNextElement("param");
}
}

if (this->dataPtr->modelPath.empty())
{
auto modelEntity = topLevelModel(_entity, _ecm);
this->dataPtr->modelPath =
_ecm.ComponentData<components::SourceFilePath>(modelEntity).value();
}

// parse path to shaders
if (sdf->HasElement("shader"))
{
Expand All @@ -166,15 +190,14 @@ void ShaderParam::Configure(const Entity &_entity,
}
else
{
auto modelEntity = topLevelModel(_entity, _ecm);
auto modelPath =
_ecm.ComponentData<components::SourceFilePath>(modelEntity);
sdf::ElementPtr vertexElem = shaderElem->GetElement("vertex");
this->dataPtr->vertexShaderUri = common::findFile(
asFullPath(vertexElem->Get<std::string>(), modelPath.value()));
asFullPath(vertexElem->Get<std::string>(),
this->dataPtr->modelPath));
sdf::ElementPtr fragmentElem = shaderElem->GetElement("fragment");
this->dataPtr->fragmentShaderUri = common::findFile(
asFullPath(fragmentElem->Get<std::string>(), modelPath.value()));
asFullPath(fragmentElem->Get<std::string>(),
this->dataPtr->modelPath));
}
}

Expand Down Expand Up @@ -263,14 +286,12 @@ void ShaderParamPrivate::OnUpdate()
// this is only done once
for (const auto & spv : this->shaderParams)
{
std::vector<std::string> values = common::split(spv.value, " ");

int intValue = 0;
float floatValue = 0;
std::vector<float> floatArrayValue;

rendering::ShaderParam::ParamType paramType =
rendering::ShaderParam::PARAM_NONE;
// TIME is reserved keyword for sim time
if (spv.value == "TIME")
{
this->timeParams.push_back(spv);
continue;
}

rendering::ShaderParamsPtr params;
if (spv.shader == "fragment")
Expand All @@ -283,22 +304,48 @@ void ShaderParamPrivate::OnUpdate()
}

// if no <value> is specified, this could be a constant
if (values.empty())
if (spv.value.empty())
{
// \todo handle args for constants
(*params)[spv.name] = intValue;
// \todo handle args for constants in ign-rendering
(*params)[spv.name] = 1;
continue;
}
// float / int
else if (values.size() == 1u)
{
std::string str = values[0];

// TIME is reserved keyword for sim time
if (str == "TIME")
// handle texture params
if (spv.type == "texture")
{
this->timeParams.push_back(spv);
continue;
unsigned int uvSetIndex = spv.args.empty() ? 0u :
static_cast<unsigned int>(std::stoul(spv.args[0]));
std::string texPath = common::findFile(
asFullPath(spv.value, this->modelPath));
(*params)[spv.name].SetTexture(texPath,
rendering::ShaderParam::ParamType::PARAM_TEXTURE, uvSetIndex);
}
else if (spv.type == "texture_cube")
{
unsigned int uvSetIndex = spv.args.empty() ? 0u :
static_cast<unsigned int>(std::stoul(spv.args[0]));
std::string texPath = common::findFile(
asFullPath(spv.value, this->modelPath));
(*params)[spv.name].SetTexture(texPath,
rendering::ShaderParam::ParamType::PARAM_TEXTURE_CUBE, uvSetIndex);
}
// handle int, float, int_array, and float_array params
else
{
std::vector<std::string> values = common::split(spv.value, " ");

int intValue = 0;
float floatValue = 0;
std::vector<float> floatArrayValue;

rendering::ShaderParam::ParamType paramType =
rendering::ShaderParam::PARAM_NONE;

// float / int
if (values.size() == 1u)
{
std::string str = values[0];

// if <type> is not empty, respect the specified type
if (!spv.type.empty())
Expand All @@ -313,10 +360,6 @@ void ShaderParamPrivate::OnUpdate()
floatValue = std::stof(str);
paramType = rendering::ShaderParam::PARAM_FLOAT;
}
else
{
// \todo(anyone) support texture samplers
}
}
// else do our best guess at what the type is
else
Expand Down Expand Up @@ -371,6 +414,7 @@ void ShaderParamPrivate::OnUpdate()
(*params)[spv.name].UpdateBuffer(fv);
}
}
}
this->shaderParams.clear();

// time variables need to be updated every iteration
Expand Down