원클릭으로
forge-pbr-textures
Add PBR texture loading with separate roughness/metallic support to an SDL GPU project using forge_scene.h
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Add PBR texture loading with separate roughness/metallic support to an SDL GPU project using forge_scene.h
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Add Cook-Torrance PBR shading with GGX, Schlick-GGX, and Schlick Fresnel to an SDL GPU project alongside forge_scene.h
Add instanced grass rendering with segmented blades, wind animation, LOD density rings, and terrain LOD with geomorphing to an SDL GPU project
Add procedural noise texture generation to the asset pipeline — C tool, Python plugin, web UI with live preview
Add an asset pipeline lesson — hybrid Python + C track for asset processing, procedural geometry, and web frontend
Add an audio lesson — sound playback, mixing, spatial audio, DSP effects, with SDL GPU scenes and forge UI
Run a quality review pass on a lesson before publishing, catching recurring issues found across project PR history
| 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).
.fmat sidecar files/* 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);
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 |
The shininess field in ForgeSceneModelFragUniforms (offset 80, unused by
PBR) is repurposed as use_separate_mr:
ForgeSceneModelFragUniforms fu;
forge_scene__fill_model_frag_uniforms(scene, mat, &fu);
fu.shininess = (tex.roughness || tex.metallic) ? 1.0f : 0.0f;
In the shader:
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;
}
| 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 |
metallic_roughness_texture before loading separate —
if both packed and separate exist, prefer packedSee Lesson 52 — PBR Textures for the full implementation.