-
Notifications
You must be signed in to change notification settings - Fork 23
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
Implement geompropvalue as GLSL varying parameters #1046
Changes from all commits
fc8742d
c0c26e3
91194c7
c41d65a
2746664
9708a4f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -220,8 +220,8 @@ GlslShaderGenerator::GlslShaderGenerator() : | |
registerImplementation("IM_geomcolor_color4_" + GlslShaderGenerator::LANGUAGE, GeomColorNodeGlsl::create); | ||
// <!-- <geompropvalue> --> | ||
registerImplementation("IM_geompropvalue_integer_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
registerImplementation("IM_geompropvalue_boolean_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
registerImplementation("IM_geompropvalue_string_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will throw an exception when generating code for a document that contains these unimplementable nodes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if we should let these through and support them as uniforms for now so we don't lose any functionality. I think for the code generation we can test for these cases. As discussed with Niklas, later on we can add in some way to specify this in MaterialX. Then we can support the general concept of "primvars" which may be uniform or varying. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes for longer term we should start using the So before you can call the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JGamache-autodesk , @niklasharrysson : For the current implementation to avoid a regression I'd like to leave the uniform support for boolean and string so graphs that used to work don't fail now. Is that agreeable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can I then recommend splitting the nodedef into varyinggeompropvalue and uniformgeompropvalue in some future update? Otherwise some of the downstream code (like xmlSetProperty in OgsXmlGenerator.cpp) will require some creativity to find out if the value is uniform or varying. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @JGamache-autodesk, Yes, let's do a follow-up to see what works best e.g. two new types as you mention or one type with a reference with an attribute indicating variation. |
||
registerImplementation("IM_geompropvalue_boolean_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl_asUniform::create); | ||
registerImplementation("IM_geompropvalue_string_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl_asUniform::create); | ||
registerImplementation("IM_geompropvalue_float_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
registerImplementation("IM_geompropvalue_color2_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
registerImplementation("IM_geompropvalue_color3_" + GlslShaderGenerator::LANGUAGE, GeomPropValueNodeGlsl::create); | ||
|
@@ -753,6 +753,11 @@ void GlslShaderGenerator::emitVariableDeclaration(const ShaderPort* variable, co | |
else | ||
{ | ||
string str = qualifier.empty() ? EMPTY_STRING : qualifier + " "; | ||
// Varying parameters of type int must be flat qualified on output from vertex stage and | ||
// input to pixel stage. The only way to get these is with geompropvalue_integer nodes. | ||
if (qualifier.empty() && variable->getType() == Type::INTEGER && !assignValue && variable->getName().rfind(HW::T_IN_GEOMPROP, 0) == 0) { | ||
str += GlslSyntax::FLAT_QUALIFIER + " "; | ||
bernardkwok marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
str += _syntax->getTypeName(variable->getType()) + " " + variable->getVariable(); | ||
|
||
// If an array we need an array qualifier (suffix) for the variable name | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,22 +20,78 @@ void GeomPropValueNodeGlsl::createVariables(const ShaderNode& node, GenContext&, | |
const ShaderInput* geomPropInput = node.getInput(GEOMPROP); | ||
if (!geomPropInput || !geomPropInput->getValue()) | ||
{ | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "', don't know what property to bind"); | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "'. Don't know what property to bind"); | ||
} | ||
const string geomProp = geomPropInput->getValue()->getValueString(); | ||
const ShaderOutput* output = node.getOutput(); | ||
|
||
ShaderStage& vs = shader.getStage(Stage::VERTEX); | ||
ShaderStage& ps = shader.getStage(Stage::PIXEL); | ||
|
||
addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_GEOMPROP + "_" + geomProp, vs); | ||
addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_IN_GEOMPROP + "_" + geomProp, vs, ps); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Systematic use of T_IN_GEOMPROP insures the parameter ends up being named |
||
} | ||
|
||
void GeomPropValueNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const | ||
{ | ||
const ShaderGenerator& shadergen = context.getShaderGenerator(); | ||
|
||
const ShaderInput* geomPropInput = node.getInput(GEOMPROP); | ||
if (!geomPropInput) | ||
{ | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "'. Don't know what property to bind"); | ||
} | ||
const string geomname = geomPropInput->getValue()->getValueString(); | ||
const string variable = HW::T_IN_GEOMPROP + "_" + geomname; | ||
|
||
BEGIN_SHADER_STAGE(stage, Stage::VERTEX) | ||
VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA); | ||
const string prefix = vertexData.getInstance() + "."; | ||
ShaderPort* geomprop = vertexData[variable]; | ||
if (!geomprop->isEmitted()) | ||
{ | ||
shadergen.emitLine(prefix + geomprop->getVariable() + " = " + HW::T_IN_GEOMPROP + "_" + geomname, stage); | ||
geomprop->setEmitted(); | ||
} | ||
END_SHADER_STAGE(shader, Stage::VERTEX) | ||
|
||
BEGIN_SHADER_STAGE(stage, Stage::PIXEL) | ||
VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA); | ||
const string prefix = vertexData.getInstance() + "."; | ||
ShaderPort* geomprop = vertexData[variable]; | ||
shadergen.emitLineBegin(stage); | ||
shadergen.emitOutput(node.getOutput(), true, false, context, stage); | ||
shadergen.emitString(" = " + prefix + geomprop->getVariable(), stage); | ||
shadergen.emitLineEnd(stage); | ||
END_SHADER_STAGE(shader, Stage::PIXEL) | ||
} | ||
|
||
ShaderNodeImplPtr GeomPropValueNodeGlsl_asUniform::create() | ||
{ | ||
return std::make_shared<GeomPropValueNodeGlsl_asUniform>(); | ||
} | ||
|
||
void GeomPropValueNodeGlsl_asUniform::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const | ||
{ | ||
const ShaderInput* geomPropInput = node.getInput(GEOMPROP); | ||
if (!geomPropInput || !geomPropInput->getValue()) | ||
{ | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "'. Don't know what property to bind"); | ||
} | ||
const string geomProp = geomPropInput->getValue()->getValueString(); | ||
ShaderStage& ps = shader.getStage(Stage::PIXEL); | ||
ShaderPort* uniform = addStageUniform(HW::PRIVATE_UNIFORMS, node.getOutput()->getType(), HW::T_GEOMPROP + "_" + geomProp, ps); | ||
uniform->setPath(geomPropInput->getPath()); | ||
} | ||
|
||
void GeomPropValueNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const | ||
void GeomPropValueNodeGlsl_asUniform::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const | ||
{ | ||
BEGIN_SHADER_STAGE(stage, Stage::PIXEL) | ||
const ShaderGenerator& shadergen = context.getShaderGenerator(); | ||
const ShaderInput* geomPropInput = node.getInput(GEOMPROP); | ||
if (!geomPropInput) | ||
{ | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "', don't know what property to bind"); | ||
throw ExceptionShaderGenError("No 'geomprop' parameter found on geompropvalue node '" + node.getName() + "'. Don't know what property to bind"); | ||
} | ||
const string attrName = geomPropInput->getValue()->getValueString(); | ||
shadergen.emitLineBegin(stage); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,12 @@ class OgsFragment | |
return _element ? _element->getDocument() : mx::DocumentPtr(); | ||
} | ||
|
||
/// Get the GLSL shader generated for this fragment | ||
mx::ShaderPtr getShader() const | ||
{ | ||
return _glslShader; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Helped with debugging. |
||
|
||
/// Return the source of the OGS fragment as a string. | ||
const std::string& getFragmentSource() const; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,8 +56,6 @@ namespace | |
{ "Tm", "Tm" }, | ||
{ "Bw", "Bw" }, | ||
{ "Bm", "Bm" }, | ||
{ "texcoord_0", "mayaUvCoordSemantic" }, | ||
{ "color_0", "colorset" }, | ||
|
||
{ "u_worldMatrix", "World" }, | ||
{ "u_worldInverseMatrix", "WorldInverse" }, | ||
|
@@ -85,6 +83,13 @@ namespace | |
{ "u_time", "Time" } | ||
}; | ||
|
||
static const vector<std::pair<string, const pugi::char_t*> > OGS_SEMANTICS_PREFIX_MAP = | ||
{ | ||
{ "texcoord_", "mayaUvCoordSemantic" }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to handle texcoord_1 and color_2 as well. |
||
{ "color_", "colorset" }, | ||
{ "i_geomprop_", "mayaUvCoordSemantic" } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now looking for explicit varying input using |
||
}; | ||
|
||
namespace OgsParameterFlags | ||
{ | ||
static const std::string | ||
|
@@ -143,6 +148,12 @@ namespace | |
{ | ||
prop.append_attribute(SEMANTIC) = semantic->second; | ||
} | ||
for (auto const& ogsSemantic: OGS_SEMANTICS_PREFIX_MAP) { | ||
// STL startswith: | ||
if (name.rfind(ogsSemantic.first, 0) == 0) { | ||
prop.append_attribute(SEMANTIC) = ogsSemantic.second; | ||
} | ||
} | ||
if (!parameterFlags.empty()) | ||
{ | ||
prop.append_attribute(FLAGS) = parameterFlags.c_str(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1508,7 +1508,7 @@ void ShaderGraph::calculateScopes() | |
{ | ||
newScopeInfo.adjustAtConditionalInput(node, int(inputIndex), 0x12); | ||
} | ||
else if (isSwitch) | ||
else if (isSwitch && inputIndex != node->numInputs() - 1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not mine. Possibly broke when the |
||
{ | ||
const uint32_t fullMask = (1 << node->numInputs()) - 1; | ||
newScopeInfo.adjustAtConditionalInput(node, int(inputIndex), fullMask); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for fixing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the result visually more interesting when used with a varying input stream.