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

Zur Installation springen

Quellinformationen

Repository
Nebulavenus/forge-gpu
Letzte Quellaktivität
29. März 2026 um 08:51
Erkannte Sprache von SKILL.md
Englisch
Sterne
38
Forks
7

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
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.
Auf GitHub ansehen