#shader #glsl #interactive #format

isf

Parsing, Deserialization and Serialization of the Interactive Shader Format

1 unstable release

0.1.0 Mar 22, 2020

#2214 in Parser implementations

MIT/Apache

1MB
32K SLoC

F# 31K SLoC // 0.0% comments Rust 340 SLoC

isf Build Status Crates.io Crates.io docs.rs

Parsing, deserialization and serialization of ISF - the Interactive Shader Format.

Implementation is as described under "The ISF Specification Vsn 2.0" part of the spec site.

The parse function can parse a given GLSL string to produce an Isf instance. The Isf type represents a fully structured representation of the format, including typed Inputs.

Tests

The repo includes all shaders from the "ISF Test/Tutorial filters" collection provided by the specification site along with all shaders within the "Vidvox/ISF-Files" repository for automated testing. These tests do a full roundtrip on every shader in the following steps:

  1. Read the GLSL string from file.
  2. Parse the GLSL string for the top-level dictionary.
  3. Deserialize the JSON to an Isf struct.
  4. Serialize the Isf struct back to a JSON string.
  5. Deserialize the new JSON string to an Isf struct again.
  6. Assert the first Isf instance is identical to the second.

Thanks to the Vidvox crew for allowing us to include these tests in the repo for easy automated testing!

Example

Parsing a GLSL string to an ISF struct looks like this:

let isf = isf::parse(&glsl_str).unwrap();

See the Isf struct docs to get an idea of what you can do with it!

Here's a copy of the tests/roundtrip.rs test as described above:

let test_files_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("test_files");
assert!(test_files_path.exists());
assert!(test_files_path.is_dir());
for entry in std::fs::read_dir(test_files_path).unwrap() {
    let entry = entry.unwrap();
    let path = entry.path();
    let ext = path.extension().and_then(|s| s.to_str());
    if ext == Some("fs") || ext == Some("vs") {
        let glsl_str = std::fs::read_to_string(&path).unwrap();
        let isf = match isf::parse(&glsl_str) {
            // Ignore non-ISF vertex shaders.
            Err(isf::ParseError::MissingTopComment) if ext == Some("vs") => continue,
            Err(err) => panic!("err while parsing {}: {}", path.display(), err),
            Ok(isf) => isf,
        };
        let isf_string = serde_json::to_string_pretty(&isf).unwrap();
        let isf2 = serde_json::from_str(&isf_string).unwrap();
        assert_eq!(isf, isf2);
    }
}

About

This crate has been developed as a step towards creating an ISF live-coding environment based on nannou, the creative coding framework.

Dependencies

~0.7–1.6MB
~35K SLoC