Skip to main content

forge-ssao

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

Ir a la instalación

Datos de origen

Repositorio
Nebulavenus/forge-gpu
Última actividad en el origen
1 de marzo de 2026 a las 21:31
Idioma detectado de SKILL.md
inglés
Estrellas
38
Forks
7

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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.
Ver en GitHub