Add Phong lighting (WIP)

This commit is contained in:
Jérôme Leclercq
2022-01-11 19:47:29 +01:00
parent 504249e70f
commit b0a3941f4e
40 changed files with 1141 additions and 427 deletions

View File

@@ -74,7 +74,9 @@ namespace Nz::ShaderAst
RegisterIntrinsic("length", IntrinsicType::Length);
RegisterIntrinsic("max", IntrinsicType::Max);
RegisterIntrinsic("min", IntrinsicType::Min);
RegisterIntrinsic("normalize", IntrinsicType::Normalize);
RegisterIntrinsic("pow", IntrinsicType::Pow);
RegisterIntrinsic("reflect", IntrinsicType::Reflect);
// Collect function name and their types
if (statement.GetType() == NodeType::MultiStatement)
@@ -152,7 +154,7 @@ namespace Nz::ShaderAst
ExpressionPtr SanitizeVisitor::Clone(AccessIdentifierExpression& node)
{
if (node.identifiers.empty())
throw AstError{ "accessIdentifierExpression must have at least one identifier" };
throw AstError{ "AccessIdentifierExpression must have at least one identifier" };
ExpressionPtr indexedExpr = CloneExpression(MandatoryExpr(node.expr));
for (const std::string& identifier : node.identifiers)
@@ -202,7 +204,7 @@ namespace Nz::ShaderAst
else
accessIdentifierPtr = static_cast<AccessIdentifierExpression*>(indexedExpr.get());
accessIdentifierPtr->identifiers.push_back(s->members[fieldIndex].name);
accessIdentifierPtr->identifiers.push_back(fieldPtr->name);
accessIdentifierPtr->cachedExpressionType = ResolveType(fieldPtr->type);
}
else
@@ -602,6 +604,9 @@ namespace Nz::ShaderAst
clone->constIndex = RegisterConstant(clone->name, value);
if (m_context->options.removeConstDeclaration)
return ShaderBuilder::NoOp();
return clone;
}
@@ -1775,6 +1780,7 @@ namespace Nz::ShaderAst
case IntrinsicType::Max:
case IntrinsicType::Min:
case IntrinsicType::Pow:
case IntrinsicType::Reflect:
{
if (node.parameters.size() != 2)
throw AstError { "Expected two parameters" };
@@ -1803,6 +1809,7 @@ namespace Nz::ShaderAst
}
case IntrinsicType::Length:
case IntrinsicType::Normalize:
{
if (node.parameters.size() != 1)
throw AstError{ "Expected only one parameters" };
@@ -1850,12 +1857,23 @@ namespace Nz::ShaderAst
{
const ExpressionType& type = GetExpressionType(*node.parameters.front());
if (!IsVectorType(type))
throw AstError{ "DotProduct expects vector types" };
throw AstError{ "DotProduct expects vector types" }; //< FIXME
node.cachedExpressionType = std::get<VectorType>(type).type;
break;
}
case IntrinsicType::Normalize:
case IntrinsicType::Reflect:
{
const ExpressionType& type = GetExpressionType(*node.parameters.front());
if (!IsVectorType(type))
throw AstError{ "DotProduct expects vector types" }; //< FIXME
node.cachedExpressionType = type;
break;
}
case IntrinsicType::Max:
case IntrinsicType::Min:
{
@@ -1998,17 +2016,18 @@ namespace Nz::ShaderAst
case BinaryType::CompGt:
case BinaryType::CompLe:
case BinaryType::CompLt:
{
if (leftType == PrimitiveType::Boolean)
throw AstError{ "this operation is not supported for booleans" };
[[fallthrough]];
case BinaryType::CompEq:
case BinaryType::CompNe:
{
TypeMustMatch(leftExpr, rightExpr);
return PrimitiveType::Boolean;
}
case BinaryType::Add:
case BinaryType::CompEq:
case BinaryType::CompNe:
case BinaryType::Subtract:
TypeMustMatch(leftExpr, rightExpr);
return leftExprType;

View File

@@ -209,6 +209,7 @@ namespace Nz
options.makeVariableNameUnique = true;
options.reduceLoopsToWhile = true;
options.removeCompoundAssignments = false;
options.removeConstDeclaration = true;
options.removeOptionDeclaration = true;
options.removeScalarSwizzling = true;
options.reservedIdentifiers = {
@@ -489,7 +490,10 @@ namespace Nz
bool first = true;
for (const ShaderAst::StatementPtr& statement : statements)
{
if (!first && statement->GetType() != ShaderAst::NodeType::NoOpStatement)
if (statement->GetType() == ShaderAst::NodeType::NoOpStatement)
continue;
if (!first)
AppendLine();
statement->Visit(*this);
@@ -863,10 +867,18 @@ namespace Nz
Append("min");
break;
case ShaderAst::IntrinsicType::Normalize:
Append("normalize");
break;
case ShaderAst::IntrinsicType::Pow:
Append("pow");
break;
case ShaderAst::IntrinsicType::Reflect:
Append("reflect");
break;
case ShaderAst::IntrinsicType::SampleTexture:
Append("texture");
break;
@@ -1118,6 +1130,9 @@ namespace Nz
bool first = true;
for (const auto& member : node.description.members)
{
if (member.cond.HasValue() && !member.cond.GetResultingValue())
continue;
if (!first)
AppendLine();

View File

@@ -945,10 +945,18 @@ namespace Nz
Append("min");
break;
case ShaderAst::IntrinsicType::Normalize:
Append("normalize");
break;
case ShaderAst::IntrinsicType::Pow:
Append("pow");
break;
case ShaderAst::IntrinsicType::Reflect:
Append("reflect");
break;
case ShaderAst::IntrinsicType::SampleTexture:
assert(!node.parameters.empty());
Visit(node.parameters.front(), true);

View File

@@ -801,6 +801,25 @@ namespace Nz
break;
}
case ShaderAst::IntrinsicType::Normalize:
{
UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450");
const ShaderAst::ExpressionType& vecExprType = GetExpressionType(*node.parameters[0]);
assert(IsVectorType(vecExprType));
const ShaderAst::VectorType& vecType = std::get<ShaderAst::VectorType>(vecExprType);
UInt32 typeId = m_writer.GetTypeId(vecType);
UInt32 vec = EvaluateExpression(node.parameters[0]);
UInt32 resultId = m_writer.AllocateResultId();
m_currentBlock->Append(SpirvOp::OpExtInst, typeId, resultId, glslInstructionSet, GLSLstd450Normalize, vec);
PushResultId(resultId);
break;
}
case ShaderAst::IntrinsicType::Pow:
{
UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450");
@@ -818,6 +837,23 @@ namespace Nz
break;
}
case ShaderAst::IntrinsicType::Reflect:
{
UInt32 glslInstructionSet = m_writer.GetExtendedInstructionSet("GLSL.std.450");
const ShaderAst::ExpressionType& parameterType = GetExpressionType(*node.parameters[0]);
assert(IsVectorType(parameterType));
UInt32 typeId = m_writer.GetTypeId(parameterType);
UInt32 firstParam = EvaluateExpression(node.parameters[0]);
UInt32 secondParam = EvaluateExpression(node.parameters[1]);
UInt32 resultId = m_writer.AllocateResultId();
m_currentBlock->Append(SpirvOp::OpExtInst, typeId, resultId, glslInstructionSet, GLSLstd450Reflect, firstParam, secondParam);
PushResultId(resultId);
break;
}
case ShaderAst::IntrinsicType::SampleTexture:
{
UInt32 typeId = m_writer.GetTypeId(ShaderAst::VectorType{4, ShaderAst::PrimitiveType::Float32});

View File

@@ -356,7 +356,9 @@ namespace Nz
case ShaderAst::IntrinsicType::Length:
case ShaderAst::IntrinsicType::Max:
case ShaderAst::IntrinsicType::Min:
case ShaderAst::IntrinsicType::Normalize:
case ShaderAst::IntrinsicType::Pow:
case ShaderAst::IntrinsicType::Reflect:
extInsts.emplace("GLSL.std.450");
break;