From 8e512692083c7c16b5d69a834d209f2a39f5cd28 Mon Sep 17 00:00:00 2001 From: Dmitry Stepanov Date: Wed, 2 Oct 2024 20:42:52 +0300 Subject: [PATCH] more uniform buffers --- editor/resources/shaders/overlay_vs.glsl | 16 ++++--- editor/src/overlay.rs | 50 ++++++++++---------- fyrox-impl/src/renderer/light/mod.rs | 34 +++++++------ fyrox-impl/src/renderer/mod.rs | 2 +- fyrox-impl/src/renderer/shaders/blur_vs.glsl | 8 ++-- fyrox-impl/src/renderer/ssao/blur.rs | 41 +++++++++------- fyrox-impl/src/renderer/ssao/mod.rs | 37 +++++++-------- 7 files changed, 100 insertions(+), 88 deletions(-) diff --git a/editor/resources/shaders/overlay_vs.glsl b/editor/resources/shaders/overlay_vs.glsl index 4d299a9a8..299d659e3 100644 --- a/editor/resources/shaders/overlay_vs.glsl +++ b/editor/resources/shaders/overlay_vs.glsl @@ -1,11 +1,13 @@ -layout(location = 0) in vec3 vertexPosition; -layout(location = 1) in vec2 vertexTexCoord; +layout (location = 0) in vec3 vertexPosition; +layout (location = 1) in vec2 vertexTexCoord; -uniform mat4 viewProjectionMatrix; -uniform mat4 worldMatrix; -uniform vec3 cameraUpVector; -uniform vec3 cameraSideVector; -uniform float size; +layout (std140) uniform Uniforms { + mat4 viewProjectionMatrix; + mat4 worldMatrix; + vec3 cameraSideVector; + vec3 cameraUpVector; + float size; +}; out vec2 texCoord; diff --git a/editor/src/overlay.rs b/editor/src/overlay.rs index e3a3fa204..91afb357c 100644 --- a/editor/src/overlay.rs +++ b/editor/src/overlay.rs @@ -23,11 +23,15 @@ use crate::{ core::{algebra::Matrix4, math::Matrix4Ext, sstorage::ImmutableString}, renderer::{ framework::{ + buffer::BufferUsage, error::FrameworkError, + framebuffer::{ResourceBindGroup, ResourceBinding}, geometry_buffer::GeometryBuffer, gpu_program::{GpuProgram, UniformLocation}, state::GlGraphicsServer, - BlendFactor, BlendFunc, BlendParameters, DrawParameters, ElementRange, + uniform::StaticUniformBuffer, + BlendFactor, BlendFunc, BlendParameters, CompareFunc, DrawParameters, ElementRange, + GeometryBufferExt, }, RenderPassStatistics, SceneRenderPass, SceneRenderPassContext, }, @@ -39,19 +43,12 @@ use crate::{ }, Editor, }; -use fyrox::renderer::framework::buffer::BufferUsage; -use fyrox::renderer::framework::framebuffer::{ResourceBindGroup, ResourceBinding}; -use fyrox::renderer::framework::{CompareFunc, GeometryBufferExt}; use std::{any::TypeId, cell::RefCell, rc::Rc}; struct OverlayShader { program: GpuProgram, - view_projection_matrix: UniformLocation, - world_matrix: UniformLocation, - camera_side_vector: UniformLocation, - camera_up_vector: UniformLocation, diffuse_texture: UniformLocation, - size: UniformLocation, + uniform_buffer_binding: usize, } impl OverlayShader { @@ -61,14 +58,8 @@ impl OverlayShader { let program = GpuProgram::from_source(server, "OverlayShader", vertex_source, fragment_source)?; Ok(Self { - view_projection_matrix: program - .uniform_location(server, &ImmutableString::new("viewProjectionMatrix"))?, - world_matrix: program.uniform_location(server, &ImmutableString::new("worldMatrix"))?, - camera_side_vector: program - .uniform_location(server, &ImmutableString::new("cameraSideVector"))?, - camera_up_vector: program - .uniform_location(server, &ImmutableString::new("cameraUpVector"))?, - size: program.uniform_location(server, &ImmutableString::new("size"))?, + uniform_buffer_binding: program + .uniform_block_index(server, &ImmutableString::new("Uniforms"))?, diffuse_texture: program .uniform_location(server, &ImmutableString::new("diffuseTexture"))?, program, @@ -163,17 +154,24 @@ impl SceneRenderPass for OverlayRenderPass { scissor_box: None, }, &[ResourceBindGroup { - bindings: &[ResourceBinding::texture(&icon, &shader.diffuse_texture)], + bindings: &[ + ResourceBinding::texture(&icon, &shader.diffuse_texture), + ResourceBinding::Buffer { + buffer: ctx.uniform_buffer_cache.write( + ctx.server, + StaticUniformBuffer::<256>::new() + .with(&view_projection) + .with(&world_matrix) + .with(&camera_side) + .with(&camera_up) + .with(&self.pictogram_size), + )?, + shader_location: shader.uniform_buffer_binding, + }, + ], }], ElementRange::Full, - &mut |mut program_binding| { - program_binding - .set_matrix4(&shader.view_projection_matrix, &view_projection) - .set_matrix4(&shader.world_matrix, &world_matrix) - .set_vector3(&shader.camera_side_vector, &camera_side) - .set_vector3(&shader.camera_up_vector, &camera_up) - .set_f32(&shader.size, self.pictogram_size); - }, + &mut |_| {}, )?; } diff --git a/fyrox-impl/src/renderer/light/mod.rs b/fyrox-impl/src/renderer/light/mod.rs index 0dd8e3029..597936951 100644 --- a/fyrox-impl/src/renderer/light/mod.rs +++ b/fyrox-impl/src/renderer/light/mod.rs @@ -89,7 +89,7 @@ pub struct DeferredLightRenderer { } pub(crate) struct DeferredRendererContext<'a> { - pub state: &'a GlGraphicsServer, + pub server: &'a GlGraphicsServer, pub scene: &'a Scene, pub camera: &'a Camera, pub gbuffer: &'a mut GBuffer, @@ -277,7 +277,7 @@ impl DeferredLightRenderer { let mut light_stats = LightingStatistics::default(); let DeferredRendererContext { - state, + server, scene, camera, gbuffer, @@ -321,9 +321,11 @@ impl DeferredLightRenderer { // Fill SSAO map. if settings.use_ssao { pass_stats += self.ssao_renderer.render( + server, gbuffer, projection_matrix, camera.view_matrix().basis(), + uniform_buffer_cache, )?; } @@ -335,7 +337,7 @@ impl DeferredLightRenderer { if let Some(gpu_texture) = skybox .cubemap_ref() - .and_then(|cube_map| textures.get(state, cube_map)) + .and_then(|cube_map| textures.get(server, cube_map)) { let shader = &self.skybox_shader; pass_stats += frame_buffer.draw( @@ -527,7 +529,7 @@ impl DeferredLightRenderer { // Mark lighted areas in stencil buffer to do light calculations only on them. let uniform_buffer = uniform_buffer_cache.write( - state, + server, StaticUniformBuffer::<256>::new().with(&(view_projection * bounding_shape_matrix)), )?; @@ -600,10 +602,12 @@ impl DeferredLightRenderer { if visibility_cache.needs_occlusion_query(camera_global_position, 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. - let uniform_buffer = uniform_buffer_cache - .write(state, StaticUniformBuffer::<256>::new().with(&frame_matrix))?; + let uniform_buffer = uniform_buffer_cache.write( + server, + StaticUniformBuffer::<256>::new().with(&frame_matrix), + )?; - visibility_cache.begin_query(state, camera_global_position, light_handle)?; + visibility_cache.begin_query(server, camera_global_position, light_handle)?; frame_buffer.draw( &self.quad, viewport, @@ -661,7 +665,7 @@ impl DeferredLightRenderer { light_view_projection = light_projection_matrix * light_view_matrix; pass_stats += self.spot_shadow_map_renderer.render( - state, + server, &scene.graph, light_position, light_view_matrix, @@ -684,7 +688,7 @@ impl DeferredLightRenderer { pass_stats += self.point_shadow_map_renderer .render(PointShadowMapRenderContext { - state, + state: server, graph: &scene.graph, light_pos: light_position, light_radius, @@ -703,7 +707,7 @@ impl DeferredLightRenderer { } else if let Some(directional) = light.cast::() { pass_stats += self.csm_renderer.render(CsmRenderContext { frame_size: Vector2::new(gbuffer.width as f32, gbuffer.height as f32), - state, + state: server, graph: &scene.graph, light: directional, camera, @@ -749,7 +753,7 @@ impl DeferredLightRenderer { let (cookie_enabled, cookie_texture) = if let Some(texture) = spot_light.cookie_texture_ref() { - if let Some(cookie) = textures.get(state, texture) { + if let Some(cookie) = textures.get(server, texture) { (true, cookie) } else { (false, &white_dummy) @@ -763,7 +767,7 @@ impl DeferredLightRenderer { let inv_size = 1.0 / (self.spot_shadow_map_renderer.cascade_size(cascade_index) as f32); let uniform_buffer = uniform_buffer_cache.write( - state, + server, StaticUniformBuffer::<1024>::new() .with(&frame_matrix) .with(&light_view_projection) @@ -824,7 +828,7 @@ impl DeferredLightRenderer { light_stats.point_lights_rendered += 1; let uniform_buffer = uniform_buffer_cache.write( - state, + server, StaticUniformBuffer::<1024>::new() .with(&frame_matrix) .with(&inv_view_projection) @@ -891,7 +895,7 @@ impl DeferredLightRenderer { ]; let uniform_buffer = uniform_buffer_cache.write( - state, + server, StaticUniformBuffer::<1024>::new() .with(&frame_matrix) .with(&camera.view_matrix()) @@ -970,7 +974,7 @@ impl DeferredLightRenderer { // light source. if settings.light_scatter_enabled { pass_stats += self.light_volume.render_volume( - state, + server, light, light_handle, gbuffer, diff --git a/fyrox-impl/src/renderer/mod.rs b/fyrox-impl/src/renderer/mod.rs index 127297a4d..552ff5cfc 100644 --- a/fyrox-impl/src/renderer/mod.rs +++ b/fyrox-impl/src/renderer/mod.rs @@ -1444,7 +1444,7 @@ impl Renderer { let (pass_stats, light_stats) = self.deferred_light_renderer .render(DeferredRendererContext { - state: server, + server: server, scene, camera, gbuffer: &mut scene_associated_data.gbuffer, diff --git a/fyrox-impl/src/renderer/shaders/blur_vs.glsl b/fyrox-impl/src/renderer/shaders/blur_vs.glsl index 1910348f1..649dfc460 100644 --- a/fyrox-impl/src/renderer/shaders/blur_vs.glsl +++ b/fyrox-impl/src/renderer/shaders/blur_vs.glsl @@ -1,7 +1,9 @@ -layout(location = 0) in vec3 vertexPosition; -layout(location = 1) in vec2 vertexTexCoord; +layout (location = 0) in vec3 vertexPosition; +layout (location = 1) in vec2 vertexTexCoord; -uniform mat4 worldViewProjection; +layout (std140) uniform Uniforms { + mat4 worldViewProjection; +}; out vec2 texCoord; diff --git a/fyrox-impl/src/renderer/ssao/blur.rs b/fyrox-impl/src/renderer/ssao/blur.rs index 80e6e471a..950eeb498 100644 --- a/fyrox-impl/src/renderer/ssao/blur.rs +++ b/fyrox-impl/src/renderer/ssao/blur.rs @@ -18,35 +18,36 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -use crate::renderer::framework::GeometryBufferExt; use crate::{ core::{math::Rect, sstorage::ImmutableString}, renderer::{ + cache::uniform::UniformBufferCache, framework::{ + buffer::BufferUsage, error::FrameworkError, - framebuffer::{Attachment, AttachmentKind, FrameBuffer}, + framebuffer::{ + Attachment, AttachmentKind, FrameBuffer, ResourceBindGroup, ResourceBinding, + }, geometry_buffer::{DrawCallStatistics, GeometryBuffer}, gpu_program::{GpuProgram, UniformLocation}, gpu_texture::{ Coordinate, GpuTexture, GpuTextureKind, MagnificationFilter, MinificationFilter, PixelKind, WrapMode, }, - state::GlGraphicsServer, - DrawParameters, ElementRange, + state::{GlGraphicsServer, GraphicsServer}, + uniform::StaticUniformBuffer, + DrawParameters, ElementRange, GeometryBufferExt, }, make_viewport_matrix, }, scene::mesh::surface::SurfaceData, }; -use fyrox_graphics::buffer::BufferUsage; -use fyrox_graphics::framebuffer::{ResourceBindGroup, ResourceBinding}; -use fyrox_graphics::state::GraphicsServer; use std::{cell::RefCell, rc::Rc}; struct Shader { program: GpuProgram, - world_view_projection_matrix: UniformLocation, input_texture: UniformLocation, + uniform_buffer_binding: usize, } impl Shader { @@ -57,8 +58,8 @@ impl Shader { let program = GpuProgram::from_source(server, "BlurShader", vertex_source, fragment_source)?; Ok(Self { - world_view_projection_matrix: program - .uniform_location(server, &ImmutableString::new("worldViewProjection"))?, + uniform_buffer_binding: program + .uniform_block_index(server, &ImmutableString::new("Uniforms"))?, input_texture: program .uniform_location(server, &ImmutableString::new("inputTexture"))?, program, @@ -124,7 +125,9 @@ impl Blur { pub(crate) fn render( &mut self, + server: &dyn GraphicsServer, input: Rc>, + uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { let viewport = Rect::new(0, 0, self.width as i32, self.height as i32); @@ -144,15 +147,19 @@ impl Blur { scissor_box: None, }, &[ResourceBindGroup { - bindings: &[ResourceBinding::texture(&input, &shader.input_texture)], + bindings: &[ + ResourceBinding::texture(&input, &shader.input_texture), + ResourceBinding::Buffer { + buffer: uniform_buffer_cache.write( + server, + StaticUniformBuffer::<256>::new().with(&make_viewport_matrix(viewport)), + )?, + shader_location: shader.uniform_buffer_binding, + }, + ], }], ElementRange::Full, - &mut |mut program_binding| { - program_binding.set_matrix4( - &shader.world_view_projection_matrix, - &(make_viewport_matrix(viewport)), - ); - }, + &mut |_| {}, ) } } diff --git a/fyrox-impl/src/renderer/ssao/mod.rs b/fyrox-impl/src/renderer/ssao/mod.rs index 0931f6643..d88aed91d 100644 --- a/fyrox-impl/src/renderer/ssao/mod.rs +++ b/fyrox-impl/src/renderer/ssao/mod.rs @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +use crate::renderer::cache::uniform::UniformBufferCache; use crate::{ core::{ algebra::{Matrix3, Matrix4, Vector2, Vector3}, @@ -28,7 +29,7 @@ use crate::{ rand::Rng, renderer::{ framework::{ - buffer::{Buffer, BufferKind, BufferUsage}, + buffer::BufferUsage, error::FrameworkError, framebuffer::{Attachment, AttachmentKind, FrameBuffer}, geometry_buffer::GeometryBuffer, @@ -91,7 +92,6 @@ pub struct ScreenSpaceAmbientOcclusionRenderer { shader: Shader, framebuffer: Box, quad: GeometryBuffer, - uniform_buffer: Box, width: i32, height: i32, noise: Rc>, @@ -122,11 +122,6 @@ impl ScreenSpaceAmbientOcclusionRenderer { let mut rng = crate::rand::thread_rng(); Ok(Self { - uniform_buffer: server.create_buffer( - 1024, - BufferKind::Uniform, - BufferUsage::StreamCopy, - )?, blur: Blur::new(server, width, height)?, shader: Shader::new(server)?, framebuffer: server.create_frame_buffer( @@ -207,9 +202,11 @@ impl ScreenSpaceAmbientOcclusionRenderer { pub(crate) fn render( &mut self, + server: &dyn GraphicsServer, gbuffer: &GBuffer, projection_matrix: Matrix4, view_matrix: Matrix3, + uniform_buffer_cache: &mut UniformBufferCache, ) -> Result { let mut stats = RenderPassStatistics::default(); @@ -240,16 +237,17 @@ impl ScreenSpaceAmbientOcclusionRenderer { self.height as f32 / NOISE_SIZE as f32, ); - let mut uniforms = StaticUniformBuffer::<1024>::new(); - uniforms - .push(&frame_matrix) - .push(&projection_matrix.try_inverse().unwrap_or_default()) - .push(&projection_matrix) - .push_slice(&self.kernel) - .push(&noise_scale) - .push(&view_matrix) - .push(&self.radius); - self.uniform_buffer.write_data(uniforms.finish().as_ref())?; + let uniform_buffer = uniform_buffer_cache.write( + server, + StaticUniformBuffer::<1024>::new() + .with(&frame_matrix) + .with(&projection_matrix.try_inverse().unwrap_or_default()) + .with(&projection_matrix) + .with_slice(&self.kernel) + .with(&noise_scale) + .with(&view_matrix) + .with(&self.radius), + )?; stats += self.framebuffer.draw( &self.quad, @@ -274,7 +272,7 @@ impl ScreenSpaceAmbientOcclusionRenderer { ), ResourceBinding::texture(&self.noise, &self.shader.noise_sampler), ResourceBinding::Buffer { - buffer: &*self.uniform_buffer, + buffer: uniform_buffer, shader_location: self.shader.uniform_block_index, }, ], @@ -283,7 +281,8 @@ impl ScreenSpaceAmbientOcclusionRenderer { &mut |_| {}, )?; - self.blur.render(self.raw_ao_map())?; + self.blur + .render(server, self.raw_ao_map(), uniform_buffer_cache)?; Ok(stats) }