https://github.com/ppenenko/metashade Navigation Menu Skip to content Toggle navigation Sign in * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions For + Enterprise + Teams + Startups + Education By Solution + CI/CD & Automation + DevOps + DevSecOps Resources + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} ppenenko / metashade Public * Notifications * Fork 1 * Star 25 * An experimental GPU shading DSL embedded in Python. License Apache-2.0 license 25 stars 1 fork Branches Tags Activity Star Notifications * Code * Issues 11 * Pull requests 0 * Discussions * Actions * Projects 1 * Security * Insights Additional navigation options * Code * Issues * Pull requests * Discussions * Actions * Projects * Security * Insights ppenenko/metashade This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main BranchesTags Go to file Code Folders and files Name Name Last commit message Last commit date Latest commit History 350 Commits .vscode .vscode examples examples gltfdemo gltfdemo metashade metashade tests tests .gitignore .gitignore LICENSE LICENSE README.md README.md View all files Repository files navigation * README * Apache-2.0 license Metashade What is Metashade? Metashade is an experimental GPU shading domain-specific language (DSL) embedded in Python. When a Metashade script executes, it generates code in a target shading language. Only HLSL is supported so far but the intent is definitely to support multiple targets. To see Metashade in action, check out the glTF demo. Please see the presentation on Google Slides for a detailed discussion of the motivation for Metashade and its design. Rationale * Programming at a more abstract level than the target language: + Metaprogramming - think C++ templates but with greater flexibility. Like any other Python code, Mestashade code is polymorphic at generation time. This approach can replace the traditional ubershader practice, effectively replacing the C preprocessor with Python. + Stricter typing - e.g. a 3D point and an RGB color can be represented with different Metashade types, backed by the same data type in HLSL. * Multi-language/cross-platform support. Cross-compilation (e.g. with SPIRV-Cross) is definitely an alternative but the code generation approach should offer higher flexibility around: + more divergent languages, e.g. HLSL vs OSL; + language dialects; + integration required by the specific host application (a shader fragment with an interface defined in metadata, an effect file etc.), which is hard to accomplish with cross-compilation because it typically operates on final, full shaders with a defined entry point. * Easy integration with content pipeline and build system scripts written in Python, and the vast Python ecosystem in general. How does it work? Unlike some other Python DSLs, Metashade doesn't rely on introspection to translate the Python AST to the target language. It uses more straight-forward mechanisms in hopes of making the DSL appear less magical to the user and enabling integration with other Python code. Creating a generator Before Metashade can generate anything, a generator object has to be created for a specific target shading language profile, with an output file (or a file-like stream object) passed as a constructor argument, e.g. from metashade.hlsl.sm6 import ps_6_0 with open("ps.hlsl", 'w') as ps_file: sh = ps_6_0.Generator(ps_file) Note that, by convention, the generator object is always named sh (for "shader"). This helps Metashade code be polymorphic with regard to different target profiles. E.g. code with the same logic can be generated for an HLSL pixel shader and a GLSL compute shader. Function definitions Metashade function definition syntax looks like this: with sh.function('add', sh.Float4)(a = sh.Float4, b = sh.Float4): sh.return_(sh.a + sh.b) Here, the first pair of parentheses defines the function name and the return type, while the second pair contains parameter declarations with their types. All data types here can be determined dynamically at generation time and become static in the generated code. The above Python code generates the following HLSL: float4 add(float4 a, float4 b) { return (a + b); } Entry points Shader entry points are really just a special case of functions in Metashade, for example: with sh.ps_output('PsOut') as PsOut: PsOut.SV_Target('color', sh.RgbaF) with sh.main('mainPS', sh.PsOut)(): sh.psOut = sh.PsOut() sh.psOut.color.rgb = sh.RgbF(1) sh.psOut.color.a = 1 sh.return_(sh.psOut) Which generates in HLSL: struct PsOut { float4 color : SV_TARGET; }; PsOut mainPS() { PsOut psOut; psOut.color.rgb = 1.0.xxx; psOut.color.a = 1.0; return psOut; } Generating C-like scopes and local variables Metashade uses Python variables to represent variables in target C-like shading languages, but there obviously major differences in their behavior, namely: * Unlike in Python, lifetimes of variables in C-like languages are tied to the scope they're defined in. * In Python, variables are always assigned by reference and the same variable can point to different objects of different types in its lifetime. Variables in C-like shading languages, in contrast, are typed statically and are assigned by value. Addressing these differences requires explicit emulation in Python code. with scopes are the closest analogy for C-like scopes in Python, however they only apply to the variables referenced in the with statement and call the special __enter__ and __exit__ methods instead of construction and destruction like in C++. That's why Metashade uses with statements with special objects such as function definitions created with sh.function, which modify the state of the generator. The generator emulates C-like scopes internally, and and the generated variables are modeled with member variables on the generator, which are implemented with the __getattr__()/__setattr__() Python mechanism. With __setattr__() for example, we can capture the variable's name without Python introspection. We can also easily check in __setattr__() if the user is trying to reinitialize the variable with a different type and we can similarly raise an exception in __getattr__() if the user tries to access a variable that's gone out of scope. The __getattr__()/__setattr__() is also used for other features, such as accessing struct members and vector elements. Further, Python expressions model expressions in the target language with help of operator overloading. Basically, a + b generates the respective operation in the target language instead of performing the addition in Python. About An experimental GPU shading DSL embedded in Python. Topics python shaders dsl computer-graphics metaprogramming edsl shading-language Resources Readme License Apache-2.0 license Activity Stars 25 stars Watchers 4 watching Forks 1 fork Report repository Releases 3 v0.4.2 Latest Mar 10, 2024 + 2 releases Packages 0 No packages published Languages * Python 74.6% * HLSL 25.4% Footer (c) 2024 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact * Manage cookies * Do not share my personal information You can't perform that action at this time.