mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
detached renderer from scene's Camera
- added `Observer` - renamed `ObserverInfo` to `ObserverPosition` - makes it easier to render scenes from arbitrary observers (like reflection probes)
This commit is contained in:
@@ -32,7 +32,7 @@ use crate::{
|
||||
graph::{BaseSceneGraph, SceneGraph, SceneGraphNode},
|
||||
gui::message::{KeyCode, KeyboardModifiers, MouseButton},
|
||||
renderer::{
|
||||
bundle::{ObserverInfo, RenderContext, RenderDataBundleStorage},
|
||||
bundle::{ObserverPosition, RenderContext, RenderDataBundleStorage},
|
||||
DynamicSurfaceCache,
|
||||
},
|
||||
scene::{
|
||||
@@ -929,12 +929,12 @@ fn precise_ray_test(
|
||||
ignore_back_faces: bool,
|
||||
) -> PreciseRayTestResult {
|
||||
let mut cache = DynamicSurfaceCache::new();
|
||||
let observer_info = ObserverInfo::from_camera(camera);
|
||||
let mut bundle_storage = RenderDataBundleStorage::new_empty(observer_info.clone());
|
||||
let observer_position = ObserverPosition::from_camera(camera);
|
||||
let mut bundle_storage = RenderDataBundleStorage::new_empty(observer_position.clone());
|
||||
node.collect_render_data(&mut RenderContext {
|
||||
render_mask: BitMask::all(),
|
||||
elapsed_time: 0.0,
|
||||
observer_info: &observer_info,
|
||||
observer_position: &observer_position,
|
||||
frustum: Some(&camera.frustum()),
|
||||
storage: &mut bundle_storage,
|
||||
graph,
|
||||
|
||||
+14
-19
@@ -24,7 +24,7 @@ use crate::{
|
||||
fxhash::FxHashSet,
|
||||
graph::{BaseSceneGraph, SceneGraph},
|
||||
renderer::{
|
||||
bundle::{BundleRenderContext, ObserverInfo, RenderContext, RenderDataBundleStorage},
|
||||
bundle::{BundleRenderContext, RenderContext, RenderDataBundleStorage},
|
||||
cache::shader::{
|
||||
binding, property, PropertyGroup, RenderMaterial, RenderPassContainer,
|
||||
},
|
||||
@@ -127,23 +127,14 @@ impl SceneRenderPass for HighlightRenderPass {
|
||||
{
|
||||
let render_pass_name = ImmutableString::new("Forward");
|
||||
|
||||
let observer_info = ObserverInfo {
|
||||
observer_position: ctx.camera.global_position(),
|
||||
z_near: ctx.camera.projection().z_near(),
|
||||
z_far: ctx.camera.projection().z_far(),
|
||||
view_matrix: ctx.camera.view_matrix(),
|
||||
projection_matrix: ctx.camera.projection_matrix(),
|
||||
};
|
||||
|
||||
let mut render_bundle_storage =
|
||||
RenderDataBundleStorage::new_empty(observer_info.clone());
|
||||
RenderDataBundleStorage::new_empty(ctx.observer.position.clone());
|
||||
|
||||
let frustum = ctx.camera.frustum();
|
||||
let mut render_context = RenderContext {
|
||||
render_mask: *ctx.camera.render_mask,
|
||||
render_mask: ctx.observer.render_mask,
|
||||
elapsed_time: ctx.elapsed_time,
|
||||
observer_info: &observer_info,
|
||||
frustum: Some(&frustum),
|
||||
observer_position: &ctx.observer.position,
|
||||
frustum: Some(&ctx.observer.frustum),
|
||||
storage: &mut render_bundle_storage,
|
||||
graph: &ctx.scene.graph,
|
||||
render_pass_name: &render_pass_name,
|
||||
@@ -160,8 +151,12 @@ impl SceneRenderPass for HighlightRenderPass {
|
||||
|
||||
render_bundle_storage.sort();
|
||||
|
||||
self.framebuffer
|
||||
.clear(ctx.viewport, Some(Color::TRANSPARENT), Some(1.0), None);
|
||||
self.framebuffer.clear(
|
||||
ctx.observer.viewport,
|
||||
Some(Color::TRANSPARENT),
|
||||
Some(1.0),
|
||||
None,
|
||||
);
|
||||
|
||||
stats += render_bundle_storage.render_to_frame_buffer(
|
||||
ctx.server,
|
||||
@@ -178,7 +173,7 @@ impl SceneRenderPass for HighlightRenderPass {
|
||||
fallback_resources: ctx.fallback_resources,
|
||||
ambient_light: Default::default(),
|
||||
scene_depth: Some(ctx.depth_texture),
|
||||
viewport: ctx.viewport,
|
||||
viewport: ctx.observer.viewport,
|
||||
uniform_memory_allocator: ctx.uniform_memory_allocator,
|
||||
},
|
||||
)?;
|
||||
@@ -186,7 +181,7 @@ impl SceneRenderPass for HighlightRenderPass {
|
||||
|
||||
// Render full screen quad with edge detect shader to draw outline of selected objects.
|
||||
{
|
||||
let frame_matrix = make_viewport_matrix(ctx.viewport);
|
||||
let frame_matrix = make_viewport_matrix(ctx.observer.viewport);
|
||||
let frame_texture = &self.framebuffer.color_attachments()[0].texture;
|
||||
|
||||
let color = Color::ORANGE.as_frgba();
|
||||
@@ -207,7 +202,7 @@ impl SceneRenderPass for HighlightRenderPass {
|
||||
&ImmutableString::new("Primary"),
|
||||
ctx.framebuffer,
|
||||
&self.quad,
|
||||
ctx.viewport,
|
||||
ctx.observer.viewport,
|
||||
&material,
|
||||
ctx.uniform_buffer_cache,
|
||||
Default::default(),
|
||||
|
||||
@@ -94,8 +94,8 @@ impl SceneRenderPass for OverlayRenderPass {
|
||||
ctx: SceneRenderPassContext,
|
||||
) -> Result<RenderPassStatistics, FrameworkError> {
|
||||
let mut stats = RenderPassStatistics::default();
|
||||
let view_projection = ctx.camera.view_projection_matrix();
|
||||
let inv_view = ctx.camera.inv_view_matrix().unwrap();
|
||||
let view_projection = ctx.observer.position.view_projection_matrix;
|
||||
let inv_view = ctx.observer.position.view_matrix.try_inverse().unwrap();
|
||||
let camera_up = -inv_view.up();
|
||||
let camera_side = inv_view.side();
|
||||
let sound_icon = ctx
|
||||
@@ -135,7 +135,7 @@ impl SceneRenderPass for OverlayRenderPass {
|
||||
&ImmutableString::new("Primary"),
|
||||
ctx.framebuffer,
|
||||
&self.quad,
|
||||
ctx.viewport,
|
||||
ctx.observer.viewport,
|
||||
&material,
|
||||
ctx.uniform_buffer_cache,
|
||||
Default::default(),
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#![allow(missing_docs)] // TODO
|
||||
|
||||
use crate::material::Material;
|
||||
use crate::scene::camera::Camera;
|
||||
use crate::scene::camera::{Camera, ColorGradingLut, Exposure, Projection};
|
||||
use crate::{
|
||||
core::{
|
||||
algebra::{Matrix4, Vector3, Vector4},
|
||||
@@ -75,7 +75,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use fxhash::{FxBuildHasher, FxHashMap, FxHasher};
|
||||
use fyrox_core::algebra::Point3;
|
||||
use fyrox_core::algebra::{Point3, Vector2};
|
||||
use fyrox_graph::{SceneGraph, SceneGraphNode};
|
||||
use fyrox_graphics::gpu_program::{SamplerFallback, ShaderResourceDefinition};
|
||||
use std::{
|
||||
@@ -83,30 +83,76 @@ use std::{
|
||||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
/// Observer info contains all the data, that describes an observer. It could be a real camera, light source's
|
||||
/// "virtual camera" that is used for shadow mapping, etc.
|
||||
pub struct Observer {
|
||||
pub handle: Handle<Node>,
|
||||
pub render_target: Option<TextureResource>,
|
||||
pub position: ObserverPosition,
|
||||
pub environment_map: Option<TextureResource>,
|
||||
pub skybox_map: Option<TextureResource>,
|
||||
pub render_mask: BitMask,
|
||||
pub projection: Projection,
|
||||
pub color_grading_lut: Option<ColorGradingLut>,
|
||||
pub color_grading_enabled: bool,
|
||||
pub exposure: Exposure,
|
||||
pub viewport: Rect<i32>,
|
||||
pub frustum: Frustum,
|
||||
}
|
||||
|
||||
impl Observer {
|
||||
pub fn from_camera(camera: &Camera, mut frame_size: Vector2<f32>) -> Self {
|
||||
let skybox_map = camera.skybox_ref().and_then(|s| s.cubemap.clone());
|
||||
if let Some(render_target) = camera.render_target() {
|
||||
if let Some(size) = render_target
|
||||
.data_ref()
|
||||
.as_loaded_ref()
|
||||
.and_then(|rt| rt.kind().rectangle_size().map(|size| size.cast::<f32>()))
|
||||
{
|
||||
frame_size = size;
|
||||
}
|
||||
}
|
||||
Observer {
|
||||
handle: camera.handle(),
|
||||
environment_map: camera.environment_map().or_else(|| skybox_map.clone()),
|
||||
skybox_map,
|
||||
render_mask: *camera.render_mask,
|
||||
projection: camera.projection().clone(),
|
||||
position: ObserverPosition::from_camera(camera),
|
||||
render_target: camera.render_target().cloned(),
|
||||
color_grading_lut: camera.color_grading_lut(),
|
||||
color_grading_enabled: camera.color_grading_enabled(),
|
||||
exposure: camera.exposure(),
|
||||
viewport: camera.viewport_pixels(frame_size),
|
||||
frustum: camera.frustum(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Observer position contains all the data, that describes an observer position in 3D space. It
|
||||
/// could be a real camera, light source's "virtual camera" that is used for shadow mapping, etc.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ObserverInfo {
|
||||
pub struct ObserverPosition {
|
||||
/// World-space position of the observer.
|
||||
pub observer_position: Vector3<f32>,
|
||||
/// Location of the near clipping plane.
|
||||
pub translation: Vector3<f32>,
|
||||
/// Position of the near clipping plane.
|
||||
pub z_near: f32,
|
||||
/// Location of the far clipping plane.
|
||||
/// Position of the far clipping plane.
|
||||
pub z_far: f32,
|
||||
/// View matrix of the observer.
|
||||
/// The view matrix of the observer.
|
||||
pub view_matrix: Matrix4<f32>,
|
||||
/// Projection matrix of the observer.
|
||||
pub projection_matrix: Matrix4<f32>,
|
||||
pub view_projection_matrix: Matrix4<f32>,
|
||||
}
|
||||
|
||||
impl ObserverInfo {
|
||||
impl ObserverPosition {
|
||||
pub fn from_camera(camera: &Camera) -> Self {
|
||||
ObserverInfo {
|
||||
observer_position: camera.global_position(),
|
||||
Self {
|
||||
translation: camera.global_position(),
|
||||
z_near: camera.projection().z_near(),
|
||||
z_far: camera.projection().z_far(),
|
||||
view_matrix: camera.view_matrix(),
|
||||
projection_matrix: camera.projection_matrix(),
|
||||
view_projection_matrix: camera.view_projection_matrix(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +167,7 @@ pub struct RenderContext<'a> {
|
||||
/// this value is **not** guaranteed to match real time. A user can change delta time with
|
||||
/// which the engine "ticks" and this delta time affects elapsed time.
|
||||
pub elapsed_time: f32,
|
||||
pub observer_info: &'a ObserverInfo,
|
||||
pub observer_position: &'a ObserverPosition,
|
||||
/// Frustum of the observer, it is built using observer's view and projection matrix. Use the frustum to do
|
||||
/// frustum culling.
|
||||
pub frustum: Option<&'a Frustum>,
|
||||
@@ -144,7 +190,7 @@ impl RenderContext<'_> {
|
||||
const RANGE_CENTER: u64 = u64::MAX / 2;
|
||||
const GRANULARITY: f32 = 1000.0;
|
||||
|
||||
let view_matrix = &self.observer_info.view_matrix;
|
||||
let view_matrix = &self.observer_position.view_matrix;
|
||||
let world_space_point = Point3::from(global_position);
|
||||
let view_space_point = view_matrix.transform_point(&world_space_point);
|
||||
|
||||
@@ -823,7 +869,8 @@ pub struct LightSource {
|
||||
/// rendering by reducing amount of state changes of OpenGL context.
|
||||
pub struct RenderDataBundleStorage {
|
||||
bundle_map: FxHashMap<u64, usize>,
|
||||
pub observer_info: ObserverInfo,
|
||||
/// Position of an observer for which this data bundle was created.
|
||||
pub observer_position: ObserverPosition,
|
||||
/// A sorted list of bundles.
|
||||
pub bundles: Vec<RenderDataBundle>,
|
||||
pub light_sources: Vec<LightSource>,
|
||||
@@ -842,10 +889,10 @@ impl Default for RenderDataBundleStorageOptions {
|
||||
}
|
||||
|
||||
impl RenderDataBundleStorage {
|
||||
pub fn new_empty(observer_info: ObserverInfo) -> Self {
|
||||
pub fn new_empty(observer_position: ObserverPosition) -> Self {
|
||||
Self {
|
||||
bundle_map: Default::default(),
|
||||
observer_info,
|
||||
observer_position,
|
||||
bundles: Default::default(),
|
||||
light_sources: Default::default(),
|
||||
}
|
||||
@@ -858,7 +905,7 @@ impl RenderDataBundleStorage {
|
||||
graph: &Graph,
|
||||
render_mask: BitMask,
|
||||
elapsed_time: f32,
|
||||
observer_info: ObserverInfo,
|
||||
observer_position: &ObserverPosition,
|
||||
render_pass_name: ImmutableString,
|
||||
options: RenderDataBundleStorageOptions,
|
||||
dynamic_surface_cache: &mut DynamicSurfaceCache,
|
||||
@@ -867,13 +914,13 @@ impl RenderDataBundleStorage {
|
||||
let capacity = graph.node_count() as usize;
|
||||
let mut storage = Self {
|
||||
bundle_map: FxHashMap::with_capacity_and_hasher(capacity, FxBuildHasher::default()),
|
||||
observer_info: observer_info.clone(),
|
||||
observer_position: observer_position.clone(),
|
||||
bundles: Vec::with_capacity(capacity),
|
||||
light_sources: Default::default(),
|
||||
};
|
||||
|
||||
let frustum = Frustum::from_view_projection_matrix(
|
||||
observer_info.projection_matrix * observer_info.view_matrix,
|
||||
observer_position.projection_matrix * observer_position.view_matrix,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -883,11 +930,12 @@ impl RenderDataBundleStorage {
|
||||
for level in lod_group.levels.iter() {
|
||||
for &object in level.objects.iter() {
|
||||
if let Some(object_ref) = graph.try_get(object) {
|
||||
let distance = observer_info
|
||||
.observer_position
|
||||
let distance = observer_position
|
||||
.translation
|
||||
.metric_distance(&object_ref.global_position());
|
||||
let z_range = observer_info.z_far - observer_info.z_near;
|
||||
let normalized_distance = (distance - observer_info.z_near) / z_range;
|
||||
let z_range = observer_position.z_far - observer_position.z_near;
|
||||
let normalized_distance =
|
||||
(distance - observer_position.z_near) / z_range;
|
||||
let visible = normalized_distance >= level.begin()
|
||||
&& normalized_distance <= level.end();
|
||||
lod_filter[object.index() as usize] = visible;
|
||||
@@ -948,7 +996,7 @@ impl RenderDataBundleStorage {
|
||||
let mut ctx = RenderContext {
|
||||
render_mask,
|
||||
elapsed_time,
|
||||
observer_info: &observer_info,
|
||||
observer_position,
|
||||
frustum: Some(&frustum),
|
||||
storage: &mut storage,
|
||||
graph,
|
||||
@@ -1042,21 +1090,22 @@ impl RenderDataBundleStorage {
|
||||
|
||||
// Upload camera uniforms.
|
||||
let inv_view = self
|
||||
.observer_info
|
||||
.observer_position
|
||||
.view_matrix
|
||||
.try_inverse()
|
||||
.unwrap_or_default();
|
||||
let view_projection = self.observer_info.projection_matrix * self.observer_info.view_matrix;
|
||||
let view_projection =
|
||||
self.observer_position.projection_matrix * self.observer_position.view_matrix;
|
||||
let camera_up = inv_view.up();
|
||||
let camera_side = inv_view.side();
|
||||
let camera_uniforms = StaticUniformBuffer::<512>::new()
|
||||
.with(&view_projection)
|
||||
.with(&self.observer_info.observer_position)
|
||||
.with(&self.observer_position.translation)
|
||||
.with(&camera_up)
|
||||
.with(&camera_side)
|
||||
.with(&self.observer_info.z_near)
|
||||
.with(&self.observer_info.z_far)
|
||||
.with(&(self.observer_info.z_far - self.observer_info.z_near));
|
||||
.with(&self.observer_position.z_near)
|
||||
.with(&self.observer_position.z_far)
|
||||
.with(&(self.observer_position.z_far - self.observer_position.z_near));
|
||||
let camera_block = render_context
|
||||
.uniform_memory_allocator
|
||||
.allocate(camera_uniforms);
|
||||
@@ -1089,7 +1138,8 @@ impl RenderDataBundleStorage {
|
||||
{
|
||||
let global_uniforms = self.write_global_uniform_blocks(&mut render_context);
|
||||
|
||||
let view_projection = self.observer_info.projection_matrix * self.observer_info.view_matrix;
|
||||
let view_projection =
|
||||
self.observer_position.projection_matrix * self.observer_position.view_matrix;
|
||||
let mut bundle_uniform_data_set = Vec::with_capacity(self.bundles.len());
|
||||
for bundle in self.bundles.iter() {
|
||||
if !bundle_filter(bundle) {
|
||||
@@ -1228,26 +1278,27 @@ impl RenderDataBundleStorageTrait for RenderDataBundleStorage {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::renderer::bundle::{ObserverInfo, RenderContext, RenderDataBundleStorage};
|
||||
use crate::renderer::bundle::{ObserverPosition, RenderContext, RenderDataBundleStorage};
|
||||
use fyrox_core::algebra::{Matrix4, Vector3};
|
||||
|
||||
//noinspection ALL
|
||||
#[test]
|
||||
fn test_calculate_sorting_index() {
|
||||
let observer_info = ObserverInfo {
|
||||
observer_position: Default::default(),
|
||||
let observer_position = ObserverPosition {
|
||||
translation: Default::default(),
|
||||
z_near: 0.0,
|
||||
z_far: 0.0,
|
||||
view_matrix: Matrix4::identity(),
|
||||
projection_matrix: Matrix4::identity(),
|
||||
view_projection_matrix: Matrix4::identity(),
|
||||
};
|
||||
|
||||
let render_context = RenderContext {
|
||||
render_mask: Default::default(),
|
||||
elapsed_time: 0.0,
|
||||
observer_info: &observer_info.clone(),
|
||||
observer_position: &observer_position.clone(),
|
||||
frustum: None,
|
||||
storage: &mut RenderDataBundleStorage::new_empty(observer_info),
|
||||
storage: &mut RenderDataBundleStorage::new_empty(observer_position),
|
||||
graph: &Default::default(),
|
||||
render_pass_name: &Default::default(),
|
||||
dynamic_surface_cache: &mut Default::default(),
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
//! Every alpha channel is used for layer blending for terrains. This is inefficient, but for
|
||||
//! now I don't know better solution.
|
||||
|
||||
use crate::renderer::bundle::Observer;
|
||||
use crate::{
|
||||
core::{
|
||||
algebra::{Matrix4, Vector2},
|
||||
@@ -58,7 +59,6 @@ use crate::{
|
||||
FallbackResources, GeometryCache, QualitySettings, RenderPassStatistics, TextureCache,
|
||||
},
|
||||
scene::{
|
||||
camera::Camera,
|
||||
decal::Decal,
|
||||
graph::Graph,
|
||||
mesh::{surface::SurfaceData, RenderPath},
|
||||
@@ -79,7 +79,7 @@ pub struct GBuffer {
|
||||
|
||||
pub(crate) struct GBufferRenderContext<'a, 'b> {
|
||||
pub server: &'a dyn GraphicsServer,
|
||||
pub camera: &'b Camera,
|
||||
pub observer: &'b Observer,
|
||||
pub geom_cache: &'a mut GeometryCache,
|
||||
pub bundle_storage: &'a RenderDataBundleStorage,
|
||||
pub texture_cache: &'a mut TextureCache,
|
||||
@@ -200,7 +200,7 @@ impl GBuffer {
|
||||
|
||||
let GBufferRenderContext {
|
||||
server,
|
||||
camera,
|
||||
observer,
|
||||
geom_cache,
|
||||
bundle_storage,
|
||||
texture_cache,
|
||||
@@ -214,8 +214,6 @@ impl GBuffer {
|
||||
..
|
||||
} = args;
|
||||
|
||||
let view_projection = camera.view_projection_matrix();
|
||||
|
||||
if quality_settings.use_occlusion_culling {
|
||||
self.occlusion_tester.try_query_visibility_results(graph);
|
||||
};
|
||||
@@ -231,7 +229,7 @@ impl GBuffer {
|
||||
let grid_cell = self
|
||||
.occlusion_tester
|
||||
.grid_cache
|
||||
.cell(camera.global_position());
|
||||
.cell(observer.position.translation);
|
||||
|
||||
let instance_filter = |instance: &SurfaceInstanceData| {
|
||||
!quality_settings.use_occlusion_culling
|
||||
@@ -272,14 +270,18 @@ impl GBuffer {
|
||||
unit_quad,
|
||||
objects.iter(),
|
||||
&self.framebuffer,
|
||||
camera.global_position(),
|
||||
view_projection,
|
||||
observer.position.translation,
|
||||
observer.position.view_projection_matrix,
|
||||
uniform_buffer_cache,
|
||||
fallback_resources,
|
||||
)?;
|
||||
}
|
||||
|
||||
let inv_view_proj = view_projection.try_inverse().unwrap_or_default();
|
||||
let inv_view_proj = observer
|
||||
.position
|
||||
.view_projection_matrix
|
||||
.try_inverse()
|
||||
.unwrap_or_default();
|
||||
let depth = self.depth();
|
||||
let decal_mask = self.decal_mask_texture();
|
||||
let resolution = Vector2::new(self.width as f32, self.height as f32);
|
||||
@@ -289,7 +291,8 @@ impl GBuffer {
|
||||
// decals do not modify depth (only diffuse and normal maps).
|
||||
let unit_cube = &self.cube;
|
||||
for decal in graph.linear_iter().filter_map(|n| n.cast::<Decal>()) {
|
||||
let world_view_proj = view_projection * decal.global_transform();
|
||||
let world_view_proj =
|
||||
observer.position.view_projection_matrix * decal.global_transform();
|
||||
|
||||
let diffuse_texture = decal
|
||||
.diffuse_texture()
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
use crate::renderer::bundle::Observer;
|
||||
use crate::renderer::DynamicSurfaceCache;
|
||||
use crate::{
|
||||
core::{
|
||||
@@ -54,7 +55,6 @@ use crate::{
|
||||
RenderPassStatistics, TextureCache,
|
||||
},
|
||||
scene::{
|
||||
camera::Camera,
|
||||
mesh::{
|
||||
buffer::{TriangleBuffer, VertexBuffer},
|
||||
surface::SurfaceData,
|
||||
@@ -87,7 +87,7 @@ pub(crate) struct DeferredRendererContext<'a> {
|
||||
pub elapsed_time: f32,
|
||||
pub server: &'a dyn GraphicsServer,
|
||||
pub scene: &'a Scene,
|
||||
pub camera: &'a Camera,
|
||||
pub observer: &'a Observer,
|
||||
pub gbuffer: &'a mut GBuffer,
|
||||
pub ambient_color: Color,
|
||||
pub render_data_bundle: &'a RenderDataBundleStorage,
|
||||
@@ -298,7 +298,7 @@ impl DeferredLightRenderer {
|
||||
elapsed_time,
|
||||
server,
|
||||
scene,
|
||||
camera,
|
||||
observer,
|
||||
gbuffer,
|
||||
render_data_bundle,
|
||||
shader_cache,
|
||||
@@ -315,38 +315,41 @@ impl DeferredLightRenderer {
|
||||
} = args;
|
||||
|
||||
let viewport = Rect::new(0, 0, gbuffer.width, gbuffer.height);
|
||||
let frustum = Frustum::from_view_projection_matrix(camera.view_projection_matrix())
|
||||
.unwrap_or_default();
|
||||
let frustum =
|
||||
Frustum::from_view_projection_matrix(observer.position.view_projection_matrix)
|
||||
.unwrap_or_default();
|
||||
|
||||
let frame_matrix = make_viewport_matrix(viewport);
|
||||
|
||||
let projection_matrix = camera.projection_matrix();
|
||||
let view_projection = camera.view_projection_matrix();
|
||||
let inv_projection = projection_matrix.try_inverse().unwrap_or_default();
|
||||
let inv_view_projection = view_projection.try_inverse().unwrap_or_default();
|
||||
let camera_global_position = camera.global_position();
|
||||
let inv_projection = observer
|
||||
.position
|
||||
.projection_matrix
|
||||
.try_inverse()
|
||||
.unwrap_or_default();
|
||||
let inv_view_projection = observer
|
||||
.position
|
||||
.view_projection_matrix
|
||||
.try_inverse()
|
||||
.unwrap_or_default();
|
||||
|
||||
// Fill SSAO map.
|
||||
if settings.use_ssao {
|
||||
pass_stats += self.ssao_renderer.render(
|
||||
gbuffer,
|
||||
projection_matrix,
|
||||
camera.view_matrix().basis(),
|
||||
observer.position.projection_matrix,
|
||||
observer.position.view_matrix.basis(),
|
||||
uniform_buffer_cache,
|
||||
fallback_resources,
|
||||
)?;
|
||||
}
|
||||
|
||||
// Render skybox (if any).
|
||||
if let Some(skybox) = camera.skybox_ref() {
|
||||
if let Some(texture_sampler_pair) = skybox
|
||||
.cubemap_ref()
|
||||
.and_then(|cube_map| textures.get(server, cube_map))
|
||||
{
|
||||
let size = camera.projection().z_far() / 2.0f32.sqrt();
|
||||
if let Some(skybox) = observer.skybox_map.as_ref() {
|
||||
if let Some(texture_sampler_pair) = textures.get(server, skybox) {
|
||||
let size = observer.position.z_far / 2.0f32.sqrt();
|
||||
let scale = Matrix4::new_scaling(size);
|
||||
let wvp = Matrix4::new_translation(&camera.global_position()) * scale;
|
||||
let wvp = view_projection * wvp;
|
||||
let wvp = Matrix4::new_translation(&observer.position.translation) * scale;
|
||||
let wvp = observer.position.view_projection_matrix * wvp;
|
||||
let properties = PropertyGroup::from([property("worldViewProjection", &wvp)]);
|
||||
let material = RenderMaterial::from([
|
||||
binding(
|
||||
@@ -376,9 +379,9 @@ impl DeferredLightRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
let environment_map = camera
|
||||
.skybox_ref()
|
||||
.and_then(|s| s.cubemap_ref())
|
||||
let environment_map = observer
|
||||
.environment_map
|
||||
.as_ref()
|
||||
.and_then(|c| {
|
||||
textures
|
||||
.get(server, c)
|
||||
@@ -401,7 +404,7 @@ impl DeferredLightRenderer {
|
||||
let properties = PropertyGroup::from([
|
||||
property("worldViewProjection", &frame_matrix),
|
||||
property("ambientColor", &ambient_color),
|
||||
property("cameraPosition", &camera_global_position),
|
||||
property("cameraPosition", &observer.position.translation),
|
||||
property("invViewProj", &inv_view_projection),
|
||||
]);
|
||||
let material = RenderMaterial::from([
|
||||
@@ -462,7 +465,7 @@ impl DeferredLightRenderer {
|
||||
)?;
|
||||
|
||||
for light in render_data_bundle.light_sources.iter() {
|
||||
let distance_to_camera = (light.position - camera.global_position()).norm();
|
||||
let distance_to_camera = (light.position - observer.position.translation).norm();
|
||||
|
||||
let (
|
||||
raw_radius,
|
||||
@@ -547,7 +550,11 @@ impl DeferredLightRenderer {
|
||||
let b1 = shadows_distance * 0.2;
|
||||
let b2 = shadows_distance * 0.4;
|
||||
let cascade_index = if distance_to_camera < b1
|
||||
|| (camera.global_position().metric_distance(&light.position) <= light_radius)
|
||||
|| (observer
|
||||
.position
|
||||
.translation
|
||||
.metric_distance(&light.position)
|
||||
<= light_radius)
|
||||
{
|
||||
0
|
||||
} else if distance_to_camera > b1 && distance_to_camera < b2 {
|
||||
@@ -566,7 +573,7 @@ impl DeferredLightRenderer {
|
||||
let mut light_view_projection = Matrix4::identity();
|
||||
|
||||
// Mark lit areas in stencil buffer to do light calculations only on them.
|
||||
let shape_wvp_matrix = view_projection * bounding_shape_matrix;
|
||||
let shape_wvp_matrix = observer.position.view_projection_matrix * bounding_shape_matrix;
|
||||
for (cull_face, stencil_action) in [
|
||||
(CullFace::Front, StencilAction::Incr),
|
||||
(CullFace::Back, StencilAction::Decr),
|
||||
@@ -611,10 +618,16 @@ impl DeferredLightRenderer {
|
||||
if !matches!(light.kind, LightSourceKind::Directional { .. })
|
||||
&& settings.use_light_occlusion_culling
|
||||
{
|
||||
if visibility_cache.needs_occlusion_query(camera_global_position, light.handle) {
|
||||
if visibility_cache
|
||||
.needs_occlusion_query(observer.position.translation, light.handle)
|
||||
{
|
||||
// Draw full screen quad, that will be used to count pixels that passed the stencil test
|
||||
// on the stencil buffer's content generated by two previous drawing commands.
|
||||
visibility_cache.begin_query(server, camera_global_position, light.handle)?;
|
||||
visibility_cache.begin_query(
|
||||
server,
|
||||
observer.position.translation,
|
||||
light.handle,
|
||||
)?;
|
||||
let properties =
|
||||
PropertyGroup::from([property("worldViewProjection", &frame_matrix)]);
|
||||
let material = RenderMaterial::from([binding("properties", &properties)]);
|
||||
@@ -632,7 +645,7 @@ impl DeferredLightRenderer {
|
||||
visibility_cache.end_query();
|
||||
}
|
||||
|
||||
if !visibility_cache.is_visible(camera_global_position, light.handle) {
|
||||
if !visibility_cache.is_visible(observer.position.translation, light.handle) {
|
||||
needs_lighting = false;
|
||||
}
|
||||
}
|
||||
@@ -665,7 +678,7 @@ impl DeferredLightRenderer {
|
||||
pass_stats += self.spot_shadow_map_renderer.render(
|
||||
server,
|
||||
&scene.graph,
|
||||
*camera.render_mask,
|
||||
observer.render_mask,
|
||||
elapsed_time,
|
||||
light.position,
|
||||
light_view_matrix,
|
||||
@@ -687,7 +700,7 @@ impl DeferredLightRenderer {
|
||||
pass_stats +=
|
||||
self.point_shadow_map_renderer
|
||||
.render(PointShadowMapRenderContext {
|
||||
render_mask: *camera.render_mask,
|
||||
render_mask: observer.render_mask,
|
||||
elapsed_time,
|
||||
state: server,
|
||||
graph: &scene.graph,
|
||||
@@ -711,7 +724,7 @@ impl DeferredLightRenderer {
|
||||
state: server,
|
||||
graph: &scene.graph,
|
||||
light,
|
||||
camera,
|
||||
observer,
|
||||
geom_cache: geometry_cache,
|
||||
shader_cache,
|
||||
texture_cache: textures,
|
||||
@@ -774,7 +787,7 @@ impl DeferredLightRenderer {
|
||||
property("invViewProj", &inv_view_projection),
|
||||
property("lightPos", &light.position),
|
||||
property("lightColor", &color),
|
||||
property("cameraPosition", &camera_global_position),
|
||||
property("cameraPosition", &observer.position.translation),
|
||||
property("lightDirection", &emit_direction),
|
||||
property("lightRadius", &light_radius),
|
||||
property("halfHotspotConeAngleCos", &half_hotspot_cone_angle_cos),
|
||||
@@ -844,7 +857,7 @@ impl DeferredLightRenderer {
|
||||
property("invViewProj", &inv_view_projection),
|
||||
property("lightPos", &light.position),
|
||||
property("lightColor", &color),
|
||||
property("cameraPosition", &camera_global_position),
|
||||
property("cameraPosition", &observer.position.translation),
|
||||
property("lightRadius", &light_radius),
|
||||
property("shadowBias", &shadow_bias),
|
||||
property("lightIntensity", &light.intensity),
|
||||
@@ -916,15 +929,14 @@ impl DeferredLightRenderer {
|
||||
];
|
||||
let shadow_map_inv_size = 1.0 / (self.csm_renderer.size() as f32);
|
||||
let shadow_bias = csm_options.shadow_bias();
|
||||
let view_matrix = camera.view_matrix();
|
||||
let properties = PropertyGroup::from([
|
||||
property("worldViewProjection", &frame_matrix),
|
||||
property("viewMatrix", &view_matrix),
|
||||
property("viewMatrix", &observer.position.view_matrix),
|
||||
property("invViewProj", &inv_view_projection),
|
||||
property("lightViewProjMatrices", matrices.as_slice()),
|
||||
property("lightColor", &color),
|
||||
property("lightDirection", &emit_direction),
|
||||
property("cameraPosition", &camera_global_position),
|
||||
property("cameraPosition", &observer.position.translation),
|
||||
property("lightIntensity", &light.intensity),
|
||||
property("shadowsEnabled", &shadows_enabled),
|
||||
property("shadowBias", &shadow_bias),
|
||||
@@ -1006,9 +1018,9 @@ impl DeferredLightRenderer {
|
||||
light,
|
||||
gbuffer,
|
||||
&self.quad,
|
||||
camera.view_matrix(),
|
||||
observer.position.view_matrix,
|
||||
inv_projection,
|
||||
view_projection,
|
||||
observer.position.view_projection_matrix,
|
||||
viewport,
|
||||
&scene.graph,
|
||||
frame_buffer,
|
||||
|
||||
@@ -49,6 +49,7 @@ mod shadow;
|
||||
mod ssao;
|
||||
mod stats;
|
||||
|
||||
use crate::renderer::bundle::Observer;
|
||||
use crate::scene::node::Node;
|
||||
use crate::{
|
||||
asset::{event::ResourceEvent, manager::ResourceManager},
|
||||
@@ -65,12 +66,11 @@ use crate::{
|
||||
uuid_provider,
|
||||
},
|
||||
engine::error::EngineError,
|
||||
graph::SceneGraph,
|
||||
gui::draw::DrawingContext,
|
||||
material::shader::{Shader, ShaderDefinition},
|
||||
renderer::{
|
||||
bloom::BloomRenderer,
|
||||
bundle::{ObserverInfo, RenderDataBundleStorage, RenderDataBundleStorageOptions},
|
||||
bundle::{RenderDataBundleStorage, RenderDataBundleStorageOptions},
|
||||
cache::{
|
||||
geometry::GeometryCache,
|
||||
shader::{
|
||||
@@ -899,10 +899,7 @@ pub struct SceneRenderPassContext<'a, 'b> {
|
||||
pub scene: &'b Scene,
|
||||
|
||||
/// A camera from the scene that is used as "eyes".
|
||||
pub camera: &'b Camera,
|
||||
|
||||
/// A viewport of the camera.
|
||||
pub viewport: Rect<i32>,
|
||||
pub observer: &'b Observer,
|
||||
|
||||
/// A handle of the scene being rendered.
|
||||
pub scene_handle: Handle<Scene>,
|
||||
@@ -1038,6 +1035,24 @@ fn render_target_size(render_target: &TextureResource) -> Result<Vector2<f32>, F
|
||||
})
|
||||
}
|
||||
|
||||
fn collect_observers(scene: &Scene, frame_size: Vector2<f32>) -> Vec<Observer> {
|
||||
scene
|
||||
.graph
|
||||
.linear_iter()
|
||||
.filter_map(|node| {
|
||||
if node.is_globally_enabled() {
|
||||
if let Some(camera) = node.cast::<Camera>() {
|
||||
if camera.is_enabled() {
|
||||
return Some(camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.map(|camera| Observer::from_camera(camera, frame_size))
|
||||
.collect()
|
||||
}
|
||||
|
||||
impl Renderer {
|
||||
/// Creates a new renderer with the given graphics server.
|
||||
pub fn new(
|
||||
@@ -1520,19 +1535,13 @@ impl Renderer {
|
||||
.camera_data
|
||||
.retain(|h, _| graph.is_valid_handle(*h));
|
||||
|
||||
for (camera_handle, camera) in graph.pair_iter().filter_map(|(handle, node)| {
|
||||
if node.is_globally_enabled() {
|
||||
if let Some(camera) = node.cast::<Camera>() {
|
||||
if camera.is_enabled() {
|
||||
return Some((handle, camera));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}) {
|
||||
let (render_data, rt_size) = if let Some(render_target) = camera.render_target() {
|
||||
let observers = collect_observers(scene, frame_size);
|
||||
|
||||
for observer in &observers {
|
||||
let render_data = if let Some(render_target) = observer.render_target.as_ref() {
|
||||
let rt_size = render_target_size(render_target)?;
|
||||
let camera_render_data = match scene_render_data.camera_data.entry(camera_handle) {
|
||||
let camera_render_data = match scene_render_data.camera_data.entry(observer.handle)
|
||||
{
|
||||
Entry::Occupied(entry) => {
|
||||
let camera_render_data = entry.into_mut();
|
||||
recreate_render_data_if_needed(
|
||||
@@ -1546,7 +1555,8 @@ impl Renderer {
|
||||
Entry::Vacant(entry) => {
|
||||
let render_data = entry.insert(RenderDataContainer::new(server, rt_size)?);
|
||||
info!(
|
||||
"A new associated scene rendering data was created for camera {camera_handle}!"
|
||||
"A new associated scene rendering data was created for camera {}!",
|
||||
observer.handle
|
||||
);
|
||||
render_data
|
||||
}
|
||||
@@ -1558,26 +1568,20 @@ impl Renderer {
|
||||
camera_render_data.ldr_scene_frame_texture().clone(),
|
||||
)?;
|
||||
|
||||
(camera_render_data, rt_size)
|
||||
camera_render_data
|
||||
} else {
|
||||
(&mut scene_render_data.scene_data, frame_size)
|
||||
&mut scene_render_data.scene_data
|
||||
};
|
||||
|
||||
let visibility_cache = self.visibility_cache.get_or_register(graph, camera_handle);
|
||||
|
||||
let viewport = camera.viewport_pixels(rt_size);
|
||||
let visibility_cache = self
|
||||
.visibility_cache
|
||||
.get_or_register(graph, observer.handle);
|
||||
|
||||
let bundle_storage = RenderDataBundleStorage::from_graph(
|
||||
graph,
|
||||
*camera.render_mask,
|
||||
observer.render_mask,
|
||||
elapsed_time,
|
||||
ObserverInfo {
|
||||
observer_position: camera.global_position(),
|
||||
z_near: camera.projection().z_near(),
|
||||
z_far: camera.projection().z_far(),
|
||||
view_matrix: camera.view_matrix(),
|
||||
projection_matrix: camera.projection_matrix(),
|
||||
},
|
||||
&observer.position,
|
||||
GBUFFER_PASS_NAME.clone(),
|
||||
RenderDataBundleStorageOptions {
|
||||
collect_lights: true,
|
||||
@@ -1592,7 +1596,7 @@ impl Renderer {
|
||||
|
||||
render_data.statistics += render_data.gbuffer.fill(GBufferRenderContext {
|
||||
server,
|
||||
camera,
|
||||
observer,
|
||||
geom_cache: &mut self.geometry_cache,
|
||||
bundle_storage: &bundle_storage,
|
||||
texture_cache: &mut self.texture_cache,
|
||||
@@ -1611,7 +1615,7 @@ impl Renderer {
|
||||
render_data.copy_depth_stencil_to_scene_framebuffer();
|
||||
|
||||
render_data.hdr_scene_framebuffer.clear(
|
||||
viewport,
|
||||
observer.viewport,
|
||||
Some(
|
||||
scene
|
||||
.rendering_options
|
||||
@@ -1628,7 +1632,7 @@ impl Renderer {
|
||||
elapsed_time,
|
||||
server,
|
||||
scene,
|
||||
camera,
|
||||
observer,
|
||||
gbuffer: &mut render_data.gbuffer,
|
||||
ambient_color: scene.rendering_options.ambient_lighting_color,
|
||||
render_data_bundle: &bundle_storage,
|
||||
@@ -1656,7 +1660,7 @@ impl Renderer {
|
||||
shader_cache: &mut self.shader_cache,
|
||||
bundle_storage: &bundle_storage,
|
||||
framebuffer: &render_data.hdr_scene_framebuffer,
|
||||
viewport,
|
||||
viewport: observer.viewport,
|
||||
quality_settings: &self.quality_settings,
|
||||
fallback_resources: &self.fallback_resources,
|
||||
scene_depth: depth,
|
||||
@@ -1676,9 +1680,8 @@ impl Renderer {
|
||||
shader_cache: &mut self.shader_cache,
|
||||
quality_settings: &self.quality_settings,
|
||||
bundle_storage: &bundle_storage,
|
||||
viewport,
|
||||
scene,
|
||||
camera,
|
||||
observer,
|
||||
scene_handle,
|
||||
fallback_resources: &self.fallback_resources,
|
||||
depth_texture: render_data.gbuffer.depth(),
|
||||
@@ -1708,12 +1711,12 @@ impl Renderer {
|
||||
render_data.hdr_scene_frame_texture(),
|
||||
render_data.bloom_renderer.result(),
|
||||
&render_data.ldr_scene_framebuffer,
|
||||
viewport,
|
||||
observer.viewport,
|
||||
quad,
|
||||
dt,
|
||||
camera.exposure(),
|
||||
camera.color_grading_lut_ref(),
|
||||
camera.color_grading_enabled(),
|
||||
observer.exposure,
|
||||
observer.color_grading_lut.as_ref(),
|
||||
observer.color_grading_enabled,
|
||||
&mut self.texture_cache,
|
||||
&mut self.uniform_buffer_cache,
|
||||
&self.fallback_resources,
|
||||
@@ -1722,7 +1725,7 @@ impl Renderer {
|
||||
// Apply FXAA if needed.
|
||||
if self.quality_settings.fxaa {
|
||||
render_data.statistics += self.fxaa_renderer.render(
|
||||
viewport,
|
||||
observer.viewport,
|
||||
render_data.ldr_scene_frame_texture(),
|
||||
&render_data.ldr_temp_framebuffer,
|
||||
&mut self.uniform_buffer_cache,
|
||||
@@ -1736,7 +1739,7 @@ impl Renderer {
|
||||
&render_data.ldr_scene_framebuffer,
|
||||
temp_frame_texture,
|
||||
&self.blit_shader,
|
||||
viewport,
|
||||
observer.viewport,
|
||||
quad,
|
||||
&self.fallback_resources,
|
||||
)?;
|
||||
@@ -1746,9 +1749,9 @@ impl Renderer {
|
||||
self.debug_renderer.set_lines(&scene.drawing_context.lines);
|
||||
render_data.statistics += self.debug_renderer.render(
|
||||
&mut self.uniform_buffer_cache,
|
||||
viewport,
|
||||
observer.viewport,
|
||||
&render_data.ldr_scene_framebuffer,
|
||||
camera.view_projection_matrix(),
|
||||
observer.position.view_projection_matrix,
|
||||
)?;
|
||||
|
||||
for render_pass in self.scene_render_passes.iter() {
|
||||
@@ -1763,9 +1766,8 @@ impl Renderer {
|
||||
shader_cache: &mut self.shader_cache,
|
||||
quality_settings: &self.quality_settings,
|
||||
bundle_storage: &bundle_storage,
|
||||
viewport,
|
||||
scene,
|
||||
camera,
|
||||
observer,
|
||||
scene_handle,
|
||||
fallback_resources: &self.fallback_resources,
|
||||
depth_texture: render_data.gbuffer.depth(),
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
use crate::renderer::bundle::Observer;
|
||||
use crate::renderer::DynamicSurfaceCache;
|
||||
use crate::{
|
||||
core::{
|
||||
@@ -27,7 +28,7 @@ use crate::{
|
||||
},
|
||||
renderer::{
|
||||
bundle::{
|
||||
BundleRenderContext, LightSource, LightSourceKind, ObserverInfo,
|
||||
BundleRenderContext, LightSource, LightSourceKind, ObserverPosition,
|
||||
RenderDataBundleStorage, RenderDataBundleStorageOptions,
|
||||
},
|
||||
cache::{
|
||||
@@ -43,7 +44,6 @@ use crate::{
|
||||
FallbackResources, RenderPassStatistics, ShadowMapPrecision, DIRECTIONAL_SHADOW_PASS_NAME,
|
||||
},
|
||||
scene::{
|
||||
camera::Camera,
|
||||
graph::Graph,
|
||||
light::directional::{FrustumSplitOptions, CSM_NUM_CASCADES},
|
||||
},
|
||||
@@ -103,7 +103,7 @@ pub(crate) struct CsmRenderContext<'a, 'c> {
|
||||
pub state: &'a dyn GraphicsServer,
|
||||
pub graph: &'c Graph,
|
||||
pub light: &'c LightSource,
|
||||
pub camera: &'c Camera,
|
||||
pub observer: &'a Observer,
|
||||
pub geom_cache: &'a mut GeometryCache,
|
||||
pub shader_cache: &'a mut ShaderCache,
|
||||
pub texture_cache: &'a mut TextureCache,
|
||||
@@ -153,7 +153,7 @@ impl CsmRenderer {
|
||||
state,
|
||||
graph,
|
||||
light,
|
||||
camera,
|
||||
observer,
|
||||
geom_cache,
|
||||
shader_cache,
|
||||
texture_cache,
|
||||
@@ -178,16 +178,16 @@ impl CsmRenderer {
|
||||
|
||||
let z_values = match csm_options.split_options {
|
||||
FrustumSplitOptions::Absolute { far_planes } => [
|
||||
camera.projection().z_near(),
|
||||
observer.position.z_near,
|
||||
far_planes[0],
|
||||
far_planes[1],
|
||||
far_planes[2],
|
||||
],
|
||||
FrustumSplitOptions::Relative { fractions } => [
|
||||
camera.projection().z_near(),
|
||||
camera.projection().z_far() * fractions[0],
|
||||
camera.projection().z_far() * fractions[1],
|
||||
camera.projection().z_far() * fractions[2],
|
||||
observer.position.z_near,
|
||||
observer.position.z_far * fractions[0],
|
||||
observer.position.z_far * fractions[1],
|
||||
observer.position.z_far * fractions[2],
|
||||
],
|
||||
};
|
||||
|
||||
@@ -202,16 +202,17 @@ impl CsmRenderer {
|
||||
z_far += MIN_DEPTH_DELTA * z_near;
|
||||
}
|
||||
|
||||
let projection_matrix = camera
|
||||
.projection()
|
||||
let projection_matrix = observer
|
||||
.projection
|
||||
.clone()
|
||||
.with_z_near(z_near)
|
||||
.with_z_far(z_far)
|
||||
.matrix(frame_size);
|
||||
|
||||
let frustum =
|
||||
Frustum::from_view_projection_matrix(projection_matrix * camera.view_matrix())
|
||||
.unwrap_or_default();
|
||||
let frustum = Frustum::from_view_projection_matrix(
|
||||
projection_matrix * observer.position.view_matrix,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
let center = frustum.center();
|
||||
let observer_position = center + light_direction;
|
||||
@@ -256,14 +257,15 @@ impl CsmRenderer {
|
||||
|
||||
let bundle_storage = RenderDataBundleStorage::from_graph(
|
||||
graph,
|
||||
*camera.render_mask,
|
||||
observer.render_mask,
|
||||
elapsed_time,
|
||||
ObserverInfo {
|
||||
observer_position,
|
||||
&ObserverPosition {
|
||||
translation: observer_position,
|
||||
z_near,
|
||||
z_far,
|
||||
view_matrix: light_view_matrix,
|
||||
projection_matrix: cascade_projection_matrix,
|
||||
view_projection_matrix: cascade_projection_matrix * light_view_matrix,
|
||||
},
|
||||
DIRECTIONAL_SHADOW_PASS_NAME.clone(),
|
||||
RenderDataBundleStorageOptions {
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::{
|
||||
},
|
||||
renderer::{
|
||||
bundle::{
|
||||
BundleRenderContext, ObserverInfo, RenderDataBundleStorage,
|
||||
BundleRenderContext, ObserverPosition, RenderDataBundleStorage,
|
||||
RenderDataBundleStorageOptions,
|
||||
},
|
||||
cache::{shader::ShaderCache, texture::TextureCache, uniform::UniformMemoryAllocator},
|
||||
@@ -217,12 +217,13 @@ impl PointShadowMapRenderer {
|
||||
graph,
|
||||
render_mask,
|
||||
elapsed_time,
|
||||
ObserverInfo {
|
||||
observer_position: light_pos,
|
||||
&ObserverPosition {
|
||||
translation: light_pos,
|
||||
z_near,
|
||||
z_far,
|
||||
view_matrix: light_view_matrix,
|
||||
projection_matrix: light_projection_matrix,
|
||||
view_projection_matrix: light_projection_matrix * light_view_matrix,
|
||||
},
|
||||
POINT_SHADOW_PASS_NAME.clone(),
|
||||
RenderDataBundleStorageOptions {
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::{
|
||||
},
|
||||
renderer::{
|
||||
bundle::{
|
||||
BundleRenderContext, ObserverInfo, RenderDataBundleStorage,
|
||||
BundleRenderContext, ObserverPosition, RenderDataBundleStorage,
|
||||
RenderDataBundleStorageOptions,
|
||||
},
|
||||
cache::{shader::ShaderCache, texture::TextureCache, uniform::UniformMemoryAllocator},
|
||||
@@ -146,12 +146,13 @@ impl SpotShadowMapRenderer {
|
||||
graph,
|
||||
render_mask,
|
||||
elapsed_time,
|
||||
ObserverInfo {
|
||||
observer_position: light_position,
|
||||
&ObserverPosition {
|
||||
translation: light_position,
|
||||
z_near,
|
||||
z_far,
|
||||
view_matrix: light_view_matrix,
|
||||
projection_matrix: light_projection_matrix,
|
||||
view_projection_matrix: light_projection_matrix * light_view_matrix,
|
||||
},
|
||||
SPOT_SHADOW_PASS_NAME.clone(),
|
||||
RenderDataBundleStorageOptions {
|
||||
|
||||
@@ -180,7 +180,7 @@ impl BatchContainer {
|
||||
descendant.collect_render_data(&mut RenderContext {
|
||||
render_mask: ctx.render_mask,
|
||||
elapsed_time: ctx.elapsed_time,
|
||||
observer_info: ctx.observer_info,
|
||||
observer_position: ctx.observer_position,
|
||||
frustum: None,
|
||||
storage: self,
|
||||
graph: ctx.graph,
|
||||
|
||||
@@ -588,7 +588,7 @@ impl NodeTrait for ParticleSystem {
|
||||
|
||||
fn collect_render_data(&self, ctx: &mut RenderContext) -> RdcControlFlow {
|
||||
if !self.should_be_rendered(ctx.frustum, ctx.render_mask)
|
||||
|| self.is_distance_clipped(&ctx.observer_info.observer_position)
|
||||
|| self.is_distance_clipped(&ctx.observer_position.translation)
|
||||
{
|
||||
return RdcControlFlow::Continue;
|
||||
}
|
||||
@@ -598,8 +598,8 @@ impl NodeTrait for ParticleSystem {
|
||||
}
|
||||
|
||||
let distance_to_observer = ctx
|
||||
.observer_info
|
||||
.observer_position
|
||||
.translation
|
||||
.metric_distance(&self.global_position());
|
||||
|
||||
let particle_alpha_factor = if distance_to_observer >= self.visible_distance() {
|
||||
@@ -614,7 +614,7 @@ impl NodeTrait for ParticleSystem {
|
||||
let actual_position = particle.position + self.base.global_position();
|
||||
particle
|
||||
.sqr_distance_to_camera
|
||||
.set((ctx.observer_info.observer_position - actual_position).norm_squared());
|
||||
.set((ctx.observer_position.translation - actual_position).norm_squared());
|
||||
sorted_particles.push(i as u32);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2650,7 +2650,7 @@ impl NodeTrait for Terrain {
|
||||
let quad_tree = chunk.quad_tree.lock();
|
||||
let levels = (0..=quad_tree.max_level)
|
||||
.map(|n| {
|
||||
ctx.observer_info.z_far
|
||||
ctx.observer_position.z_far
|
||||
* ((quad_tree.max_level - n) as f32 / quad_tree.max_level as f32)
|
||||
.powf(3.0)
|
||||
})
|
||||
@@ -2669,7 +2669,7 @@ impl NodeTrait for Terrain {
|
||||
self.height_map_size(),
|
||||
self.chunk_size(),
|
||||
ctx.frustum,
|
||||
ctx.observer_info.observer_position,
|
||||
ctx.observer_position.translation,
|
||||
&levels,
|
||||
&mut selection,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user