Install
$ agentstack add skill-nebulavenus-forge-gpu-forge-atlas-rendering ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Atlas-Based Texture Rendering
Add texture atlas rendering to an SDL GPU project. Loads pre-packed atlas metadata (UV offset/scale per material), remaps UVs in the fragment shader, and binds a single atlas texture instead of N per-material textures.
Based on [GPU Lesson 47](../../../lessons/gpu/47-texture-atlas-rendering/).
Prerequisites
- An atlas image (PNG) and metadata file (atlas.json) generated by the
pipeline's atlas plugin ([Asset Lesson 17](../../../lessons/assets/17-texture-atlas/))
forge_pipeline.hforforge_pipeline_load_atlas()- cJSON (third_party/cJSON) for JSON parsing
Atlas metadata format
{
"version": 1,
"width": 2048,
"height": 2048,
"padding": 4,
"utilization": 0.499,
"entries": {
"material_name": {
"x": 4, "y": 4, "width": 256, "height": 256,
"u_offset": 0.002, "v_offset": 0.002,
"u_scale": 0.125, "v_scale": 0.125
}
}
}
C setup
#define FORGE_PIPELINE_IMPLEMENTATION
#include "pipeline/forge_pipeline.h"
/* Load atlas metadata */
ForgePipelineAtlas atlas_meta;
if (!forge_pipeline_load_atlas("assets/atlas.json", &atlas_meta)) {
SDL_Log("Failed to load atlas metadata");
return SDL_APP_FAILURE;
}
/* Load atlas texture (single image containing all materials) */
SDL_GPUTexture *atlas_texture = load_png_texture(device, "assets/atlas.png");
/* Create sampler with clamp-to-edge to prevent atlas bleeding */
SDL_GPUSamplerCreateInfo si;
SDL_zero(si);
si.min_filter = SDL_GPU_FILTER_LINEAR;
si.mag_filter = SDL_GPU_FILTER_LINEAR;
si.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
si.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
si.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
si.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
Key API calls
forge_pipeline_load_atlas(path, &atlas)— parse atlas.json into
ForgePipelineAtlas with per-entry UV offset/scale
forge_pipeline_free_atlas(&atlas)— release parsed atlas metadataSDL_BindGPUFragmentSamplers(pass, 0, &bind, 1)— bind the atlas texture
once before the draw loop (the state change this pattern eliminates)
SDL_PushGPUFragmentUniformData(cmd, 0, &fu, sizeof(fu))— push per-object
UV transform selecting the correct atlas region
Fragment shader (HLSL)
cbuffer FragUniforms : register(b0, space3) {
float4 uv_transform; /* xy = offset, zw = scale */
/* ... lighting params ... */
};
Texture2D material_tex : register(t0, space2);
SamplerState material_smp : register(s0, space2);
float4 main(PSInput input) : SV_Target {
/* Atlas UV remapping: transform original UVs to atlas coordinates */
float2 atlas_uv = input.uv * uv_transform.zw + uv_transform.xy;
float4 albedo = material_tex.Sample(material_smp, atlas_uv);
/* ... lighting ... */
}
Atlas entry lookup
Build a material-to-entry index table at init time to avoid per-frame string comparisons and to decouple material order from atlas JSON insertion order:
/* Init: build material → atlas entry index lookup */
int atlas_entry_idx[MATERIAL_COUNT];
for (int i = 0; i = 0) {
ForgePipelineAtlasEntry *e = &atlas_meta.entries[idx];
uv[0] = e->u_offset; uv[1] = e->v_offset;
uv[2] = e->u_scale; uv[3] = e->v_scale;
}
forge_scene_draw_textured_mesh_no_bind(
scene, vb, ib, index_count, model, uv);
}
Backwards compatibility
For models that don't use an atlas, pass identity UV transform values:
fu.uv_transform[0] = 0.0f; fu.uv_transform[1] = 0.0f;
fu.uv_transform[2] = 1.0f; fu.uv_transform[3] = 1.0f;
This makes the shader work identically for both atlas and individual texture modes — only the bound texture and uniform values differ.
Cleanup
forge_pipeline_free_atlas(&atlas_meta);
SDL_ReleaseGPUTexture(device, atlas_texture);
SDL_ReleaseGPUSampler(device, sampler);
Common mistakes
- Using
REPEATaddress mode: atlas textures must useCLAMP_TO_EDGE—
repeat mode wraps UVs into adjacent material regions, producing visible seams and color bleeding.
- Forgetting identity transform for non-atlas objects: when mixing atlas
and individual textures in the same shader, pass vec4_create(0.0f, 0.0f, 1.0f, 1.0f) as the UV transform for individual textures so the remap becomes a no-op.
- Looking up entries by string every frame: atlas entry lookup by material
name involves string comparison. Build an index mapping (material → entry index) once at init time, not per-frame.
- Ignoring mipmap bleeding: at lower mip levels, bilinear filtering
samples across atlas region boundaries. The atlas packer adds padding to mitigate this, but padding halves at each mip level — visible artifacts appear at mip 3+.
Tradeoffs
- No tiling: clamp-to-edge prevents sampling adjacent materials but
disables texture wrapping
- Mipmap bleeding: padding halves at each mip level; visible at mip 3+
- Resolution uniformity: all materials share the atlas resolution budget
CMakeLists.txt
add_executable(my-target WIN32
main.c
${CMAKE_SOURCE_DIR}/third_party/cJSON/cJSON.c
)
target_include_directories(my-target PRIVATE
${FORGE_COMMON_DIR}
${CMAKE_SOURCE_DIR}/third_party/cJSON
)
target_link_libraries(my-target PRIVATE SDL3::SDL3
$>:m>)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Nebulavenus
- Source: Nebulavenus/forge-gpu
- License: Zlib
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.