Shader: Add Discard node
This commit is contained in:
parent
a1c15a8c16
commit
ed72d668d9
|
|
@ -73,6 +73,7 @@ namespace Nz
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
||||||
void Visit(ShaderNodes::Constant& node) override;
|
void Visit(ShaderNodes::Constant& node) override;
|
||||||
void Visit(ShaderNodes::DeclareVariable& node) override;
|
void Visit(ShaderNodes::DeclareVariable& node) override;
|
||||||
|
void Visit(ShaderNodes::Discard& node) override;
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
||||||
void Visit(ShaderNodes::Identifier& node) override;
|
void Visit(ShaderNodes::Identifier& node) override;
|
||||||
void Visit(ShaderNodes::InputVariable& var) override;
|
void Visit(ShaderNodes::InputVariable& var) override;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ namespace Nz
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
||||||
void Visit(ShaderNodes::Constant& node) override;
|
void Visit(ShaderNodes::Constant& node) override;
|
||||||
void Visit(ShaderNodes::DeclareVariable& node) override;
|
void Visit(ShaderNodes::DeclareVariable& node) override;
|
||||||
|
void Visit(ShaderNodes::Discard& node) override;
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
||||||
void Visit(ShaderNodes::Identifier& node) override;
|
void Visit(ShaderNodes::Identifier& node) override;
|
||||||
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ namespace Nz
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
||||||
void Visit(ShaderNodes::Constant& node) override;
|
void Visit(ShaderNodes::Constant& node) override;
|
||||||
void Visit(ShaderNodes::DeclareVariable& node) override;
|
void Visit(ShaderNodes::DeclareVariable& node) override;
|
||||||
|
void Visit(ShaderNodes::Discard& node) override;
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
||||||
void Visit(ShaderNodes::Identifier& node) override;
|
void Visit(ShaderNodes::Identifier& node) override;
|
||||||
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ namespace Nz
|
||||||
void Serialize(ShaderNodes::ConditionalStatement& node);
|
void Serialize(ShaderNodes::ConditionalStatement& node);
|
||||||
void Serialize(ShaderNodes::Constant& node);
|
void Serialize(ShaderNodes::Constant& node);
|
||||||
void Serialize(ShaderNodes::DeclareVariable& node);
|
void Serialize(ShaderNodes::DeclareVariable& node);
|
||||||
|
void Serialize(ShaderNodes::Discard& node);
|
||||||
void Serialize(ShaderNodes::ExpressionStatement& node);
|
void Serialize(ShaderNodes::ExpressionStatement& node);
|
||||||
void Serialize(ShaderNodes::Identifier& node);
|
void Serialize(ShaderNodes::Identifier& node);
|
||||||
void Serialize(ShaderNodes::IntrinsicCall& node);
|
void Serialize(ShaderNodes::IntrinsicCall& node);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ namespace Nz
|
||||||
virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0;
|
virtual void Visit(ShaderNodes::ConditionalStatement& node) = 0;
|
||||||
virtual void Visit(ShaderNodes::Constant& node) = 0;
|
virtual void Visit(ShaderNodes::Constant& node) = 0;
|
||||||
virtual void Visit(ShaderNodes::DeclareVariable& node) = 0;
|
virtual void Visit(ShaderNodes::DeclareVariable& node) = 0;
|
||||||
|
virtual void Visit(ShaderNodes::Discard& node) = 0;
|
||||||
virtual void Visit(ShaderNodes::ExpressionStatement& node) = 0;
|
virtual void Visit(ShaderNodes::ExpressionStatement& node) = 0;
|
||||||
virtual void Visit(ShaderNodes::Identifier& node) = 0;
|
virtual void Visit(ShaderNodes::Identifier& node) = 0;
|
||||||
virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0;
|
virtual void Visit(ShaderNodes::IntrinsicCall& node) = 0;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ namespace Nz
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
||||||
void Visit(ShaderNodes::Constant& node) override;
|
void Visit(ShaderNodes::Constant& node) override;
|
||||||
void Visit(ShaderNodes::DeclareVariable& node) override;
|
void Visit(ShaderNodes::DeclareVariable& node) override;
|
||||||
|
void Visit(ShaderNodes::Discard& node) override;
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
||||||
void Visit(ShaderNodes::Identifier& node) override;
|
void Visit(ShaderNodes::Identifier& node) override;
|
||||||
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ namespace Nz::ShaderBuilder
|
||||||
constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement;
|
constexpr GenBuilder<ShaderNodes::ConditionalStatement> ConditionalStatement;
|
||||||
constexpr GenBuilder<ShaderNodes::Constant> Constant;
|
constexpr GenBuilder<ShaderNodes::Constant> Constant;
|
||||||
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
|
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
|
||||||
|
constexpr GenBuilder<ShaderNodes::Discard> Discard;
|
||||||
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
|
||||||
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
|
||||||
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
|
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ namespace Nz::ShaderNodes
|
||||||
ConditionalExpression,
|
ConditionalExpression,
|
||||||
ConditionalStatement,
|
ConditionalStatement,
|
||||||
DeclareVariable,
|
DeclareVariable,
|
||||||
|
Discard,
|
||||||
ExpressionStatement,
|
ExpressionStatement,
|
||||||
Identifier,
|
Identifier,
|
||||||
IntrinsicCall,
|
IntrinsicCall,
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,15 @@ namespace Nz
|
||||||
static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr);
|
static inline std::shared_ptr<DeclareVariable> Build(VariablePtr variable, ExpressionPtr expression = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NAZARA_SHADER_API Discard : public Statement
|
||||||
|
{
|
||||||
|
inline Discard();
|
||||||
|
|
||||||
|
void Visit(ShaderAstVisitor& visitor) override;
|
||||||
|
|
||||||
|
static inline std::shared_ptr<Discard> Build();
|
||||||
|
};
|
||||||
|
|
||||||
struct NAZARA_SHADER_API Identifier : public Expression
|
struct NAZARA_SHADER_API Identifier : public Expression
|
||||||
{
|
{
|
||||||
inline Identifier();
|
inline Identifier();
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,17 @@ namespace Nz::ShaderNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Discard::Discard() :
|
||||||
|
Statement(NodeType::DeclareVariable)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::shared_ptr<Discard> Discard::Build()
|
||||||
|
{
|
||||||
|
return std::make_shared<Discard>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Identifier::Identifier() :
|
inline Identifier::Identifier() :
|
||||||
Expression(NodeType::Identifier)
|
Expression(NodeType::Identifier)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ namespace Nz
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
void Visit(ShaderNodes::ConditionalStatement& node) override;
|
||||||
void Visit(ShaderNodes::Constant& node) override;
|
void Visit(ShaderNodes::Constant& node) override;
|
||||||
void Visit(ShaderNodes::DeclareVariable& node) override;
|
void Visit(ShaderNodes::DeclareVariable& node) override;
|
||||||
|
void Visit(ShaderNodes::Discard& node) override;
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
void Visit(ShaderNodes::ExpressionStatement& node) override;
|
||||||
void Visit(ShaderNodes::Identifier& node) override;
|
void Visit(ShaderNodes::Identifier& node) override;
|
||||||
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
void Visit(ShaderNodes::IntrinsicCall& node) override;
|
||||||
|
|
|
||||||
|
|
@ -519,6 +519,11 @@ namespace Nz
|
||||||
AppendLine(";");
|
AppendLine(";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GlslWriter::Visit(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
Append("discard;");
|
||||||
|
}
|
||||||
|
|
||||||
void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node)
|
void GlslWriter::Visit(ShaderNodes::ExpressionStatement& node)
|
||||||
{
|
{
|
||||||
Visit(node.expression);
|
Visit(node.expression);
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,11 @@ namespace Nz
|
||||||
PushStatement(ShaderNodes::DeclareVariable::Build(CloneVariable(node.variable), CloneExpression(node.expression)));
|
PushStatement(ShaderNodes::DeclareVariable::Build(CloneVariable(node.variable), CloneExpression(node.expression)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderAstCloner::Visit(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
PushStatement(ShaderNodes::Discard::Build());
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderAstCloner::Visit(ShaderNodes::ExpressionStatement& node)
|
void ShaderAstCloner::Visit(ShaderNodes::ExpressionStatement& node)
|
||||||
{
|
{
|
||||||
PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression)));
|
PushStatement(ShaderNodes::ExpressionStatement::Build(CloneExpression(node.expression)));
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,11 @@ namespace Nz
|
||||||
Visit(node.expression);
|
Visit(node.expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
/* Nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node)
|
void ShaderAstRecursiveVisitor::Visit(ShaderNodes::ExpressionStatement& node)
|
||||||
{
|
{
|
||||||
Visit(node.expression);
|
Visit(node.expression);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,11 @@ namespace Nz
|
||||||
Serialize(node);
|
Serialize(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Visit(ShaderNodes::Discard& node) override
|
||||||
|
{
|
||||||
|
Serialize(node);
|
||||||
|
}
|
||||||
|
|
||||||
void Visit(ShaderNodes::ExpressionStatement& node) override
|
void Visit(ShaderNodes::ExpressionStatement& node) override
|
||||||
{
|
{
|
||||||
Serialize(node);
|
Serialize(node);
|
||||||
|
|
@ -242,6 +247,11 @@ namespace Nz
|
||||||
Node(node.expression);
|
Node(node.expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderAstSerializerBase::Serialize(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
/* Nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderAstSerializerBase::Serialize(ShaderNodes::ExpressionStatement& node)
|
void ShaderAstSerializerBase::Serialize(ShaderNodes::ExpressionStatement& node)
|
||||||
{
|
{
|
||||||
Node(node.expression);
|
Node(node.expression);
|
||||||
|
|
@ -665,6 +675,7 @@ namespace Nz
|
||||||
HandleType(ConditionalExpression);
|
HandleType(ConditionalExpression);
|
||||||
HandleType(ConditionalStatement);
|
HandleType(ConditionalStatement);
|
||||||
HandleType(DeclareVariable);
|
HandleType(DeclareVariable);
|
||||||
|
HandleType(Discard);
|
||||||
HandleType(ExpressionStatement);
|
HandleType(ExpressionStatement);
|
||||||
HandleType(Identifier);
|
HandleType(Identifier);
|
||||||
HandleType(IntrinsicCall);
|
HandleType(IntrinsicCall);
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ namespace Nz
|
||||||
throw std::runtime_error("unhandled DeclareVariable node");
|
throw std::runtime_error("unhandled DeclareVariable node");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderAstVisitorExcept::Visit(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("unhandled Discard node");
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderAstVisitorExcept::Visit(ShaderNodes::ExpressionStatement& /*node*/)
|
void ShaderAstVisitorExcept::Visit(ShaderNodes::ExpressionStatement& /*node*/)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("unhandled ExpressionStatement node");
|
throw std::runtime_error("unhandled ExpressionStatement node");
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,12 @@ namespace Nz::ShaderNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Discard::Visit(ShaderAstVisitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ExpressionCategory Identifier::GetExpressionCategory() const
|
ExpressionCategory Identifier::GetExpressionCategory() const
|
||||||
{
|
{
|
||||||
return ExpressionCategory::LValue;
|
return ExpressionCategory::LValue;
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,11 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpirvAstVisitor::Visit(ShaderNodes::Discard& /*node*/)
|
||||||
|
{
|
||||||
|
m_writer.GetInstructions().Append(SpirvOp::OpKill);
|
||||||
|
}
|
||||||
|
|
||||||
void SpirvAstVisitor::Visit(ShaderNodes::ExpressionStatement& node)
|
void SpirvAstVisitor::Visit(ShaderNodes::ExpressionStatement& node)
|
||||||
{
|
{
|
||||||
Visit(node.expression);
|
Visit(node.expression);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include <ShaderNode/DataModels/Discard.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
#include <ShaderNode/ShaderGraph.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/BoolData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
#include <QtWidgets/QComboBox>
|
||||||
|
#include <QtWidgets/QFormLayout>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
Discard::Discard(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
DisablePreview();
|
||||||
|
DisableCustomVariableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr Discard::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
using namespace Nz::ShaderBuilder;
|
||||||
|
|
||||||
|
assert(count == 1);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
return Branch(Equal(expressions[0], Constant(true)), Nz::ShaderBuilder::Discard(), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Discard::GetOutputOrder() const
|
||||||
|
{
|
||||||
|
return std::numeric_limits<int>::lowest();
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeDataType Discard::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portType == QtNodes::PortType::In);
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
return BoolData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Discard::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return 1;
|
||||||
|
case QtNodes::PortType::Out: return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> Discard::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_DISCARD_HPP
|
||||||
|
#define NAZARA_SHADERNODES_DISCARD_HPP
|
||||||
|
|
||||||
|
#include <ShaderNode/ShaderGraph.hpp>
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
|
class QFormLayout;
|
||||||
|
|
||||||
|
class Discard : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Discard(ShaderGraph& graph);
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
int GetOutputOrder() const;
|
||||||
|
|
||||||
|
QString caption() const override { return "Discard"; }
|
||||||
|
QString name() const override { return "Discard"; }
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/Discard.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include <ShaderNode/DataModels/Discard.hpp>
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <ShaderNode/DataModels/BufferField.hpp>
|
#include <ShaderNode/DataModels/BufferField.hpp>
|
||||||
#include <ShaderNode/DataModels/Cast.hpp>
|
#include <ShaderNode/DataModels/Cast.hpp>
|
||||||
#include <ShaderNode/DataModels/ConditionalExpression.hpp>
|
#include <ShaderNode/DataModels/ConditionalExpression.hpp>
|
||||||
|
#include <ShaderNode/DataModels/Discard.hpp>
|
||||||
#include <ShaderNode/DataModels/FloatValue.hpp>
|
#include <ShaderNode/DataModels/FloatValue.hpp>
|
||||||
#include <ShaderNode/DataModels/InputValue.hpp>
|
#include <ShaderNode/DataModels/InputValue.hpp>
|
||||||
#include <ShaderNode/DataModels/OutputValue.hpp>
|
#include <ShaderNode/DataModels/OutputValue.hpp>
|
||||||
|
|
@ -742,6 +743,7 @@ std::shared_ptr<QtNodes::DataModelRegistry> ShaderGraph::BuildRegistry()
|
||||||
RegisterShaderNode<CastToVec3>(*this, registry, "Casts");
|
RegisterShaderNode<CastToVec3>(*this, registry, "Casts");
|
||||||
RegisterShaderNode<CastToVec4>(*this, registry, "Casts");
|
RegisterShaderNode<CastToVec4>(*this, registry, "Casts");
|
||||||
RegisterShaderNode<ConditionalExpression>(*this, registry, "Shader");
|
RegisterShaderNode<ConditionalExpression>(*this, registry, "Shader");
|
||||||
|
RegisterShaderNode<Discard>(*this, registry, "Outputs");
|
||||||
RegisterShaderNode<FloatValue>(*this, registry, "Constants");
|
RegisterShaderNode<FloatValue>(*this, registry, "Constants");
|
||||||
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
|
RegisterShaderNode<InputValue>(*this, registry, "Inputs");
|
||||||
RegisterShaderNode<PositionOutputValue>(*this, registry, "Outputs");
|
RegisterShaderNode<PositionOutputValue>(*this, registry, "Outputs");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue