Project Documentation
π 1. Overview
The UnityShaderParser project is a comprehensive library designed for parsing Unity shaders, encompassing various distinct components. At its core, the library consists of a parser for ShaderLab, Unity's proprietary Shader Domain-Specific Language (DSL), as well as a parser for High-Level Shading Language (HLSL), which is embedded within ShaderLab. Additionally, it features a preprocessor for handling macros prior to parsing and a framework for analyzing syntax trees using the visitor pattern, allowing for edits to the corresponding source code.
The primary purpose of the UnityShaderParser project is to provide a robust and reliable solution for parsing and analyzing Unity shaders, enabling developers to create a wide range of applications, from shader code interpretation and execution to syntax analysis and modification. The library has been utilized in various projects, including the HLSLInterpreter, a library for running shader code on the CPU, and the Slang shading language plugin for Unity. Its versatility and effectiveness have also been demonstrated in numerous examples and tests, showcasing its potential for a broad range of use cases.
From a technical standpoint, the UnityShaderParser project is built using a .NET-based stack, with the core library implemented in C#. The project's continuous integration and continuous deployment (CI/CD) pipeline is managed through GitHub Actions, as evidenced by the .github/workflows/test-ci.yml file. This pipeline automates the build, testing, and deployment process, ensuring that the library is consistently reliable and up-to-date. The use of .NET 6.0 and the dotnet CLI facilitates efficient development, testing, and deployment of the library.
Tech Stack at a Glance
| Category | Technology | Purpose |
|---|---|---|
| Programming Language | C# | Implementation of the UnityShaderParser library |
| Framework | .NET 6.0 | Provides the foundation for the library's development and deployment |
| CI/CD Pipeline | GitHub Actions | Automates the build, testing, and deployment process |
| Testing Framework | dotnet CLI | Enables efficient testing of the library using the dotnet test command |
| Package Manager | NuGet | Facilitates distribution and integration of the UnityShaderParser library |
| The project's architecture is designed to be modular and extensible, allowing developers to easily integrate the library into their existing workflows and applications. The use of a visitor pattern for syntax tree analysis and modification enables flexible and efficient processing of shader code. Furthermore, the library's availability as a single portable C# file, a zip archive, or via NuGet package simplifies the integration process, making it accessible to a wide range of developers and use cases. |
In terms of state management, styling, and database libraries, the UnityShaderParser project does not appear to have specific dependencies or integrations. Its primary focus is on parsing and analyzing Unity shaders, and it achieves this through its own custom implementations and frameworks. The library's design and architecture prioritize simplicity, reliability, and performance, making it an attractive solution for developers seeking a robust and efficient shader parsing and analysis tool. Overall, the UnityShaderParser project represents a valuable resource for the development community, offering a powerful and flexible solution for working with Unity shaders.
π 2. Project Structure
Directory Structure
The codebase contains the following primary files and directories:
.editorconfig.github/workflows/test-ci.yml.gitignoreLICENSEREADME.mdUnityShaderParser.Experiments/Program.csUnityShaderParser.Experiments/UnityShaderParser.Experiments.csprojUnityShaderParser.Tests/HLSLParserTests.csUnityShaderParser.Tests/PreProcessorTests.csUnityShaderParser.Tests/ShaderLabParserTests.csUnityShaderParser.Tests/ShaderParserTests.csUnityShaderParser.Tests/TestShaders/FxDis/readme.txtUnityShaderParser.Tests/TestShaders/FxDis/test.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ds5/basic.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ds5/basic.knowngoodUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/hs5/basic.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ps4/fxaa.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ps4/primID.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ps5/conservative_depth.hlslUnityShaderParser.Tests/TestShaders/HlslCrossCompiler/ps5/interface_arrays.hlsl
Generated via local analysis.
ποΈ 3. Architecture & Data Flow
Deep Architecture Analysis of UnityShaderParser
1. Architecture Reasoning & Module Interactions
Core Architecture Overview
UnityShaderParser follows a modular compiler architecture with distinct parsing layers for different shader languages (ShaderLab and HLSL) while sharing common infrastructure. The system is designed as a recursive descent parser with strong separation of concerns between lexical analysis, parsing, and syntax tree manipulation.
Key Design Patterns & Principles
-
Lexer/Parser Separation Pattern:
- Each language (ShaderLab, HLSL) has dedicated lexers (
ShaderLabLexer.cs,HLSLLexer.cs) that tokenize input - Corresponding parsers (
ShaderLabParser.cs,HLSLParser.cs) build syntax trees from tokens - Follows the Compiler Compiler pattern where lexers produce tokens consumed by parsers
- Each language (ShaderLab, HLSL) has dedicated lexers (
-
Visitor Pattern:
HLSLSyntaxVisitor.csandShaderLabSyntaxVisitor.csprovide interfaces for traversing syntax trees- Enables analysis, transformation, and code generation without modifying core syntax classes
- Used extensively in tests for validation and in real-world tools for shader analysis
-
Composite Syntax Elements:
BaseSyntaxElements.csdefines the core syntax tree structure withSyntaxElementbase class- Language-specific syntax elements inherit from base classes (
HLSLSyntaxElements.cs,ShaderLabSyntaxElements.cs) - Implements the Composite Pattern allowing tree structures of arbitrary depth
-
Preprocessor Pipeline:
HLSLPreProcessor.cshandles macro expansion and conditional compilation- Uses
IPreProcessorIncludeResolverfor file inclusion resolution - Implements Chain of Responsibility for handling different preprocessor directives
-
Editor Integration:
BaseLexer.csandBaseParser.csprovide common infrastructure for both languagesShaderParser.csacts as a Facade providing unified entry point for parsing either language
Module Interactions & Data Flow
-
Parsing Pipeline:
Source File β Lexer β Token Stream β Parser β Syntax Tree -
Preprocessing Pipeline:
HLSL Source β PreProcessor β Expanded Source β Lexer β Parser -
Analysis Pipeline:
Syntax Tree β Visitor β Analysis Results -
Transformation Pipeline:
Syntax Tree β Visitor β Modified Syntax Tree β Printer β Output Source
Advanced Design Considerations
-
Error Recovery:
- Both lexers and parsers implement panic mode recovery to continue parsing after errors
BaseLexer.cstracks error positions for precise error reporting
-
Memory Efficiency:
- Syntax elements store source spans rather than full text
- Uses flyweight pattern for common syntax elements
-
Extensibility:
- Virtual methods in base classes allow language-specific behavior
- Visitor pattern enables adding new operations without modifying syntax classes
-
Cross-Language Support:
- Common infrastructure handles both ShaderLab and HLSL
- Type system bridges HLSL and ShaderLab concepts where needed
2. Data Flow & State Transitions
| Origin | Action | Logic Handler | Resulting State |
|---|---|---|---|
| File System | Read shader source | ShaderParser.cs | Raw source text |
| Raw source text | Tokenize (lexical analysis) | ShaderLabLexer.cs/HLSLLexer.cs | Token stream |
| Token stream | Parse syntax tree | ShaderLabParser.cs/HLSLParser.cs | Abstract Syntax Tree (AST) |
| AST | Preprocess macros | HLSLPreProcessor.cs | Expanded AST |
| Expanded AST | Validate structure | BaseSyntaxVisitor.cs | Validated AST or error |
| Validated AST | Analyze semantics | Custom visitor | Semantic information |
| Validated AST | Transform code | Custom visitor | Modified AST |
| Modified AST | Generate output | HLSLPrinter.cs/ShaderLabPrinter.cs | Output source code |
| Output source | Write to file | File system | Persisted shader |
3. Mermaid.js Architecture Diagram
Key Component Relationships
-
Core Infrastructure:
BaseLexer.cs/BaseParser.cs: Foundation for all language parsersBaseSyntaxElements.cs: Defines the syntax tree structureShaderParser.cs: Unified entry point for parsing either language
-
Language-Specific Components:
- ShaderLab: Complete parser stack from lexing to printing
- HLSL: Complete parser stack with additional preprocessing
- Both share the same core infrastructure but have language-specific syntax
-
Preprocessing:
- Only applies to HLSL (ShaderLab has minimal preprocessing)
- Handles macro expansion and conditional compilation
- Includes file resolution through
IPreProcessorIncludeResolver
-
Visitor Pattern:
- Language-specific visitors (
ShaderLabSyntaxVisitor.cs,HLSLSyntaxVisitor.cs) - Enable analysis and transformation of syntax trees
- Used extensively in tests and real-world tools
- Language-specific visitors (
-
Printers:
ShaderLabPrinter.csandHLSLPrinter.csconvert AST back to source- Enable round-trip parsing and code generation
-
Test Infrastructure:
- Comprehensive test suite covering both languages
- Test shaders from multiple sources (Nvidia, Unity, DirectX SDK)
- Validates parsing, preprocessing, and printing
This architecture demonstrates a well-structured compiler system with clear separation of concerns, enabling robust parsing of Unity shaders while maintaining extensibility for future enhancements.
π System Architecture Diagram
π οΈ 4. Function Breakdowns
.github/workflows/test-ci.yml
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
| Checkout Code | Checks out the code in the repository using actions/checkout@v4 | Retrieves the latest code for testing and building | |
| Setup Dotnet | dotnet-version: '6.0.x' | Installs the specified version of the .NET framework using actions/setup-dotnet@v3 | Configures the environment for .NET-based projects |
| Install Dependencies | Runs dotnet restore to install the project's dependencies | Ensures all required libraries and frameworks are installed | |
| Build Project | Runs dotnet build to compile the project | Compiles the source code into an executable | |
| Test with Dotnet CLI | Runs dotnet test to execute the project's tests | Verifies the functionality of the project |
README.md
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
| Introduction to UnityShaderParser | Provides an overview of the UnityShaderParser library and its components | Informs users about the library's purpose and functionality | |
| Example Usages | Lists various projects and repositories that utilize the UnityShaderParser library | Demonstrates the library's usage and versatility | |
| Acknowledgements | Credits the sources of test data and inspiration for the project | Recognizes the contributions of other projects and developers | |
| Note that the README.md file does not contain any executable code or functions, but rather serves as a documentation and information source for the UnityShaderParser library. |
However, the library itself is not provided, so a detailed function-level code breakdown cannot be performed. The actual code of the UnityShaderParser library would need to be analyzed to provide a comprehensive breakdown of its functions, parameters, logic, and impact.
Here is an example of what the breakdown might look like for a hypothetical ShaderParser class:
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
ParseShader | shaderCode: string | Parses the provided shader code into an abstract syntax tree (AST) | Enables the analysis and manipulation of shader code |
VisitAST | ast: ASTNode, visitor: ASTVisitor | Traverses the AST using the provided visitor | Allows for the analysis and modification of the shader code's syntax tree |
GenerateShaderCode | ast: ASTNode | Generates shader code from the provided AST | Enables the creation of new shader code based on the analyzed AST |
| Please provide the actual code of the UnityShaderParser library to perform a detailed analysis. |