Skip to main content

forge-linear-fog

Add depth-based distance fog to an SDL GPU project. Supports linear, exponential, and exponential-squared modes. Fog is applied in the fragment shader after lighting, blending the lit color toward a fog color based on camera distance.

インストールへ移動

ソース情報

リポジトリ
Nebulavenus/forge-gpu
ソースの最終更新活動
2026年3月22日 03:50
検出された SKILL.md の言語
英語
スター
38
フォーク
7

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
forge-linear-fog
description
Add depth-based distance fog to an SDL GPU project. Supports linear, exponential, and exponential-squared modes. Fog is applied in the fragment shader after lighting, blending the lit color toward a fog color based on camera distance.
# Linear Fog Skill Adds distance fog to any SDL3 GPU scene. Derived from Lesson 20. ## When to use - Adding atmospheric perspective to a 3D scene - Fading distant objects into a background color - Simulating haze, mist, or ground fog - Hiding the far-plane clipping boundary ## Fog uniform block (append to existing fragment cbuffer) ```hlsl /* Append these fields to your existing fragment uniform buffer. * Total addition: 32 bytes (2 x float4 worth). */ float4 fog_color; /* Must match the clear color (rgb) */ float fog_start; /* Linear mode: distance where fog begins */ float fog_end; /* Linear mode: fully fogged distance */ float fog_density; /* Exp/Exp2 modes: density coefficient */ uint fog_mode; /* 0 = linear, 1 = exp, 2 = exp-squared */ ``` Matching C struct fields: ```c float fog_color[4]; float fog_start; float fog_end; float fog_density; Uint32 fog_mode; ``` ## HLSL fog calculation (paste after lighting) ```hlsl /* Compute Euclidean distance from fragment to camera. */ float dist = length(eye_pos.xyz - input.world_pos); float fog_factor = 1.0; if (fog_mode == 0) { /* Linear */ fog_factor = saturate((fog_end - dist) / (fog_end - fog_start)); } else if (fog_mode == 1) { /* Exponential */ fog_factor = saturate(exp(-fog_density * dist)); } else { /* Exponential squared */ float f = fog_density * dist; fog_factor = saturate(exp(-(f * f))); } /* Blend: fog_factor=1 → lit color, fog_factor=0 → fog color */ float3 final_color = lerp(fog_color.rgb, lit_color, fog_factor); ``` ## Typical parameter values | Parameter | Value | Notes | |-----------|-------|-------| | fog_color | match your clear color | Must equal the framebuffer clear color | | fog_start | 2.0 | Linear mode: fully visible before this distance | | fog_end | 18.0 | Linear mode: fully fogged beyond this distance | | fog_density (exp) | 0.12 | Exponential mode | | fog_density (exp2) | 0.08 | Exp-squared mode | ## Key rules 1. **Fog color = clear color.** Always set the framebuffer clear color to the same RGB as the fog color. Otherwise there will be a visible seam at the horizon. 2. **Apply fog to ALL shaders.** Every fragment shader in the scene (objects, grid, terrain, particles) must apply the same fog with the same parameters. Inconsistent fog breaks the atmospheric illusion. 3. **Use Euclidean distance, not Z depth.** Compute `length(eye - frag_pos)` in world space. Using only the Z component causes fog to shift when the camera rotates. 4. **Fog goes after lighting.** Compute the full Blinn-Phong (or PBR) result first, then blend it toward the fog color. Applying fog to individual lighting terms produces incorrect results. 5. **Clamp the fog factor.** Use `saturate()` to keep the factor in [0, 1]. Without clamping, objects beyond the fog end distance can produce negative values that invert the fog. ## Common mistakes - **Fog color doesn't match clear color** — creates a visible horizon line between fogged geometry and the background. - **Only one shader has fog** — the grid floor appears to float on top of the fog while objects fade correctly (or vice versa). - **Using Z depth instead of distance** — fog shifts when the camera rotates because fragments at the same world position get different fog values. - **Applying fog before lighting** — the ambient/diffuse/specular terms get fogged individually, producing darker or brighter results than expected. - **Forgetting to pass fog_mode to the shader** — defaults to 0 but toggling modes at runtime requires updating the uniform each frame. ## Reference - [GPU Lesson 20 — Linear Fog](../../../lessons/gpu/20-linear-fog/) - [Fragment shader](../../../lessons/gpu/20-linear-fog/shaders/fog.frag.hlsl) - [Grid shader](../../../lessons/gpu/20-linear-fog/shaders/grid_fog.frag.hlsl)
GitHubで見る