ゼロからVulkan Ray Tracing[0]

公開:2021/01/01
更新:2021/01/03
3 min読了の目安(約3500字TECH技術記事

分量が多くなったので本にまとめました。こちらの方が読みやすいと思います。

https://zenn.dev/nishiki/books/f468197dca2dd8

はじめに

2020年11月、Vulkan Ray Tracing の最終仕様がリリースされ、12月には最終仕様に対応したVulkan SDK 1.2.162.0 が公開されました。これによって開発者はマルチプラットフォームでリアルタイムレイトレーシングができるようになったと言えます。

この記事について

この記事ではVulkan Ray Tracingでゼロから三角形を出すまでの手順をステップごとに記述します。

この記事は以下のような特徴があります。

  • サードパーティの Vulkan ライブラリを使用せずゼロから記述する
  • 最終仕様に対応している
  • 公式 C++ラッパー vulkan.hpp を使うため冗長な記述がない
  • レイトレーシングに必要最低限なプログラムを目指す
  • 小さなヘルパーヘッダを 1 つだけ提供する

ヘルパーについて

レイトレーシングに関係のないVulkanのセットアップ部分についてはヘルパーでスキップできるようになっています。このヘルパーは単純な関数をまとめた程度のもので、大きなクラスは存在しません。そのため設計としては良くありませんが、簡単に読むことができるようになっています。また、このヘルパーの大部分は Vulkan Tutorial に準拠しているため、関数がよく分からない場合はこちらを参照することで理解できるはずです。

環境

  • Vulkan SDK 1.2.162.0
  • Windows10 64bit
  • NVIDIA GeForce 1070Ti
  • GEFORCE GAME READY DRIVER 460.89
  • Visual Studio 2019

2020年12月現在、最新のSDKとドライバーでなければ動かすことはできませんので注意してください。

リポジトリ

この記事で使用するプログラムはこのリポジトリに置いています。

https://github.com/nishidate-yuki/vulkan_raytracing_from_scratch

筆者について (optional)

筆者はVulkanに入門したばかりの学生で、理解が足りていない部分も多いです。Web上に間違った記述を残すべきではないと考えているため、至らない箇所があれば是非ご指摘ください。Twitter(@asta18425)のDMでも大丈夫です。

プロジェクト設定

要求

  • vulkan.hpp
  • C++17
  • GLFW

セットアップ

プロジェクトを作成して、上記の要求を満たすように設定を行ってください。

詳細な説明が必要な場合は、Vulkan Tutorialの開発環境の章を参考にすると良いと思います。この記事では vulkan.h ではなく vulkan.hpp を利用しますが、これらのファイルはSDKの同じディレクトリに含まれているので設定の変更は必要ありません。

個人的にはGLFWはvcpkgを用いて導入するのが最も簡単だと思います。

次にヘルパーをダウンロードし、プロジェクトに追加してください。ここからダウンロードできます。

https://github.com/nishidate-yuki/vulkan_raytracing_from_scratch/blob/master/code/vkutils.hpp

0. ベースコード

ベースコード

さっそくコードを書いていきます。まずはベースとなるコードを記述します。

#include "vkutils.hpp"

class Application
{
public:
    void run()
    {
        initWindow();
        initVulkan();
        mainLoop();
        cleanup();
    }

private:
    void initWindow()
    {
    }

    void initVulkan()
    {
    }

    void mainLoop()
    {
    }

    void cleanup()
    {
    }
};

int main()
{
    Application app;

    try {
        app.run();
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

エラーなく実行できることを確認してください。

GLFWでウィンドウを出す

GLFWでウィンドウを出していきます。まずはウィンドウサイズをクラスの上で定義します。

const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600;

次にウィンドウのハンドルをクラス変数に追加します。

private:
    GLFWwindow* window;

initWindow()の中でウィンドウを作成しましょう。

void initWindow()
{
    glfwInit();

    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
}

mainLoop() にループを追加します。

void mainLoop()
{
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
    }
}

cleanup()でGLFWを終了することを忘れないでください。

void cleanup()
{
    glfwDestroyWindow(window);
    glfwTerminate();
}

これで実行するとウィンドウが出るようになったはずです。

ベースとなるコードができました。次の章では Vulkan のセットアップを行っていきます。

連記事は削除しましたので、続きはこちらの本でご覧ください。記事と変わらず無料です。

https://zenn.dev/nishiki/books/f468197dca2dd8

ここまでのC++コード(00_base_code.cpp)