NEUROMANTIC

自分でC/C++/UE4/Graphics/ゲームなどなどをやったことを記すブログです。日本語以外の国語が混ざることがあります。

ShaderToyで「Nier:Automata」の後処理っぽくレンダリングしてみた。

はじめに

sawcegames.com

今回はスクエア・エニックスさんのNier Automataの様々な後処理効果をShaderToyで再現してみようかとします。上のリンクから提供するチュートリアルを見ながら、HLSLコードをShaderToyが支援するGLSLに移してみたいと思います。

続きを読む

「一流グラフィックスプログラマへの道~リアルタイム編~」の感想及びメモ。

はじめに

いろいろとプロジェクトを作っているのですが、実は私はゲームのグラフィックスに興味があります。
そしてゲーム開発界隈に入ってから最終的にはローレベルを弄りまくるグラフィックスプログラマになりたいです。
(エンジンを底を触りながらグラフィックスなんてちょっととんでもなさそうですけどね)

raytracing.hatenablog.com

それで一昔前に「一流グラフィックスプログラマへの道~リアルタイム編~」という記事を発見してお読みしました。今から3年の前の記事ですが、ローレベルのグラフィックスプログラマを目指している私には物凄く役に立ちそうな記事でしたので精読させていただきました。それで私が感じた感想やメモなどをブログにて書いていきたいと思います。

続きを読む

Modern C++ Design Chapter 2 Memo (1)

2.2 Partial Template Specialization

  • クラスに対しての部分特殊化は通じるが、メンバー関数や一般関数での部分特殊化は出来ない。
  • 関数をテンプレートに対して部分的に特殊化したい場合なら、以下のようにオーバーローディングをするしかない。
template <class T, class U> T Func(U obj);
template <class U> void Fun<void, U>(U obj); // Prohibited.
template <class T> T Fun(Window obj); // Legal (overloading)

2.3 Local Classes

void Func() {
  class Local {
    // ... Member variables ...
    // ... Member function definitions ...
  };
  // Code using local...
}
  • 関数の中身にクラスの定義がある場合、このクラスはローカルクラスという。
  • ローカルクラスは静的変数が定義出来ない。そして関数の外からはローカルクラスの変数には接近できない。
  • ローカルクラスは関数の外からはローカルクラスを継承出来ない。

ローカルクラスを使用し、インタフェースを継承したクロージャーなどを実装することが出来る。

class Interface {
public:
  virtual void Fun() = 0;
};

template <class T, class P>
std::unique_ptr<Interface> MakeAdapter(const T& obj, const P& arg) {
  class Local : public Interface {
  public:
    Local(const T& obj, const P& arg) :
      obj_(obj), arg_(arg) {};

    virtual void Fun() { 
      obj_.Call(arg_);
    }
  private:
    T obj_;
    P arg_;
  };
  return std::make_unique<Local>(obj, arg);
}

2.5 Type-to-Type Mapping

#include <cstdint>
#include <vector>

template <typename TFrom, typename TTo>
class Conversion {
    using TSmall = char;
    class DBig { char dummy[2]; };

    static constexpr TSmall Test(const TTo&);
    static constexpr DBig Test(...);
    static constexpr TFrom MakeT();

public:
    static constexpr bool exists = sizeof(Conversion::Test(MakeT())) == sizeof(TSmall);
};

template <typename TFrom, typename TTo>
class ConversionExt : public Conversion<TFrom, TTo> {
public:
    static constexpr bool sameType = false;
};

template <typename TFrom>
class ConversionExt<TFrom, TFrom> : public Conversion<TFrom, TFrom> {
public:
    static constexpr bool sameType = true;
};

static_assert(Conversion<double, int>::exists, "");
static_assert(Conversion<char, char*>::exists, "");
static_assert(Conversion<std::size_t, std::vector<int>>::exists, "");

class Base {};
class Derived final : public Base {};
class NotDerived final {};

static_assert(Conversion<Derived, Base>::exists, "");
static_assert(Conversion<Base, Derived>::exists, "");
static_assert(Conversion<NotDerived, Base>::exists, "");

template <typename T, typename V>
constexpr bool IsSuperClass =
    (ConversionExt<T, V>::exists == true) && 
    (ConversionExt<T, const void*>::sameType == false);

static_assert(IsSuperClass<const Derived*, const Base*>, "");
static_assert(IsSuperClass<const NotDerived*, const Base*>, "");
static_assert(IsSuperClass<const Base*, const Base*>, "");

template <typename T, typename V>
constexpr bool IsSuperClassStrict = 
    IsSuperClass<T, V> && (ConversionExt<T, V>::sameType == false);

static_assert(IsSuperClassStrict<const Derived*, const Base*>, "");
static_assert(IsSuperClassStrict<const NotDerived*, const Base*>, "");
static_assert(IsSuperClassStrict<const Base*, const Base*>, "");