r3d_environment.odin 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* r3d_environment.odin -- R3D Environment Module.
  2. *
  3. * Copyright (c) 2025-2026 Le Juez Victor
  4. *
  5. * This software is provided 'as-is', without any express or implied warranty.
  6. * For conditions of distribution and use, see accompanying LICENSE file.
  7. */
  8. package r3d
  9. import rl "vendor:raylib"
  10. when ODIN_OS == .Windows {
  11. foreign import lib {
  12. "windows/libr3d.a",
  13. "system:raylib",
  14. "system:assimp",
  15. }
  16. } else when ODIN_OS == .Linux {
  17. foreign import lib {
  18. "linux/libr3d.a",
  19. "system:raylib",
  20. "system:assimp",
  21. }
  22. } else when ODIN_OS == .Darwin {
  23. foreign import lib {
  24. "darwin/libr3d.a",
  25. "system:raylib",
  26. "system:assimp",
  27. }
  28. }
  29. /**
  30. * @brief Bloom effect modes.
  31. *
  32. * Different blending methods for the bloom glow effect.
  33. */
  34. Bloom :: enum u32 {
  35. DISABLED = 0, ///< No bloom effect applied
  36. MIX = 1, ///< Linear interpolation blend between scene and bloom
  37. ADDITIVE = 2, ///< Additive blending, intensifying bright regions
  38. SCREEN = 3, ///< Screen blending for softer highlight enhancement
  39. }
  40. /**
  41. * @brief Fog effect modes.
  42. *
  43. * Distance-based fog density distribution methods.
  44. */
  45. Fog :: enum u32 {
  46. DISABLED = 0, ///< No fog effect
  47. LINEAR = 1, ///< Linear density increase between start and end distances
  48. EXP2 = 2, ///< Exponential squared density (exp2), more realistic
  49. EXP = 3, ///< Simple exponential density increase
  50. }
  51. /**
  52. * @brief Depth of field modes.
  53. */
  54. DoF :: enum u32 {
  55. DISABLED = 0, ///< No depth of field effect
  56. ENABLED = 1, ///< Depth of field enabled with focus point and blur
  57. }
  58. /**
  59. * @brief Tone mapping algorithms.
  60. *
  61. * HDR to LDR color compression methods.
  62. */
  63. Tonemap :: enum u32 {
  64. LINEAR = 0, ///< Direct linear mapping (no compression)
  65. REINHARD = 1, ///< Reinhard operator, balanced HDR compression
  66. FILMIC = 2, ///< Film-like response curve
  67. ACES = 3, ///< Academy rl.Color Encoding System (cinematic standard)
  68. AGX = 4, ///< Modern algorithm preserving highlights and shadows
  69. COUNT = 5, ///< Internal: number of tonemap modes
  70. }
  71. /**
  72. * @brief Background and skybox configuration.
  73. */
  74. EnvBackground :: struct {
  75. color: rl.Color, ///< Background color when there is no skybox
  76. energy: f32, ///< Energy multiplier applied to background (skybox or color)
  77. skyBlur: f32, ///< Sky blur factor [0,1], based on mipmaps, very fast
  78. sky: Cubemap, ///< Skybox asset (used if ID is non-zero)
  79. rotation: rl.Quaternion, ///< Skybox rotation (pitch, yaw, roll as quaternion)
  80. }
  81. /**
  82. * @brief Ambient lighting configuration.
  83. */
  84. EnvAmbient :: struct {
  85. color: rl.Color, ///< Ambient light color when there is no ambient map
  86. energy: f32, ///< Energy multiplier for ambient light (map or color)
  87. _map: AmbientMap, ///< IBL environment map, can be generated from skybox
  88. }
  89. /**
  90. * @brief Screen Space Ambient Occlusion (SSAO) settings.
  91. *
  92. * Darkens areas where surfaces are close together, such as corners and crevices.
  93. */
  94. EnvSSAO :: struct {
  95. sampleCount: i32, ///< Number of samples to compute SSAO (default: 16)
  96. intensity: f32, ///< Base occlusion strength multiplier (default: 1.0)
  97. power: f32, ///< Exponential falloff for sharper darkening (default: 1.5)
  98. radius: f32, ///< Sampling radius in world space (default: 0.25)
  99. bias: f32, ///< Depth bias to prevent self-shadowing, good value is ~2% of the radius (default: 0.007)
  100. enabled: bool, ///< Enable/disable SSAO effect (default: false)
  101. }
  102. /**
  103. * @brief Screen Space Indirect Lighting (SSIL) settings.
  104. *
  105. * Approximates indirect lighting by gathering light from nearby surfaces in screen space.
  106. */
  107. EnvSSIL :: struct {
  108. sampleCount: i32, ///< Number of samples to compute indirect lighting (default: 4)
  109. sliceCount: i32, ///< Number of depth slices for accumulation (default: 4)
  110. sampleRadius: f32, ///< Maximum distance to gather light from (default: 5.0)
  111. hitThickness: f32, ///< Thickness threshold for occluders (default: 0.5)
  112. aoPower: f32, ///< Exponential falloff for visibility factor (too high = more noise) (default: 1.0)
  113. energy: f32, ///< Multiplier for indirect light intensity (default: 1.0)
  114. bounce: f32, /**< Bounce feeback factor. (default: 0.5)
  115. * Simulates light bounces by re-injecting the SSIL from the previous frame into the current direct light.
  116. * Be careful not to make the factor too high in order to avoid a feedback loop.
  117. */
  118. convergence: f32, /**< Temporal convergence factor (0 disables it, default 0.5).
  119. * Smooths sudden light flashes by blending with previous frames.
  120. * Higher values produce smoother results but may cause ghosting.
  121. * Tip: The faster the screen changes, the higher the convergence can be acceptable.
  122. * Requires an additional history buffer (so require more memory).
  123. * If multiple SSIL passes are done in the same frame, the history may be inconsistent,
  124. * in that case, enable SSIL/convergence for only one pass per frame.
  125. */
  126. enabled: bool, ///< Enable/disable SSIL effect (default: false)
  127. }
  128. /**
  129. * @brief Screen Space Reflections (SSR) settings.
  130. *
  131. * Real-time reflections calculated in screen space.
  132. */
  133. EnvSSR :: struct {
  134. maxRaySteps: i32, ///< Maximum ray marching steps (default: 32)
  135. binarySteps: i32, ///< Binary search refinement steps (default: 4)
  136. stepSize: f32, ///< rl.Ray step size (default: 0.125)
  137. thickness: f32, ///< Depth tolerance for valid hits (default: 0.2)
  138. maxDistance: f32, ///< Maximum ray distance (default: 4.0)
  139. edgeFade: f32, ///< Screen edge fade start [0,1] (default: 0.25)
  140. enabled: bool, ///< Enable/disable SSR (default: false)
  141. }
  142. /**
  143. * @brief Bloom post-processing settings.
  144. *
  145. * Glow effect around bright areas in the scene.
  146. */
  147. EnvBloom :: struct {
  148. mode: Bloom, ///< Bloom blending mode (default: R3D_BLOOM_DISABLED)
  149. levels: f32, ///< Mipmap spread factor [0-1]: higher = wider glow (default: 0.5)
  150. intensity: f32, ///< Bloom strength multiplier (default: 0.05)
  151. threshold: f32, ///< Minimum brightness to trigger bloom (default: 0.0)
  152. softThreshold: f32, ///< Softness of brightness cutoff transition (default: 0.5)
  153. filterRadius: f32, ///< Blur filter radius during upscaling (default: 1.0)
  154. }
  155. /**
  156. * @brief Fog atmospheric effect settings.
  157. */
  158. EnvFog :: struct {
  159. mode: Fog, ///< Fog distribution mode (default: R3D_FOG_DISABLED)
  160. color: rl.Color, ///< Fog tint color (default: white)
  161. start: f32, ///< Linear mode: distance where fog begins (default: 1.0)
  162. end: f32, ///< Linear mode: distance of full fog density (default: 50.0)
  163. density: f32, ///< Exponential modes: fog thickness factor (default: 0.05)
  164. skyAffect: f32, ///< Fog influence on skybox [0-1] (default: 0.5)
  165. }
  166. /**
  167. * @brief Depth of Field (DoF) camera focus settings.
  168. *
  169. * Blurs objects outside the focal plane.
  170. */
  171. EnvDoF :: struct {
  172. mode: DoF, ///< Enable/disable state (default: R3D_DOF_DISABLED)
  173. focusPoint: f32, ///< Focus distance in meters from camera (default: 10.0)
  174. focusScale: f32, ///< Depth of field depth: lower = shallower (default: 1.0)
  175. maxBlurSize: f32, ///< Maximum blur radius, similar to aperture (default: 20.0)
  176. }
  177. /**
  178. * @brief Tone mapping and exposure settings.
  179. *
  180. * Converts HDR colors to displayable LDR range.
  181. */
  182. EnvTonemap :: struct {
  183. mode: Tonemap, ///< Tone mapping algorithm (default: R3D_TONEMAP_LINEAR)
  184. exposure: f32, ///< Scene brightness multiplier (default: 1.0)
  185. white: f32, ///< Reference white point (not used for AGX) (default: 1.0)
  186. }
  187. /**
  188. * @brief rl.Color grading adjustments.
  189. *
  190. * Final color correction applied after all other effects.
  191. */
  192. EnvColor :: struct {
  193. brightness: f32, ///< Overall brightness multiplier (default: 1.0)
  194. contrast: f32, ///< Contrast between dark and bright areas (default: 1.0)
  195. saturation: f32, ///< rl.Color intensity (default: 1.0)
  196. }
  197. /**
  198. * @brief Complete environment configuration structure.
  199. *
  200. * Contains all rendering environment parameters: background, lighting, and post-processing effects.
  201. * Initialize with R3D_ENVIRONMENT_BASE for default values.
  202. */
  203. Environment :: struct {
  204. background: EnvBackground, ///< Background and skybox settings
  205. ambient: EnvAmbient, ///< Ambient lighting configuration
  206. ssao: EnvSSAO, ///< Screen space ambient occlusion
  207. ssil: EnvSSIL, ///< Screen space indirect lighting
  208. ssr: EnvSSR, ///< Screen space reflections
  209. bloom: EnvBloom, ///< Bloom glow effect
  210. fog: EnvFog, ///< Atmospheric fog
  211. dof: EnvDoF, ///< Depth of field focus effect
  212. tonemap: EnvTonemap, ///< HDR tone mapping
  213. color: EnvColor, ///< rl.Color grading adjustments
  214. }
  215. @(default_calling_convention="c", link_prefix="R3D_")
  216. foreign lib {
  217. /**
  218. * @brief Retrieves a pointer to the current environment configuration.
  219. *
  220. * Provides direct read/write access to environment settings.
  221. * Modifications take effect immediately.
  222. *
  223. * @return Pointer to the active R3D_Environment structure
  224. */
  225. GetEnvironment :: proc() -> ^Environment ---
  226. /**
  227. * @brief Replaces the entire environment configuration.
  228. *
  229. * Copies all settings from the provided structure to the active environment.
  230. * Useful for switching between presets or restoring saved states.
  231. *
  232. * @param env Pointer to the R3D_Environment structure to copy from
  233. */
  234. SetEnvironment :: proc(env: ^Environment) ---
  235. }
  236. /**
  237. * @brief Default environment configuration.
  238. *
  239. * Initializes an R3D_Environment structure with sensible default values for all
  240. * rendering parameters. Use this as a starting point for custom configurations.
  241. */
  242. ENVIRONMENT_BASE :: Environment {
  243. background = {
  244. color = rl.GRAY,
  245. energy = 1.0,
  246. skyBlur = 0.0,
  247. sky = {},
  248. rotation = quaternion(x=0.0, y=0.0, z=0.0, w=1.0),
  249. },
  250. ambient = {
  251. color = rl.BLACK,
  252. energy = 1.0,
  253. _map = {},
  254. },
  255. ssao = {
  256. sampleCount = 16,
  257. intensity = 0.5,
  258. power = 1.5,
  259. radius = 0.5,
  260. bias = 0.02,
  261. enabled = false,
  262. },
  263. ssil = {
  264. sampleCount = 4,
  265. sliceCount = 4,
  266. sampleRadius = 2.0,
  267. hitThickness = 0.5,
  268. aoPower = 1.0,
  269. energy = 1.0,
  270. bounce = 0.5,
  271. convergence = 0.5,
  272. enabled = false,
  273. },
  274. ssr = {
  275. maxRaySteps = 32,
  276. binarySteps = 4,
  277. stepSize = 0.125,
  278. thickness = 0.2,
  279. maxDistance = 4.0,
  280. edgeFade = 0.25,
  281. enabled = false,
  282. },
  283. bloom = {
  284. mode = .DISABLED,
  285. levels = 0.5,
  286. intensity = 0.05,
  287. threshold = 0.0,
  288. softThreshold = 0.5,
  289. filterRadius = 1.0,
  290. },
  291. fog = {
  292. mode = .DISABLED,
  293. color = {255, 255, 255, 255},
  294. start = 1.0,
  295. end = 50.0,
  296. density = 0.05,
  297. skyAffect = 0.5,
  298. },
  299. dof = {
  300. mode = .DISABLED,
  301. focusPoint = 10.0,
  302. focusScale = 1.0,
  303. maxBlurSize = 20.0,
  304. },
  305. tonemap = {
  306. mode = .LINEAR,
  307. exposure = 1.0,
  308. white = 1.0,
  309. },
  310. color = {
  311. brightness = 1.0,
  312. contrast = 1.0,
  313. saturation = 1.0,
  314. },
  315. }