4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Siv3DでPBR(物理ベースレンダリング)を実装してみた!

Last updated at Posted at 2025-12-23

Siv3Dで物理ベースレンダリング実装してみた!

Albedo(BaseColor)編(順次追加予定)

今回は、Siv3Dで、物理ベースレンダリング(PBR)の最初のステップである
Albedo(BaseColor) を実装してみます。

まずは、3D空間に Box を描画してみましょう。

Siv3D には、あらかじめ Box を生成するための API が用意されています。

# include <Siv3D.hpp> // Siv3D v0.6.16

Main.cpp 全体

まず、今回使用している Main.cpp の全体像を先に示します。
記事中では後ほど各要素を分解して解説します。

# include <Siv3D.hpp> // Siv3D v0.6.16

void Main()
{
    const ColorF backGroundColor = ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve();

    const PixelShader psPBR = HLSL{ U"PBR_PS.hlsl", U"PS" };
    if (!psPBR)
    {
        Print << U"Failed to load PBR_PS.hlsl";
    }

    const MSRenderTexture renderTexture{
        Scene::Size(),
        TextureFormat::R8G8B8A8_Unorm_SRGB,
        HasDepth::Yes
    };

    DebugCamera3D camera{
        renderTexture.size(),
        30_deg,
        Vec3{ 10, 16, -32 }
    };

    Mesh mesh{ MeshData::Box(2.0) };

    while (System::Update())
    {
        camera.update(2.0);
        Graphics3D::SetCameraTransform(camera);

        const ScopedRenderTarget3D target{
            renderTexture.clear(backGroundColor)
        };

        {
            ScopedCustomShader3D shader{ psPBR };
            mesh.draw();
        }

        Graphics3D::Flush();
        renderTexture.resolve();
        Shader::LinearToScreen(renderTexture);
    }
}

Box を Mesh として用意する

Siv3D では、MeshData::Box() を使うことで簡単に立方体メッシュを生成できます。

Mesh mesh{ MeshData::Box(2.0) };

今回は、この Box に対して カスタム PixelShader を適用します。


RenderTexture を用意する

PBR では Linear 空間で計算し、sRGB で表示する ことが重要です。
そのため、今回は RenderTexture を経由して描画します。

const MSRenderTexture renderTexture{
    Scene::Size(),
    TextureFormat::R8G8B8A8_Unorm_SRGB,
    HasDepth::Yes
};

カメラの設定

デバッグ用として DebugCamera3D を使用します。

DebugCamera3D camera{
    renderTexture.size(),
    30_deg,
    Vec3{ 10, 16, -32 }
};

Pixel Shader(Albedoのみ)

今回は、PBR の最初の段階として
Albedo(BaseColor)だけを出力する Pixel Shader を書きます。

cbuffer PSConstants : register(b0)
{
    float3 cameraPos;
    float metallic;
    float roughness;
    float3 albedo;
}

struct PSInput
{
    float4 pos      : SV_POSITION;
    float3 worldPos : POSITION0;
    float3 normal   : NORMAL0;
};

float4 PS(PSInput input) : SV_TARGET
{
    float3 linearColor = float3(1.0, 0.0, 0.0);
    return float4(linearColor, 1.0);
}

描画ループ

カスタム Pixel Shader を ScopedCustomShader3D で適用します。

while (System::Update())
{
    camera.update(2.0);
    Graphics3D::SetCameraTransform(camera);

    const ScopedRenderTarget3D target{
        renderTexture.clear(ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve())
    };

    {
        ScopedCustomShader3D shader{ psPBR };
        mesh.draw();
    }

    Graphics3D::Flush();
    renderTexture.resolve();
    Shader::LinearToScreen(renderTexture);
}

ここまで、進むとBoxが赤くなります。

スクリーンショット 2025-12-23 185510.png


まとめ

  • Siv3D でもカスタムシェーダを使った PBR 実装が可能
  • 今回は Albedo(BaseColor)のみ を描画
  • 次回は未定(できればライティングとか)
4
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?