Fix Pre-Skinned Normal and Position when accessed in Pixel Shader

#2549
This commit is contained in:
Wojtek Figat
2024-09-19 10:11:49 +02:00
parent fb4b0b2f75
commit be395304ec
3 changed files with 36 additions and 33 deletions

View File

@@ -183,11 +183,15 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value)
break;
// Pre-skinned Local Position
case 13:
value = _treeType == MaterialTreeType::VertexShader ? Value(VariantType::Float3, TEXT("input.PreSkinnedPosition")) : Value::Zero;
value = Value(VariantType::Float3, TEXT("input.PreSkinnedPosition"));
if (_treeType != MaterialTreeType::VertexShader)
value = VsToPs(node, box).AsFloat3();
break;
// Pre-skinned Local Normal
case 14:
value = _treeType == MaterialTreeType::VertexShader ? Value(VariantType::Float3, TEXT("input.PreSkinnedNormal")) : Value::Zero;
value = Value(VariantType::Float3, TEXT("input.PreSkinnedNormal"));
if (_treeType != MaterialTreeType::VertexShader)
value = VsToPs(node, box).AsFloat3();
break;
// Depth
case 15:
@@ -211,38 +215,8 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value)
break;
// Interpolate VS To PS
case 20:
{
const auto input = node->GetBox(0);
// If used in VS then pass the value from the input box
if (_treeType == MaterialTreeType::VertexShader)
{
value = tryGetValue(input, Value::Zero).AsFloat4();
break;
}
// Check if can use more interpolants
if (_vsToPsInterpolants.Count() == 16)
{
OnError(node, box, TEXT("Too many VS to PS interpolants used."));
value = Value::Zero;
break;
}
// Check if can use interpolants
const auto layer = GetRootLayer();
if (!layer || layer->Domain == MaterialDomain::Decal || layer->Domain == MaterialDomain::PostProcess)
{
OnError(node, box, TEXT("VS to PS interpolants are not supported in Decal or Post Process materials."));
value = Value::Zero;
break;
}
// Indicate the interpolator slot usage
value = Value(VariantType::Float4, String::Format(TEXT("input.CustomVSToPS[{0}]"), _vsToPsInterpolants.Count()));
_vsToPsInterpolants.Add(input);
value = VsToPs(node, node->GetBox(0));
break;
}
// Terrain Holes Mask
case 21:
{

View File

@@ -832,4 +832,32 @@ void MaterialGenerator::WriteCustomGlobalCode(const Array<const MaterialGraph::N
}
}
ShaderGenerator::Value MaterialGenerator::VsToPs(Node* node, Box* input)
{
// If used in VS then pass the value from the input box
if (_treeType == MaterialTreeType::VertexShader)
{
return tryGetValue(input, Value::Zero).AsFloat4();
}
// Check if can use more interpolants
if (_vsToPsInterpolants.Count() == 16)
{
OnError(node, input, TEXT("Too many VS to PS interpolants used."));
return Value::Zero;
}
// Check if can use interpolants
const auto layer = GetRootLayer();
if (!layer || layer->Domain == MaterialDomain::Decal || layer->Domain == MaterialDomain::PostProcess)
{
OnError(node, input, TEXT("VS to PS interpolants are not supported in Decal or Post Process materials."));
return Value::Zero;
}
// Indicate the interpolator slot usage
_vsToPsInterpolants.Add(input);
return Value(VariantType::Float4, String::Format(TEXT("input.CustomVSToPS[{0}]"), _vsToPsInterpolants.Count() - 1));
}
#endif

View File

@@ -205,6 +205,7 @@ private:
MaterialValue AccessParticleAttribute(Node* caller, const StringView& name, ParticleAttributeValueTypes valueType, const Char* index = nullptr, ParticleAttributeSpace space = ParticleAttributeSpace::AsIs);
void prepareLayer(MaterialLayer* layer, bool allowVisibleParams);
void WriteCustomGlobalCode(const Array<const MaterialGraph::Node*, InlinedAllocation<8>>& nodes, int32 templateInputsMapping);
Value VsToPs(Node* node, Box* input);
public: