parseShaderUniforms function
Parses all uniform declarations from a GLSL shader source string.
This parser supports two inputs:
- Flutter compiled shader payload metadata (
sksl.uniforms). - Plain GLSL source text with
uniformdeclarations.
Returns explicit index bindings for float and sampler uniforms.
Throws FormatException if shader source is invalid.
Implementation
ShaderUniformBindings parseShaderUniforms(
String shaderSource, {
Map<String, dynamic>? propertiesJson,
}) {
if (shaderSource.isEmpty) {
throw FormatException('Shader source cannot be empty');
}
final compiledBindings = _parseCompiledShaderUniforms(shaderSource);
if (compiledBindings != null) {
debugPrint(
'parseShaderUniforms.compiled.bindings: ${compiledBindings.toNamesByType()}');
return compiledBindings;
}
final uniformRegex = RegExp(
r'uniform\s+(\w+)\s+(\w+)(\s*\[\s*\d*\s*\])?\s*;',
multiLine: true,
);
final matches = uniformRegex.allMatches(shaderSource);
final floatBindings = <UniformBinding>[];
final samplerBindings = <UniformBinding>[];
final propertyIndices = _parsePropertyIndices(propertiesJson);
var fallbackFloatIndex = 0;
var fallbackSamplerIndex = 0;
for (final match in matches) {
final type = match.group(1)!;
final name = match.group(2)!;
if (type == SupportedUniformTypes.float) {
final index = propertyIndices.floatIndices[name] ?? fallbackFloatIndex;
floatBindings.add(UniformBinding(name: name, index: index));
if (!propertyIndices.floatIndices.containsKey(name)) {
fallbackFloatIndex++;
}
continue;
}
if (type == SupportedUniformTypes.sampler2D ||
type == SupportedUniformTypes.flutterSampler2D) {
final index =
propertyIndices.samplerIndices[name] ?? fallbackSamplerIndex;
samplerBindings.add(UniformBinding(name: name, index: index));
if (!propertyIndices.samplerIndices.containsKey(name)) {
fallbackSamplerIndex++;
}
}
}
final bindings = ShaderUniformBindings(
floatBindings: floatBindings,
sampler2DBindings: samplerBindings,
);
debugPrint('parseShaderUniforms.bindings: ${bindings.toNamesByType()}');
return bindings;
}