Introducing Shader Playground

TL/DR: I’ve made a new website called Shader Playground that is sort of like Compiler Explorer but for shading languages. You can compile HLSL and GLSL using fxc.exe, dxc.exe, glslangValidator.exe, spirv-cross.exe, and mali-sc.exe. You can see the compiler output and disassembly. You can chain multiple shader compilers together to transpile one language to another. You can share permalinks to shaders.

Screenshot of Shader Playground website

As you may know, I am very interested in shaders and shading languages (exhibit A, exhibit B, exhibit C, exhibit D, exhibit E). I frequently want to test little bits of shader syntax to see what the compiler does. That was why I made the Try HLSL website, first for myself and then I put it online last year. It was really very simple - type or paste HLSL code on the left, choose whether to compile with the old (fxc.exe) or new (dxc.exe) HLSL compilers, and see the disassembly (or compiler errors) on the right. It’s been quite popular - I don’t have stats on it, but my recent tweet about it was RT’d quite a bit, so I think this is something that people find useful.

However, the Try HLSL website was always a bit limited. It only worked with HLSL, and it only worked with Microsoft’s two HLSL compilers. Given the diversity of today’s shader landscape (GLSL, SPIR-V, Metal, etc.), I wanted to make it better. So I did.

Let me first list the features:

  • Multiple input languages (HLSL and GLSL, with the potential for more in the future)
  • Multiple compilers:
    • fxc.exe
    • dxc.exe
    • glslangValidator.exe
    • spirv-cross.exe
    • mali-sc.exe
  • Compiler chaining: create multiple compilation steps, so you can pipe HLSL to SPIR-V to Metal, for example.
  • Permalinks: share links to a specific “playground”, with input code and all the compilation steps saved.

Now I’ll go into more detail on some of these.

Compilers

Screenshot of compiler dropdown

The old Try HLSL site only supported Microsoft’s old and new HLSL compilers, so with Shader Playground I wanted to expand that. You can now access the following compilers. The exact ones shown in the dropdown will depend on the input language you have selected.

  • FXC - fxc.exe, Microsoft’s legacy HLSL compiler
  • DXC - dxc.exe, Microsoft’s new open-source HLSL compiler
  • glslang - glslangValidator.exe, Khronos’s reference GLSL compiler that also now has an HLSL frontend
  • SPIRV-Cross - spirv-cross.exe, Khronos’s tool for disassembling SPIR-V back into high level languages (GLSL, HLSL, Metal, C++)
  • Mali offline compiler - mali-sc.exe, ARM’s offline compiler tool

Compiler chaining

When a compiler outputs a language (or binary format) that can be fed into another compiler, you get an “Add Compiler” button. Click this, and you’ll be able to chain together up to 5 compilers. Here’s an example of compiling HLSL using DXC, outputting SPIR-V, piping that into SPIRV-Cross, and outputting GLSL:

Screenshot of compiler chaining

You get the idea. Here are the current compilers with their input and output languages. I plan to add more to this list:

  • FXC
    • Inputs:
      • HLSL
    • Outputs:
      • DXBC
  • DXC
    • Inputs:
      • HLSL
    • Outputs:
      • DXIL
      • SPIR-V
  • glslangValidator
    • Inputs:
      • GLSL
      • HLSL
    • Outputs:
      • SPIR-V
  • SPIRV-Cross
    • Inputs:
      • SPIR-V
    • Outputs:
      • GLSL
      • Metal
      • HLSL
      • C++
  • Mali offline compiler
    • Inputs:
      • GLSL
      • SPIR-V
    • Outputs:
      • [None]

You can use any valid combination of these, although right now that basically means using SPIRV-Cross somewhere in the chain.

Some compilers have multiple outputs. When using DXC or glslang, for example, you can view the abstract syntax tree (AST) from the compiler:

Screenshot of AST output

With all compilers you can view the compiler output as well as the disassembly.

Want to share a link to a shader? Once you’ve got everything setup (with whatever input code and compilers and parameters you want), click the “Share Permalink” button at the top-right:

Screenshot of Share Permalink button

That will open a dialog, and after a short wait you’ll get a URL that you can copy:

Screenshot of Share Permalink dialog

How it works

I wrote this site in C#, using ASP.NET Core. The source code is up on GitHub. It’s hosted in Azure as an App Service (not on the free plan, for reasons, so if it gets popular I might start a Patreon…). In most cases I’m calling out to the backend shader compilers using Process.Start(...), which is a bit scary because compiler options that you select on the site are passed as command line parameters to the backend compilers. I’m validating the input as best I can, and there’s a timeout on running the process, but still… please don’t break it.

I’m using GitHub Gists as the “database” for permalinks. There’s a rate limit on the GitHub API that could theoretically be hit, but I think it will be fine. If it’s not I’ll have to think of something else.

Future

Next, I plan to add more compilers:

If you have a particular compiler that you’d like me to prioritise adding, please let me know.

Or if you want to dig in yourself, the whole Shader Playground website is open source and on GitHub. Contributions or feature suggestions are welcome! Bug reports are less welcome but still appreciated :)

And a grab bag of other things I’m thinking about:

  • I’d also like to support multiple versions per compiler, so for example for dxc.exe, you’d be able to compare the outputs of multiple versions of that compiler, as it develops.
  • I’d like to add support for Unity shaders, but it’s not at all straightforward, if it’s possible at all.
  • The mobile version of the site is functional, but not ideal. My web dev knowledge is a bit out of date these days, so I need to brush up on flexbox in order to get things working how I want.

If you want an offline version of Shader Playground, I highly recommend looking at Josh Barczak’s Pyramid Shader Analyzer. I got a lot of inspiration from that project, so thank you Josh.