khora_lanes/render_lane/shaders/
mod.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Built-in shader sources for the Khora Engine rendering system.
16//!
17//! This module provides compile-time embedded shader source code for the core
18//! rendering strategies. These shaders are part of the "Strategies" layer in
19//! the SAA/CLAD architecture, representing the GPU execution paths for various
20//! render lanes.
21//!
22//! # Available Shaders
23//!
24//! - [`LIT_FORWARD_WGSL`] - Multi-light forward rendering with Blinn-Phong lighting
25//! - [`STANDARD_PBR_WGSL`] - Physically-based rendering with metallic-roughness workflow
26//! - [`UNLIT_WGSL`] - Simple unlit rendering with vertex colors
27//! - [`EMISSIVE_WGSL`] - Self-illuminating materials
28//! - [`WIREFRAME_WGSL`] - Debug wireframe visualization
29//!
30//! # Usage
31//!
32//! ```ignore
33//! use khora_lanes::shaders::LIT_FORWARD_WGSL;
34//! use khora_core::renderer::{ShaderModuleDescriptor, ShaderSourceData};
35//! use std::borrow::Cow;
36//!
37//! let descriptor = ShaderModuleDescriptor {
38//!     label: Some("lit_forward"),
39//!     source: ShaderSourceData::Wgsl(Cow::Borrowed(LIT_FORWARD_WGSL)),
40//! };
41//! ```
42
43/// Lit forward rendering shader with multi-light Blinn-Phong lighting.
44///
45/// Supports:
46/// - Up to 4 directional lights
47/// - Up to 16 point lights
48/// - Up to 8 spot lights
49///
50/// Uses Blinn-Phong BRDF with Reinhard tone mapping.
51pub const LIT_FORWARD_WGSL: &str = include_str!("lit_forward.wgsl");
52
53/// Standard PBR (Physically-Based Rendering) shader.
54///
55/// Implements the metallic-roughness workflow with Cook-Torrance BRDF:
56/// - GGX/Trowbridge-Reitz normal distribution
57/// - Schlick-GGX geometry function
58/// - Fresnel-Schlick approximation
59pub const STANDARD_PBR_WGSL: &str = include_str!("standard_pbr.wgsl");
60
61/// Simple unlit shader for vertex-colored objects.
62///
63/// Outputs interpolated vertex colors directly without any lighting
64/// calculations. Useful for debug visualization and UI elements.
65pub const UNLIT_WGSL: &str = include_str!("unlit.wgsl");
66
67/// Emissive material shader for self-illuminating objects.
68///
69/// Outputs color multiplied by an intensity factor with HDR support.
70/// Includes tone mapping and gamma correction.
71pub const EMISSIVE_WGSL: &str = include_str!("emissive.wgsl");
72
73/// Wireframe debug visualization shader.
74///
75/// Renders mesh edges using barycentric coordinates to calculate
76/// edge distances. Useful for debugging mesh topology.
77pub const WIREFRAME_WGSL: &str = include_str!("wireframe.wgsl");
78
79/// Light culling compute shader for Forward+ rendering.
80///
81/// Performs tile-based light culling by:
82/// - Computing frustum planes for each 16x16 pixel tile
83/// - Testing each light against the tile frustum
84/// - Building a per-tile light index list
85///
86/// Outputs:
87/// - `light_index_list`: Indices of lights affecting each tile
88/// - `light_grid`: (offset, count) pairs per tile
89pub const LIGHT_CULLING_WGSL: &str = include_str!("light_culling.wgsl");
90
91/// Forward+ rendering shader with tile-based light lookup.
92///
93/// Uses pre-computed light culling data to only iterate over lights
94/// that actually affect the current pixel's tile. Implements Blinn-Phong
95/// lighting with the same quality as [`LIT_FORWARD_WGSL`] but with
96/// O(lights_per_tile) complexity instead of O(all_lights).
97pub const FORWARD_PLUS_WGSL: &str = include_str!("forward_plus.wgsl");
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn test_lit_forward_shader_valid() {
105        assert!(LIT_FORWARD_WGSL.contains("@vertex"));
106        assert!(LIT_FORWARD_WGSL.contains("@fragment"));
107    }
108
109    #[test]
110    fn test_standard_pbr_shader_valid() {
111        assert!(STANDARD_PBR_WGSL.contains("@vertex"));
112        assert!(STANDARD_PBR_WGSL.contains("@fragment"));
113    }
114
115    #[test]
116    fn test_unlit_shader_valid() {
117        assert!(UNLIT_WGSL.contains("@vertex"));
118        assert!(UNLIT_WGSL.contains("@fragment"));
119    }
120
121    #[test]
122    fn test_emissive_shader_valid() {
123        assert!(EMISSIVE_WGSL.contains("@vertex"));
124        assert!(EMISSIVE_WGSL.contains("@fragment"));
125    }
126
127    #[test]
128    fn test_wireframe_shader_valid() {
129        assert!(WIREFRAME_WGSL.contains("@vertex"));
130        assert!(WIREFRAME_WGSL.contains("@fragment"));
131    }
132
133    #[test]
134    fn test_light_culling_shader_valid() {
135        assert!(LIGHT_CULLING_WGSL.contains("@compute"));
136        assert!(LIGHT_CULLING_WGSL.contains("@workgroup_size"));
137    }
138
139    #[test]
140    fn test_forward_plus_shader_valid() {
141        assert!(FORWARD_PLUS_WGSL.contains("@vertex"));
142        assert!(FORWARD_PLUS_WGSL.contains("@fragment"));
143        assert!(FORWARD_PLUS_WGSL.contains("light_grid"));
144    }
145}