Skip to content

Instantly share code, notes, and snippets.

@sad1e
Last active September 3, 2024 08:56
Show Gist options
  • Select an option

  • Save sad1e/a445e464f0d72b6c28c05a6f73e315f3 to your computer and use it in GitHub Desktop.

Select an option

Save sad1e/a445e464f0d72b6c28c05a6f73e315f3 to your computer and use it in GitHub Desktop.

Revisions

  1. sad1e revised this gist Sep 3, 2024. 1 changed file with 120 additions and 14 deletions.
    134 changes: 120 additions & 14 deletions fmath.h
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,12 @@
    #pragma once

    #include <cmath>
    #include <concepts>

    #define Float double

    namespace fmath {

    constexpr Float pi = 3.141592653589793;

    template <std::floating_point T>
    constexpr T clamp(T v, T mi, T ma) {
    return v <= mi ? mi : v >= ma ? ma : v;
    @@ -28,6 +28,75 @@ constexpr T mix(T x, T y, T a) {
    return x * (1 - a) + y * a;
    }

    struct vec2 {
    vec2() = default;
    vec2(const vec2& v) = default;
    vec2& operator=(const vec2& v) = default;
    vec2(vec2&& v) = default;
    vec2& operator=(vec2&& v) = default;

    explicit vec2(Float v) : x{v}, y{v} {}
    vec2(Float x_, Float y_) : x{x_}, y{y_} {}

    vec2 operator+(const vec2& v) const { return vec2{x + v.x, y + v.y}; }
    vec2& operator+=(const vec2& v) {
    x += v.x;
    y += v.y;
    return *this;
    }
    vec2 operator+(Float c) const { return vec2{x + c, y + c}; }
    vec2& operator+=(Float c) {
    x += c;
    y += c;
    return *this;
    }
    vec2 operator-(const vec2& v) const { return vec2{x - v.x, y - v.y}; }
    vec2& operator-=(const vec2& v) {
    x -= v.x;
    y -= v.y;
    return *this;
    }
    vec2 operator-(Float c) const { return vec2{x - c, y - c}; }
    vec2& operator-=(Float c) {
    x -= c;
    y -= c;
    return *this;
    }
    vec2 operator*(const vec2& v) const { return vec2{x * v.x, y * v.y}; }
    vec2& operator*=(const vec2& v) {
    x *= v.x;
    y *= v.y;
    return *this;
    }
    vec2 operator*(Float c) const { return vec2{x * c, y * c}; }
    vec2& operator*=(Float c) {
    x *= c;
    y *= c;
    return *this;
    }
    vec2 operator/(const vec2& v) const { return vec2{x / v.x, y / v.y}; }
    vec2& operator/=(const vec2& v) {
    x /= v.x;
    y /= v.y;
    return *this;
    }
    vec2 operator/(Float c) const { return vec2{x / c, y / c}; }
    vec2& operator/=(Float c) {
    x /= c;
    y /= c;
    return *this;
    }

    vec2 operator-() { return vec2{-x, -y}; }

    friend vec2 operator+(Float c, vec2 v);
    friend vec2 operator-(Float c, vec2 v);
    friend vec2 operator*(Float c, vec2 v);
    friend vec2 operator/(Float c, vec2 v);

    Float x{0}, y{0};
    };

    struct vec3 {
    vec3() = default;
    vec3(const vec3& v) = default;
    @@ -38,56 +107,64 @@ struct vec3 {
    explicit vec3(Float v) : x{v}, y{v}, z{v} {}
    vec3(Float x_, Float y_, Float z_) : x{x_}, y{y_}, z{z_} {}

    vec3 operator+(const vec3& v) { return vec3{x + v.x, y + v.y, z + v.z}; }
    vec3 operator+(const vec3& v) const {
    return vec3{x + v.x, y + v.y, z + v.z};
    }
    vec3& operator+=(const vec3& v) {
    x += v.x;
    y += v.y;
    z += v.z;
    return *this;
    }
    vec3 operator+(Float c) { return vec3{x + c, y + c, z + c}; }
    vec3 operator+(Float c) const { return vec3{x + c, y + c, z + c}; }
    vec3& operator+=(Float c) {
    x += c;
    y += c;
    z += c;
    return *this;
    }
    vec3 operator-(const vec3& v) { return vec3{x - v.x, y - v.y, z - v.z}; }
    vec3 operator-(const vec3& v) const {
    return vec3{x - v.x, y - v.y, z - v.z};
    }
    vec3& operator-=(const vec3& v) {
    x -= v.x;
    y -= v.y;
    z -= v.z;
    return *this;
    }
    vec3 operator-(Float c) { return vec3{x - c, y - c, z - c}; }
    vec3 operator-(Float c) const { return vec3{x - c, y - c, z - c}; }
    vec3& operator-=(Float c) {
    x -= c;
    y -= c;
    z -= c;
    return *this;
    }
    vec3 operator*(const vec3& v) { return vec3{x * v.x, y * v.y, z * v.z}; }
    vec3 operator*(const vec3& v) const {
    return vec3{x * v.x, y * v.y, z * v.z};
    }
    vec3& operator*=(const vec3& v) {
    x *= v.x;
    y *= v.y;
    z *= v.z;
    return *this;
    }
    vec3 operator*(Float c) { return vec3{x * c, y * c, z * c}; }
    vec3 operator*(Float c) const { return vec3{x * c, y * c, z * c}; }
    vec3& operator*=(Float c) {
    x *= c;
    y *= c;
    z *= c;
    return *this;
    }
    vec3 operator/(const vec3& v) { return vec3{x / v.x, y / v.y, z / v.z}; }
    vec3 operator/(const vec3& v) const {
    return vec3{x / v.x, y / v.y, z / v.z};
    }
    vec3& operator/=(const vec3& v) {
    x /= v.x;
    y /= v.y;
    z /= v.z;
    return *this;
    }
    vec3 operator/(Float c) { return vec3{x / c, y / c, z / c}; }
    vec3 operator/(Float c) const { return vec3{x / c, y / c, z / c}; }
    vec3& operator/=(Float c) {
    x /= c;
    y /= c;
    @@ -102,15 +179,17 @@ struct vec3 {
    friend vec3 operator*(Float c, vec3 v);
    friend vec3 operator/(Float c, vec3 v);

    Float x{0}, y{0}, z{0};
    Float x{0.0}, y{0.0}, z{0.0};
    };

    vec3 operator+(Float c, vec3 v) { return vec3{c + v.x, c + v.y, c + v.z}; }
    vec2 operator+(Float c, vec2 v) { return vec2{c + v.x, c + v.y}; }
    vec2 operator-(Float c, vec2 v) { return vec2{c - v.x, c - v.y}; }
    vec2 operator*(Float c, vec2 v) { return vec2{c * v.x, c * v.y}; }
    vec2 operator/(Float c, vec2 v) { return vec2{c / v.x, c / v.y}; }

    vec3 operator+(Float c, vec3 v) { return vec3{c + v.x, c + v.y, c + v.z}; }
    vec3 operator-(Float c, vec3 v) { return vec3{c - v.x, c - v.y, c - v.z}; }

    vec3 operator*(Float c, vec3 v) { return vec3{c * v.x, c * v.y, c * v.z}; }

    vec3 operator/(Float c, vec3 v) { return vec3{c / v.x, c / v.y, c / v.z}; }

    Float dot(const vec3& v0, const vec3& v1) {
    @@ -121,6 +200,16 @@ Float luminance(const vec3& v) {
    return v.x * 0.299 + v.y * 0.587 + v.z * 0.114;
    }

    Float pow2(Float x) { return x * x; }

    Float pow3(Float x) { return x * x * x; }

    Float pow1_4(Float x) { return std::sqrt(std::sqrt(x)); }

    Float pow4(Float x) { return x * x * x * x; }

    Float pow5(Float x) { return x * x * x * x * x; }

    vec3 pow(const vec3& b, const vec3& e) {
    return vec3{std::pow(b.x, e.x), std::pow(b.y, e.y), std::pow(b.z, e.z)};
    }
    @@ -141,4 +230,21 @@ vec3 mix(const vec3& x, const vec3& y, const vec3& a) {
    };
    }

    vec3 cross(const vec3& v0, const vec3& v1) {
    vec3 v0_yzx = vec3(v0.y, v0.z, v0.x);
    vec3 v1_yzx = vec3(v1.y, v1.z, v1.x);
    vec3 v2 = v0 * v1_yzx - v0_yzx * v1;
    return vec3{v2.y, v2.z, v2.x};
    }

    vec3 sqrt(const vec3& v) {
    return vec3{std::sqrt(v.x), std::sqrt(v.y), std::sqrt(v.z)};
    }

    vec3 rsqrt(const vec3& v) { return 1.0 / fmath::sqrt(v); }

    vec3 normalize(const vec3& v) { return rsqrt(vec3(dot(v, v))) * v; }

    Float rcp(Float x) { return (Float)1.0 / x; }

    } // namespace fmath
  2. sad1e revised this gist Aug 19, 2024. No changes.
  3. sad1e revised this gist Aug 17, 2024. 1 changed file with 0 additions and 18 deletions.
    18 changes: 0 additions & 18 deletions fmath.h
    Original file line number Diff line number Diff line change
    @@ -3,13 +3,7 @@
    #include <cmath>
    #include <concepts>

    #define USE_DOUBLE 1

    #ifdef USE_DOUBLE
    #define Float double
    #else
    #define Float float
    #endif

    namespace fmath {

    @@ -128,27 +122,15 @@ Float luminance(const vec3& v) {
    }

    vec3 pow(const vec3& b, const vec3& e) {
    #if USE_DOUBLE
    return vec3{std::pow(b.x, e.x), std::pow(b.y, e.y), std::pow(b.z, e.z)};
    #else
    return vec3{std::powf(b.x, e.x), std::powf(b.y, e.y), std::powf(b.z, e.z)};
    #endif
    }

    vec3 sin(const vec3& v) {
    #if USE_DOUBLE
    return vec3{std::sin(v.x), std::sin(v.y), std::sin(v.z)};
    #else
    return vec3{std::sinf(v.x), std::sinf(v.y), std::sinf(v.z)};
    #endif
    }

    vec3 cos(const vec3& v) {
    #if USE_DOUBLE
    return vec3{std::cos(v.x), std::cos(v.y), std::cos(v.z)};
    #else
    return vec3{std::cosf(v.x), std::cosf(v.y), std::cosf(v.z)};
    #endif
    }

    vec3 mix(const vec3& x, const vec3& y, const vec3& a) {
  4. sad1e revised this gist Aug 17, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion parula.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    The parula color map from matlab, created by https://shadertoy.com/view/fdXSDS.
    Generate parula color map via C++, from https://shadertoy.com/view/fdXSDS.
  5. sad1e revised this gist Aug 17, 2024. 2 changed files with 229 additions and 0 deletions.
    162 changes: 162 additions & 0 deletions fmath.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,162 @@
    #pragma once

    #include <cmath>
    #include <concepts>

    #define USE_DOUBLE 1

    #ifdef USE_DOUBLE
    #define Float double
    #else
    #define Float float
    #endif

    namespace fmath {

    template <std::floating_point T>
    constexpr T clamp(T v, T mi, T ma) {
    return v <= mi ? mi : v >= ma ? ma : v;
    }

    template <std::floating_point T>
    constexpr T saturate(T v) {
    return clamp(v, 0.0, 1.0);
    }

    template <std::floating_point T>
    constexpr T smoothstep(T a, T b, T x) {
    T t = saturate((x - a) / (b - a));
    return t * t * (3.0 - (2.0 * t));
    }

    template <std::floating_point T>
    constexpr T mix(T x, T y, T a) {
    return x * (1 - a) + y * a;
    }

    struct vec3 {
    vec3() = default;
    vec3(const vec3& v) = default;
    vec3& operator=(const vec3& v) = default;
    vec3(vec3&& v) = default;
    vec3& operator=(vec3&& v) = default;

    explicit vec3(Float v) : x{v}, y{v}, z{v} {}
    vec3(Float x_, Float y_, Float z_) : x{x_}, y{y_}, z{z_} {}

    vec3 operator+(const vec3& v) { return vec3{x + v.x, y + v.y, z + v.z}; }
    vec3& operator+=(const vec3& v) {
    x += v.x;
    y += v.y;
    z += v.z;
    return *this;
    }
    vec3 operator+(Float c) { return vec3{x + c, y + c, z + c}; }
    vec3& operator+=(Float c) {
    x += c;
    y += c;
    z += c;
    return *this;
    }
    vec3 operator-(const vec3& v) { return vec3{x - v.x, y - v.y, z - v.z}; }
    vec3& operator-=(const vec3& v) {
    x -= v.x;
    y -= v.y;
    z -= v.z;
    return *this;
    }
    vec3 operator-(Float c) { return vec3{x - c, y - c, z - c}; }
    vec3& operator-=(Float c) {
    x -= c;
    y -= c;
    z -= c;
    return *this;
    }
    vec3 operator*(const vec3& v) { return vec3{x * v.x, y * v.y, z * v.z}; }
    vec3& operator*=(const vec3& v) {
    x *= v.x;
    y *= v.y;
    z *= v.z;
    return *this;
    }
    vec3 operator*(Float c) { return vec3{x * c, y * c, z * c}; }
    vec3& operator*=(Float c) {
    x *= c;
    y *= c;
    z *= c;
    return *this;
    }
    vec3 operator/(const vec3& v) { return vec3{x / v.x, y / v.y, z / v.z}; }
    vec3& operator/=(const vec3& v) {
    x /= v.x;
    y /= v.y;
    z /= v.z;
    return *this;
    }
    vec3 operator/(Float c) { return vec3{x / c, y / c, z / c}; }
    vec3& operator/=(Float c) {
    x /= c;
    y /= c;
    z /= c;
    return *this;
    }

    vec3 operator-() { return vec3{-x, -y, -z}; }

    friend vec3 operator+(Float c, vec3 v);
    friend vec3 operator-(Float c, vec3 v);
    friend vec3 operator*(Float c, vec3 v);
    friend vec3 operator/(Float c, vec3 v);

    Float x{0}, y{0}, z{0};
    };

    vec3 operator+(Float c, vec3 v) { return vec3{c + v.x, c + v.y, c + v.z}; }

    vec3 operator-(Float c, vec3 v) { return vec3{c - v.x, c - v.y, c - v.z}; }

    vec3 operator*(Float c, vec3 v) { return vec3{c * v.x, c * v.y, c * v.z}; }

    vec3 operator/(Float c, vec3 v) { return vec3{c / v.x, c / v.y, c / v.z}; }

    Float dot(const vec3& v0, const vec3& v1) {
    return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z;
    }

    Float luminance(const vec3& v) {
    return v.x * 0.299 + v.y * 0.587 + v.z * 0.114;
    }

    vec3 pow(const vec3& b, const vec3& e) {
    #if USE_DOUBLE
    return vec3{std::pow(b.x, e.x), std::pow(b.y, e.y), std::pow(b.z, e.z)};
    #else
    return vec3{std::powf(b.x, e.x), std::powf(b.y, e.y), std::powf(b.z, e.z)};
    #endif
    }

    vec3 sin(const vec3& v) {
    #if USE_DOUBLE
    return vec3{std::sin(v.x), std::sin(v.y), std::sin(v.z)};
    #else
    return vec3{std::sinf(v.x), std::sinf(v.y), std::sinf(v.z)};
    #endif
    }

    vec3 cos(const vec3& v) {
    #if USE_DOUBLE
    return vec3{std::cos(v.x), std::cos(v.y), std::cos(v.z)};
    #else
    return vec3{std::cosf(v.x), std::cosf(v.y), std::cosf(v.z)};
    #endif
    }

    vec3 mix(const vec3& x, const vec3& y, const vec3& a) {
    return vec3{
    mix(x.x, y.x, a.x),
    mix(x.y, y.y, a.y),
    mix(x.z, y.z, a.z),
    };
    }

    } // namespace fmath
    67 changes: 67 additions & 0 deletions generate_parula.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    namespace parula {

    Float cheaplobe(Float x, Float m, Float w) {
    return fmath::smoothstep(m - w, m, x) * fmath::smoothstep(m + w, m, x);
    }

    fmath::vec3 heatmap(Float c) {
    return fmath::pow(
    0.5 * (1.0 + fmath::cos(3.1 * c - fmath::vec3(2.7, 1.3, -0.2))),
    fmath::vec3(3., 3., 4.));
    }

    fmath::vec3 heatmap(fmath::vec3 c) {
    return fmath::pow(
    0.5 * (1.0 + fmath::cos(3.1 * c - fmath::vec3(2.7, 1.3, -0.2))),
    fmath::vec3(3., 3., 4.));
    }

    fmath::vec3 parula(Float c) {
    fmath::vec3 d = fmath::vec3(
    -0.1 + 0.22 * cheaplobe(c, 0.83, 0.19) - 0.07 * cheaplobe(c, 0.55, 0.16),
    0.02 - 0.21 * cheaplobe(c, 0.83, 0.26) -
    0.23 * cheaplobe(c, -0.02, 0.14) - 0.03 * cheaplobe(c, 0.59, 0.12),
    -0.11 * cheaplobe(c, 0.57, 0.2));
    fmath::vec3 w =
    fmath::vec3(0.52, 0.5, 0.53) +
    fmath::vec3(0.52, 0.52, 0.45) *
    fmath::sin(fmath::vec3(2.80, 2.80, 2.04) *
    (fmath::vec3(c) - fmath::vec3(0.4, 0.4, -0.63)));
    fmath::vec3 p = fmath::vec3(fmath::mix(0.7, 0.8, c), fmath::mix(0.3, 0.7, c),
    fmath::mix(2.9, 2.2, c));
    return fmath::pow(d + fmath::pow(w, p), fmath::vec3(1.5));
    }

    fmath::vec3 parula(fmath::vec3 c) {
    Float l = luminance(c);
    fmath::vec3 d = fmath::vec3(
    -0.1 + 0.22 * cheaplobe(l, 0.83, 0.19) - 0.07 * cheaplobe(l, 0.55, 0.16),
    0.02 - 0.21 * cheaplobe(l, 0.83, 0.26) -
    0.23 * cheaplobe(l, -0.02, 0.14) - 0.03 * cheaplobe(l, 0.59, 0.12),
    -0.11 * cheaplobe(l, 0.57, 0.2));
    fmath::vec3 w = fmath::vec3(0.52, 0.5, 0.53) +
    fmath::vec3(0.52, 0.52, 0.45) *
    fmath::sin(fmath::vec3(2.80, 2.80, 2.04) *
    (c - fmath::vec3(0.4, 0.4, -0.63)));
    fmath::vec3 p =
    fmath::vec3(fmath::mix(0.7, 0.8, c.x), fmath::mix(0.3, 0.7, c.y),
    fmath::mix(2.9, 2.2, c.z));
    return fmath::pow(d + fmath::pow(w, p), fmath::vec3(1.5));
    }

    } // namespace parula

    void GenerateParulaColormap() {
    int width = 1024;
    int height = 32;

    pngwriter png(width, height, 0, "Parula.png");
    for (int i = 1; i <= width; ++i) {
    double uv_x = (double)i / width;
    fmath::vec3 v = parula::parula(uv_x);
    for (int j = 1; j <= height; ++j) {
    png.plot(i, j, v.x, v.y, v.z);
    }
    }
    png.close();
    }
  6. sad1e revised this gist Aug 17, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion parula.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    The parula from matlab, created by https://shadertoy.com/view/fdXSDS.
    The parula color map from matlab, created by https://shadertoy.com/view/fdXSDS.
  7. sad1e created this gist Aug 17, 2024.
    1 change: 1 addition & 0 deletions parula.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    The parula from matlab, created by https://shadertoy.com/view/fdXSDS.