Home

Awesome

CxxSwizzle

vs2019 vs2022 clang-latest gcc-latest no-parallelism-apple-clang

This project lets you download and run GLSL shadertoys as C++17 code. Out of 1000 top shadertoys (on 26.11.2021), 840 compile without any code alterations and 953 compile if code patching is enabled. Code after patching is still GLSL-compatible and can be pasted back to the Shadertoy.

Here is the brilliant "DooM" shadertoy port by P_Malin, run as C++ code. "Doom Shadertoy"

Another example, "Creation" by Danilo Guanabara, being debugged in Visual Studio: Creation Debugging"

The repository is structured in the following way:

Setup

  1. Clone the repository
git clone https://github.com/gwiazdorrr/CxxSwizzle.git
  1. Init vcpkg and imgui_sdl submodules
git submodule update --init
  1. Install vcpkg dependencies (non-Windows platforms), e.g. Debian:
sudo apt-get install curl zip unzip tar
  1. Configure with CMake toolchain file and a generator of your choice. For example, using ninja:
cmake -G Ninja -B build -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake
cd build
ninja

If you are using CMake GUI, after clicking Configure select Specify toolchain file for cross-compiling and make sure the path in the next window points to vcpkg/scripts/buildsystems/vcpkg.cmake.

If you are on MacOS and using homebrew > 3.0, vcpkg (as of 11.2022) will have hard time finding pkg-config, so make sure to define following environment variables: export PKG_CONFIG=/opt/homebrew/bin/pkg-config

Downloading shadertoys

TL;DR: set SHADERTOY_DOWNLOAD to any of top_* options and run cmake.

Downloading shadertoys takes place in CMake's configure step (not great, not terrible). Note that only shadertoys with public+api visibility can be downloaded this way. The process in controlled with following properties:

Setting any of the above will trigger the download process. To avoid redownloading same shaders during next CMake's configure phase, both properties are forcefully set to an empty string and "none", respectively. After CMake's generate step is complete, each shadertoy should now be ready to build as a standalone C++ project.

Another properties relevant to downloading Shadertoys:

Use case: download specific shadertoys

  1. Set SHADERTOY_DOWNLOAD_IDS to an id of any shadertoy with public+api visiblity (e.g. WtVfRc). If you want to download a batch, separate ids with a semicolon.
  2. Click Configure in cmake-gui or run cmake

Use case: query and download shadertoys

  1. Set SHADERTOY_DOWNLOAD_QUERY_TYPE to top_love, top_popular, top_newest or top_hot.
  2. Leave SHADERTOY_DOWNLOAD_QUERY_ARG empty or set it to a search term.
  3. Set SHADERTOY_DOWNLOAD_QUERY_MAX_COUNT to limit how many shaders you want to download.
  4. Click Configure in cmake-gui or run cmake

Automatic trivial fixes

If SHADERTOY_APPLY_TRIVIAL_FIXES is enabled, shaders of a shadertoy are patched according to these rules:

Note that all these macros are easily GLSL compatible:

#define CXX_CONST const
#define CXX_IGNORE(x) x
#define CXX_ARRAY_FIELD(type, name) type[] name
#define CXX_ARRAY(type) type[]
#define CXX_ARRAY_N(type, size) type[size]
#define CXX_MAKE_ARRAY(type) type[]

Adding non public+api shadertoys

If a shadertoy can't be downloaded there's always an option of downloading it manually.

  1. If the shadertoy uses textures, they will need to be downloaded somehow. The easiest way is to use browser's DevTools (F12), switch to Network tab and refresh the shadertoy webpage. Textures should be easily found in the list of requests. Save them in SHADERTOY_TEXTURES_ROOT.
  2. Create a directory in SHADERTOY_ROOT, say SHADERTOY_ROOT/foo. That's where passes and config need to be saved to.
  3. Copy passes and save them in following files:
    • Image -> image.frag
    • Buffer A -> buffer_a.frag
    • Buffer B -> buffer_b.frag
    • Buffer C -> buffer_c.frag
    • Buffer D -> buffer_d.frag
  4. Create shadertoy_config.hpp file. This is where passes are configured. The most barebones contents are:
shadertoy_config shadertoy_config::make_default()
{
    shadertoy_config config;
    return config;
}

If the shadertoy uses textures / buffers, iChannels settings need to be replicated.

    config.get_pass(pass_type::image).get_sampler(0) = sampler_config::make_buffer(pass_type::buffer_a)
        .init(texture_wrap_modes::clamp, texture_filter_modes::nearest, true);
    config.get_pass(pass_type::buffer_a).get_sampler(1) = sampler_config::make_texture(
        "foo.jpg")
        .init(texture_wrap_modes::repeat, texture_filter_modes::mipmap, false);
    config.get_pass(pass_type::image).get_sampler(3) = sampler_config::make_cubemap({
        "face_0.png",
        "face_1.png",
        "face_2.png",
        "face_3.png",
        "face_4.png",
        "face_5.png"})
        .init(texture_wrap_modes::clamp, texture_filter_modes::linear, false);
   config.get_pass(pass_type::buffer_c).get_sampler(3) = sampler_config::make_keyboard()
       .init(texture_wrap_modes::clamp, texture_filter_modes::nearest, true);

After that's done, run cmake.

Other notable CMake options

c
1: fatal error C1083: Cannot open source file: 'C:/SRC/CxxSwizzle/build/vcpkg_installed/x64-windows/share/vc/msvc_version.c': No such file or directory

GLSL support status

Parts of GLSL Lang Spec 4.60 CxxSwizzle attempted at replicating:

Shadertoy integration status