Skip to main content

forge-pbr-textures

Add PBR texture loading with separate roughness/metallic support to an SDL GPU project using forge_scene.h

インストールへ移動

ソース情報

リポジトリ
Nebulavenus/forge-gpu
ソースの最終更新活動
2026年3月29日 08:51
検出された SKILL.md の言語
英語
スター
38
フォーク
7

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
forge-pbr-textures
description
Add PBR texture loading with separate roughness/metallic support to an SDL GPU project using forge_scene.h
Load PBR material texture sets (albedo, normal, roughness, metallic, AO, emissive) from the asset pipeline and render them with a Cook-Torrance BRDF shader. Supports both packed metallic-roughness (glTF convention) and separate single-channel textures (ambientCG convention). ## When to use - Loading PBR materials from `.fmat` sidecar files - Rendering textured PBR materials on scene models - Supporting both packed and separate metallic-roughness workflows - Adding multiple material support to a scene ## Material loading pattern ```c /* Parse .fmat sidecar */ ForgePipelineMaterialSet mat_set; if (!forge_pipeline_load_materials("assets/materials/Rock026/Rock026.fmat", &mat_set) || mat_set.material_count == 0) { SDL_Log("Failed to load Rock026 material"); return false; } const ForgePipelineMaterial *mat = &mat_set.materials[0]; /* Load textures from processed assets. * vram tracks GPU memory usage — must be non-NULL. */ ForgeSceneVramStats vram = {0}; ForgeSceneModelTextures tex = {0}; /* Base color — sRGB (authored color) */ tex.base_color = forge_scene_load_pipeline_texture( scene, &vram, "assets/materials/Rock026/Rock026_Color.png", true, false); /* Normal map — linear, is_normal_map=true for BC5 */ tex.normal = forge_scene_load_pipeline_texture( scene, &vram, "assets/materials/Rock026/Rock026_NormalGL.png", false, true); /* Separate roughness — linear */ tex.roughness = forge_scene_load_pipeline_texture( scene, &vram, "assets/materials/Rock026/Rock026_Roughness.png", false, false); /* AO — linear, R channel */ tex.occlusion = forge_scene_load_pipeline_texture( scene, &vram, "assets/materials/Rock026/Rock026_AmbientOcclusion.png", false, false); ``` ## 8-sampler PBR pipeline The shader uses 8 texture slots to support both packed and separate workflows: | Slot | Texture | Color space | Fallback | |------|---------|-------------|----------| | 0 | Base color | sRGB | White | | 1 | Normal map | Linear | Flat (+Z) | | 2 | Packed metallic-roughness | Linear | White | | 3 | Occlusion (AO) | Linear | White | | 4 | Emissive | sRGB | Black | | 5 | Shadow map | Depth | Scene shadow | | 6 | Separate roughness | Linear | White | | 7 | Separate metallic | Linear | White | ## Separate MR flag The `shininess` field in `ForgeSceneModelFragUniforms` (offset 80, unused by PBR) is repurposed as `use_separate_mr`: ```c ForgeSceneModelFragUniforms fu; forge_scene__fill_model_frag_uniforms(scene, mat, &fu); fu.shininess = (tex.roughness || tex.metallic) ? 1.0f : 0.0f; ``` In the shader: ```hlsl if (use_separate_mr > 0.5) { roughness = roughness_tex.Sample(roughness_smp, input.uv).r * roughness_factor; metallic = metallic_tex.Sample(metallic_smp, input.uv).r * metallic_factor; } else { float2 mr = mr_tex.Sample(mr_smp, input.uv).bg; metallic = mr.x * metallic_factor; roughness = mr.y * roughness_factor; } ``` ## sRGB vs linear | Data type | Color space | Why | |-----------|-------------|-----| | Base color, emissive | sRGB | Authored as visible color — GPU linearizes on sample | | Normal, roughness, metallic, AO | Linear | Physical parameters — gamma would distort values | ## Common mistakes - **Loading roughness as sRGB** — makes 0.5 appear as ~0.22, materials look too shiny - **Loading normal maps with sRGB** — corrupts direction vectors, surface detail is lost - **Forgetting the use_separate_mr flag** — shader reads packed MR texture (white fallback = all 1.0), making everything fully metallic and rough - **Not checking `metallic_roughness_texture` before loading separate** — if both packed and separate exist, prefer packed ## Reference See [Lesson 52 — PBR Textures](../../../lessons/gpu/52-pbr-textures/) for the full implementation.
GitHubで見る