From 6c549cba707629be031e2c5ff571ee772021c92d Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Fri, 23 May 2025 10:32:56 +0000 Subject: [PATCH 1/3] WIP: Removes duplicate shader pins --- .../Effects/EffectShaderNodes.ShaderFX.cs | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs index 29caaee9..8d301b2f 100644 --- a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs +++ b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs @@ -29,8 +29,8 @@ static IVLNodeDescription NewShaderFXNode(this IVLNodeDescriptionFactory factory init: buildContext => { var outputType = shaderMetadata.GetShaderFXOutputType(out var innerType); - var (_effect, _messages, _) = - CreateEffectInstance("ShaderFXEffect", shaderName, shaderMetadata, serviceRegistry, graphicsDevice); + var (_effect, _messages, _) + = CreateEffectInstance("ShaderFXEffect", shaderName, shaderMetadata, serviceRegistry, graphicsDevice); var _inputs = new List(); var _outputs = new List() { buildContext.Pin("Output", outputType) }; @@ -72,6 +72,49 @@ static IVLNodeDescription NewShaderFXNode(this IVLNodeDescriptionFactory factory if (needsWorld) _inputs.Add(new ParameterPinDescription(usedNames, TransformationKeys.World)); + // Build set of variable names with 'stage' qualifier + var stageVariableNames = new HashSet(); + if (shaderMetadata.ParsedShader != null) + { + foreach (var v in shaderMetadata.ParsedShader.Variables) + { + if (v.Qualifiers != null && v.Qualifiers.Contains(Stride.Core.Shaders.Ast.Stride.StrideStorageQualifier.Stage)) + stageVariableNames.Add(v.Name.Text); + } + } + + // Deduplicate _inputs + var uniqueInputs = new Dictionary(); + var stagePins = new HashSet(); + foreach (var input in _inputs) + { + if (input is ParameterPinDescription paramDesc) + { + var keyName = paramDesc.Key.Name; + var varName = paramDesc.Key.GetVariableName(); + if (stageVariableNames.Contains(varName)) + { + // Only keep one pin for this stage variable + if (!stagePins.Contains(varName)) + { + uniqueInputs["stage:" + varName] = paramDesc; + stagePins.Add(varName); + } + } + else + { + // Allow multiple pins for non-stage variables (by keyName) + if (!uniqueInputs.TryGetValue(keyName, out var existing) || (existing.Name.Length < paramDesc.Name.Length)) + uniqueInputs[keyName] = paramDesc; + } + } + else + { + uniqueInputs[Guid.NewGuid().ToString()] = input; + } + } + _inputs = uniqueInputs.Values.ToList(); + return buildContext.Node( inputs: _inputs, outputs: _outputs, From 724eb3b7f7f74c292f8f18f3a3e289b4ae96ce77 Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Fri, 23 May 2025 10:36:41 +0000 Subject: [PATCH 2/3] Keeps multiple pins oif the same pin name occurs in multiple base shaders --- .../Effects/EffectShaderNodes.ShaderFX.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs index 8d301b2f..c13f0c79 100644 --- a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs +++ b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs @@ -83,7 +83,38 @@ static IVLNodeDescription NewShaderFXNode(this IVLNodeDescriptionFactory factory } } - // Deduplicate _inputs + // Group pins by variable name + var pinsByVarName = new Dictionary>(); + foreach (var input in _inputs) + { + if (input is ParameterPinDescription paramDesc) + { + var varName = paramDesc.Key.GetVariableName(); + if (!pinsByVarName.TryGetValue(varName, out var list)) + pinsByVarName[varName] = list = new List(); + list.Add(paramDesc); + } + } + + // Set pin names: simple if unique, long if ambiguous + foreach (var pair in pinsByVarName) + { + var list = pair.Value; + if (list.Count == 1) + { + // Use simple name + list[0].Name = pair.Key; + } + else + { + // Use long name (already set by default) + // Optionally, could forcefully set to paramDesc.Key.Name for clarity + foreach (var pin in list) + pin.Name = pin.Key.Name; + } + } + + // Deduplicate _inputs (with stage variable logic) var uniqueInputs = new Dictionary(); var stagePins = new HashSet(); foreach (var input in _inputs) From 99a36c92a248b0c7242d0fc23cd597fc3d8d4e5d Mon Sep 17 00:00:00 2001 From: Tebjan Halm Date: Fri, 23 May 2025 10:40:14 +0000 Subject: [PATCH 3/3] Some more clarity --- .../src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs index c13f0c79..b00c94cd 100644 --- a/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs +++ b/VL.Stride.Runtime/src/Rendering/Effects/EffectShaderNodes.ShaderFX.cs @@ -135,12 +135,13 @@ static IVLNodeDescription NewShaderFXNode(this IVLNodeDescriptionFactory factory else { // Allow multiple pins for non-stage variables (by keyName) + // Prefer pins with longer names for better clarity and disambiguation in case of conflicts if (!uniqueInputs.TryGetValue(keyName, out var existing) || (existing.Name.Length < paramDesc.Name.Length)) uniqueInputs[keyName] = paramDesc; } } else - { + uniqueInputs[input.Name ?? input.GetType().FullName ?? Guid.NewGuid().ToString()] = input; uniqueInputs[Guid.NewGuid().ToString()] = input; } }