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}