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/// Minimal depth-only shader for shadow map generation.
100pub const SHADOW_PASS_WGSL: &str = include_str!("shadow_pass.wgsl");
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_lit_forward_shader_valid() {
108 assert!(LIT_FORWARD_WGSL.contains("@vertex"));
109 assert!(LIT_FORWARD_WGSL.contains("@fragment"));
110 }
111
112 #[test]
113 fn test_standard_pbr_shader_valid() {
114 assert!(STANDARD_PBR_WGSL.contains("@vertex"));
115 assert!(STANDARD_PBR_WGSL.contains("@fragment"));
116 }
117
118 #[test]
119 fn test_unlit_shader_valid() {
120 assert!(UNLIT_WGSL.contains("@vertex"));
121 assert!(UNLIT_WGSL.contains("@fragment"));
122 }
123
124 #[test]
125 fn test_emissive_shader_valid() {
126 assert!(EMISSIVE_WGSL.contains("@vertex"));
127 assert!(EMISSIVE_WGSL.contains("@fragment"));
128 }
129
130 #[test]
131 fn test_wireframe_shader_valid() {
132 assert!(WIREFRAME_WGSL.contains("@vertex"));
133 assert!(WIREFRAME_WGSL.contains("@fragment"));
134 }
135
136 #[test]
137 fn test_light_culling_shader_valid() {
138 assert!(LIGHT_CULLING_WGSL.contains("@compute"));
139 assert!(LIGHT_CULLING_WGSL.contains("@workgroup_size"));
140 }
141
142 #[test]
143 fn test_forward_plus_shader_valid() {
144 assert!(FORWARD_PLUS_WGSL.contains("@vertex"));
145 assert!(FORWARD_PLUS_WGSL.contains("@fragment"));
146 assert!(FORWARD_PLUS_WGSL.contains("light_grid"));
147 }
148
149 #[test]
150 fn test_shadow_pass_shader_valid() {
151 assert!(SHADOW_PASS_WGSL.contains("@vertex"));
152 assert!(SHADOW_PASS_WGSL.contains("view_projection"));
153 }
154}