From 8fcda35665a2d142c20ad8a76c43f6f5abbc29c0 Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Mon, 13 Oct 2025 21:28:40 +0300 Subject: [PATCH] configurable environment lighting source for reflection probes --- fyrox-impl/src/renderer/mod.rs | 31 +++++++++++++++------------- fyrox-impl/src/renderer/observer.rs | 29 +++++++++++++++++++------- fyrox-impl/src/scene/probe.rs | 32 +++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 21 deletions(-) diff --git a/fyrox-impl/src/renderer/mod.rs b/fyrox-impl/src/renderer/mod.rs index 4792bae4e..0c8e94c59 100644 --- a/fyrox-impl/src/renderer/mod.rs +++ b/fyrox-impl/src/renderer/mod.rs @@ -49,8 +49,6 @@ mod settings; mod shadow; mod ssao; -use crate::renderer::cache::texture::convert_pixel_kind; -use crate::renderer::ui_renderer::UiRenderInfo; use crate::{ asset::{event::ResourceEvent, manager::ResourceManager}, core::{ @@ -74,6 +72,7 @@ use crate::{ renderer::{ bloom::BloomRenderer, bundle::{BundleRenderContext, RenderDataBundleStorage, RenderDataBundleStorageOptions}, + cache::texture::convert_pixel_kind, cache::{ geometry::GeometryCache, shader::{ @@ -89,6 +88,7 @@ use crate::{ hdr::HighDynamicRangeRenderer, light::{DeferredLightRenderer, DeferredRendererContext}, ssao::ScreenSpaceAmbientOcclusionRenderer, + ui_renderer::UiRenderInfo, ui_renderer::{UiRenderContext, UiRenderer}, visibility::VisibilityCache, }, @@ -934,7 +934,6 @@ impl Renderer { dt: f32, resource_manager: &ResourceManager, need_recalculate_convolution: bool, - is_reflection_probe: bool, ) -> Result<&mut RenderDataContainer, FrameworkError> { let server = &*self.server; @@ -971,10 +970,12 @@ impl Renderer { } }; - if let Some(face) = observer.cube_map_face { - observer_render_data - .ldr_scene_framebuffer - .set_cubemap_face(0, face, 0); + if let Some(probe_data) = observer.reflection_probe_data.as_ref() { + observer_render_data.ldr_scene_framebuffer.set_cubemap_face( + 0, + probe_data.cube_map_face, + 0, + ); } self.texture_cache.try_register( @@ -1005,7 +1006,7 @@ impl Renderer { }, &mut self.dynamic_surface_cache, ); - if is_reflection_probe { + if observer.reflection_probe_data.is_some() { bundle_storage.environment_map = None; } @@ -1054,10 +1055,14 @@ impl Renderer { scene, observer, gbuffer: &mut render_data.gbuffer, - ambient_color: scene.rendering_options.ambient_lighting_color, - environment_lighting_source: scene - .rendering_options - .environment_lighting_source, + ambient_color: match observer.reflection_probe_data.as_ref() { + None => scene.rendering_options.ambient_lighting_color, + Some(probe_data) => probe_data.ambient_lighting_color, + }, + environment_lighting_source: match observer.reflection_probe_data.as_ref() { + None => scene.rendering_options.environment_lighting_source, + Some(probe_data) => probe_data.environment_lighting_source, + }, render_data_bundle: &bundle_storage, settings: &self.quality_settings, textures: &mut self.texture_cache, @@ -1318,7 +1323,6 @@ impl Renderer { // There's no need to recalculate convolution for the environment map more than once // when rendering reflection probes, because it does not use a dynamic environment map. false, - true, )?; need_recalculate_convolution = true; } @@ -1333,7 +1337,6 @@ impl Renderer { dt, resource_manager, need_recalculate_convolution, - false, )?; } diff --git a/fyrox-impl/src/renderer/observer.rs b/fyrox-impl/src/renderer/observer.rs index bac7c6990..607c6d9be 100644 --- a/fyrox-impl/src/renderer/observer.rs +++ b/fyrox-impl/src/renderer/observer.rs @@ -35,9 +35,10 @@ use crate::{ collider::BitMask, node::Node, probe::ReflectionProbe, - Scene, + EnvironmentLightingSource, Scene, }, }; +use fyrox_core::color::Color; use fyrox_texture::TextureResource; /// Observer position contains all the data, that describes an observer position in 3D space. It @@ -119,7 +120,11 @@ impl ObserversCollection { let view_projection_matrix = projection_matrix * view_matrix; observers.reflection_probes.push(Observer { handle: node.handle(), - cube_map_face: Some(cube_face.face), + reflection_probe_data: Some(ReflectionProbeData { + cube_map_face: cube_face.face, + environment_lighting_source: *probe.environment_lighting_source, + ambient_lighting_color: *probe.ambient_lighting_color, + }), render_target: Some(probe.render_target().clone()), position: ObserverPosition { translation, @@ -147,16 +152,26 @@ impl ObserversCollection { } } +pub struct ReflectionProbeData { + /// Cube map face of a cube render target to which to render a scene. + pub cube_map_face: CubeMapFace, + /// Environment lighting source of the reflection probe. See [`EnvironmentLightingSource`] docs + /// for more info. + pub environment_lighting_source: EnvironmentLightingSource, + /// Ambient lighting color of the reflection probe. + pub ambient_lighting_color: Color, +} + /// An observer holds all the information required to render a scene from a particular point of view. /// Contains all information for rendering, effectively decouples rendering entities from scene /// entities. Observer can be constructed from an arbitrary set of data or from scene entities, /// such as cameras, reflection probes. pub struct Observer { - /// The handle of the camera that was used to create this Observer. + /// The handle of a scene node (camera, reflection probe, etc.) that was used to create this + /// Observer. pub handle: Handle, - /// Cube map face of a cube render target to which to render a scene. Used for reflection probes - /// only. - pub cube_map_face: Option, + /// Additional data used by reflection probes only. + pub reflection_probe_data: Option, /// Render target to which to render the scene. pub render_target: Option, /// Position of the observer. See [`ObserverPosition`] docs for more info. @@ -205,7 +220,7 @@ impl Observer { exposure: camera.exposure(), viewport: camera.viewport_pixels(frame_size), frustum: camera.frustum(), - cube_map_face: None, + reflection_probe_data: None, } } } diff --git a/fyrox-impl/src/scene/probe.rs b/fyrox-impl/src/scene/probe.rs index 27286495b..ced5c4f55 100644 --- a/fyrox-impl/src/scene/probe.rs +++ b/fyrox-impl/src/scene/probe.rs @@ -34,12 +34,14 @@ use crate::{ visitor::prelude::*, }, graph::{constructor::ConstructorProvider, BaseSceneGraph}, + scene::EnvironmentLightingSource, scene::{ base::{Base, BaseBuilder}, graph::Graph, node::{constructor::NodeConstructor, Node, NodeTrait, UpdateContext}, }, }; +use fyrox_core::color::Color; use fyrox_texture::{TextureResource, TextureResourceExtension}; use std::{ cell::Cell, @@ -166,6 +168,13 @@ pub struct ReflectionProbe { /// Update mode of the probe. See [`UpdateMode`] docs for more info. pub update_mode: InheritableVariable, + /// Ambient lighting of the reflection probe. This value is used only if the `environment` is + /// set to [`EnvironmentLightingSource::AmbientColor`]. + pub ambient_lighting_color: InheritableVariable, + + /// Environment lighting source of the reflection probe. + pub environment_lighting_source: InheritableVariable, + /// A flag, that defines whether the probe should be updated or not. #[reflect(hidden)] #[visit(skip)] @@ -187,6 +196,8 @@ impl Default for ReflectionProbe { z_near: 0.001.into(), z_far: 128.0.into(), update_mode: Default::default(), + ambient_lighting_color: Color::repeat_opaque(120).into(), + environment_lighting_source: Default::default(), need_update: true, updated: Cell::new(false), render_target: TextureResource::new_cube_render_target(DEFAULT_RESOLUTION as u32), @@ -297,6 +308,8 @@ pub struct ReflectionProbeBuilder { z_far: f32, resolution: usize, update_mode: UpdateMode, + ambient_lighting_color: Color, + environment_lighting_source: EnvironmentLightingSource, } impl ReflectionProbeBuilder { @@ -309,6 +322,8 @@ impl ReflectionProbeBuilder { z_far: 32.0, resolution: DEFAULT_RESOLUTION, update_mode: Default::default(), + ambient_lighting_color: Color::repeat_opaque(120), + environment_lighting_source: Default::default(), } } @@ -342,6 +357,21 @@ impl ReflectionProbeBuilder { self } + /// Environment lighting source of the reflection probe. + pub fn with_environment( + mut self, + environment_lighting_source: EnvironmentLightingSource, + ) -> Self { + self.environment_lighting_source = environment_lighting_source; + self + } + + /// Sets the ambient lighting color of the reflection probe. + pub fn with_ambient_lighting_color(mut self, ambient_lighting_color: Color) -> Self { + self.ambient_lighting_color = ambient_lighting_color; + self + } + /// Creates a new reflection probe node. pub fn build_node(self) -> Node { Node::new(ReflectionProbe { @@ -351,6 +381,8 @@ impl ReflectionProbeBuilder { z_near: self.z_near.into(), z_far: self.z_far.into(), update_mode: self.update_mode.into(), + ambient_lighting_color: self.ambient_lighting_color.into(), + environment_lighting_source: self.environment_lighting_source.into(), need_update: true, updated: Cell::new(false), render_target: TextureResource::new_cube_render_target(self.resolution as u32),