Skip to main content

forge-ssao

Add screen-space ambient occlusion (SSAO) to an SDL3 GPU application

الانتقال إلى التثبيت

معلومات المصدر

المستودع
Nebulavenus/forge-gpu
آخر نشاط في المصدر
١ مارس ٢٠٢٦ في ٢١:٣١
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٣٨
التفرعات
٧

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
forge-ssao
description
Add screen-space ambient occlusion (SSAO) to an SDL3 GPU application
argument-hint
(no arguments needed)
# SSAO — Screen-Space Ambient Occlusion Add hemisphere-kernel SSAO with blur and composite passes to an existing SDL3 GPU application. Based on the John Chapman / LearnOpenGL approach. ## When to use - You want contact shadows in crevices, corners, and where objects meet - You have a depth buffer and can add a view-normal G-buffer pass - You want a screen-space effect that works with any geometry ## How it works SSAO requires 3 additional render passes after your main geometry pass: 1. **SSAO pass** — samples the depth buffer in a hemisphere around each pixel's surface normal; outputs a single-channel AO factor 2. **Blur pass** — 4x4 box blur smooths the noise tile pattern 3. **Composite pass** — multiplies scene color by the AO factor The geometry pass must output view-space normals as a second render target (MRT), and the depth buffer must be readable as a sampler. ## Key API calls ### Render targets needed ```c /* Scene depth — readable as sampler for SSAO reconstruction */ ti.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT; ti.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER; /* View normals — MRT target 1 from geometry pass */ ti.format = SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT; ti.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER; /* SSAO raw + blurred — single channel AO factor */ ti.format = SDL_GPU_TEXTUREFORMAT_R8_UNORM; ti.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER; ``` ### Pipeline setup Set `num_color_targets = 2` on the MRT geometry pipeline (color + normals). The three fullscreen-quad pipelines (SSAO, blur, composite) use no vertex buffer and no depth test — see existing pipeline patterns from earlier lessons. ### SSAO kernel generation ```c /* 64 hemisphere samples with quadratic falloff */ for (int i = 0; i < 64; i++) { /* Random direction in hemisphere (+Z up) */ float x = random_signed(), y = random_signed(), z = random_01(); normalize(&x, &y, &z); /* Concentrate samples near the surface */ float t = (float)i / 64.0f; float scale = 0.1f + 0.9f * t * t; kernel[i] = {x * scale, y * scale, z * scale, 0}; } ``` ### Depth reconstruction (HLSL) ```hlsl float3 view_pos_from_depth(float2 uv, float depth) { float2 ndc_xy = uv * 2.0 - 1.0; ndc_xy.y = -ndc_xy.y; float4 clip = float4(ndc_xy, depth, 1.0); float4 view = mul(inv_projection, clip); return view.xyz / view.w; } ``` ### MRT fragment shader output (HLSL) ```hlsl struct PSOutput { float4 color : SV_Target0; /* lit scene color */ float4 view_normal : SV_Target1; /* view-space normal */ }; ``` ## Step-by-step integration 1. **Add view-normal output** to your geometry pass vertex shader (transform normal by view matrix) and fragment shader (output as SV_Target1) 2. **Change depth texture usage** to include `SDL_GPU_TEXTUREUSAGE_SAMPLER` so the SSAO pass can read it 3. **Create SSAO render targets** — `ssao_raw` and `ssao_blurred` (R8_UNORM) 4. **Create noise texture** — 4x4, R32G32B32A32_FLOAT, random unit XY vectors, REPEAT wrapping 5. **Generate SSAO kernel** — 64 hemisphere samples at init time 6. **Add 3 fullscreen-quad pipelines** — SSAO, blur, composite (no vertex buffer, no depth test) 7. **Render 3 additional passes** after your geometry pass: - SSAO: bind normals + depth + noise, push kernel + matrices - Blur: bind raw SSAO, push texel size - Composite: bind scene color + blurred AO, push display mode ## Common issues - **Black screen** — check that depth texture has SAMPLER usage flag - **All white AO** — verify `inv_projection` is correct; check depth reconstruction flips Y correctly - **Visible 4x4 pattern** — ensure blur pass runs; check noise texture uses REPEAT wrapping - **Self-occlusion (dark flat surfaces)** — increase `bias` parameter - **AO halo around objects** — decrease `radius` or add range check with `smoothstep(0, 1, radius / abs(frag_z - stored_z))` ## Reference See [Lesson 27 — SSAO](../../../lessons/gpu/27-ssao/) for the complete implementation with 5 render passes, shadow mapping, and view mode switching.
عرض على GitHub