Skip to content

Commit

Permalink
replace flat shader uses with specific ones with native shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
mrDIMAS committed Feb 20, 2025
1 parent 09e96e3 commit f408734
Show file tree
Hide file tree
Showing 12 changed files with 398 additions and 310 deletions.
48 changes: 0 additions & 48 deletions fyrox-impl/src/renderer/flat_shader.rs

This file was deleted.

122 changes: 51 additions & 71 deletions fyrox-impl/src/renderer/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,11 @@ use crate::{
},
uniform::{UniformBufferCache, UniformMemoryAllocator},
},
flat_shader::FlatShader,
framework::{
buffer::BufferUsage,
error::FrameworkError,
framebuffer::{BufferLocation, GpuFrameBuffer, ResourceBindGroup, ResourceBinding},
geometry_buffer::GpuGeometryBuffer,
server::GraphicsServer,
uniform::StaticUniformBuffer,
ColorMask, CompareFunc, CullFace, DrawParameters, ElementRange, GeometryBufferExt,
StencilAction, StencilFunc, StencilOp,
buffer::BufferUsage, error::FrameworkError, framebuffer::GpuFrameBuffer,
geometry_buffer::GpuGeometryBuffer, server::GraphicsServer, ColorMask, CompareFunc,
CullFace, DrawParameters, ElementRange, GeometryBufferExt, StencilAction, StencilFunc,
StencilOp,
},
gbuffer::GBuffer,
light_volume::LightVolumeRenderer,
Expand Down Expand Up @@ -78,12 +73,13 @@ pub struct DeferredLightRenderer {
sphere: GpuGeometryBuffer,
cone: GpuGeometryBuffer,
skybox: GpuGeometryBuffer,
flat_shader: FlatShader,
skybox_shader: RenderPassContainer,
spot_shadow_map_renderer: SpotShadowMapRenderer,
point_shadow_map_renderer: PointShadowMapRenderer,
csm_renderer: CsmRenderer,
light_volume: LightVolumeRenderer,
volume_marker: RenderPassContainer,
pixel_counter: RenderPassContainer,
}

pub(crate) struct DeferredRendererContext<'a> {
Expand Down Expand Up @@ -209,7 +205,6 @@ impl DeferredLightRenderer {
BufferUsage::StaticDraw,
server,
)?,
flat_shader: FlatShader::new(server)?,
skybox_shader: RenderPassContainer::from_str(
server,
include_str!("shaders/skybox.shader"),
Expand All @@ -230,6 +225,14 @@ impl DeferredLightRenderer {
quality_defaults.csm_settings.size,
quality_defaults.csm_settings.precision,
)?,
volume_marker: RenderPassContainer::from_str(
server,
include_str!("shaders/volume_marker_lit.shader"),
)?,
pixel_counter: RenderPassContainer::from_str(
server,
include_str!("shaders/pixel_counter.shader"),
)?,
})
}

Expand Down Expand Up @@ -505,44 +508,39 @@ impl DeferredLightRenderer {
let mut light_view_projection = Matrix4::identity();

// Mark lit areas in stencil buffer to do light calculations only on them.
let uniform_buffer = uniform_buffer_cache.write(
StaticUniformBuffer::<256>::new().with(&(view_projection * bounding_shape_matrix)),
)?;

let shape_wvp_matrix = view_projection * bounding_shape_matrix;
for (cull_face, stencil_action) in [
(CullFace::Front, StencilAction::Incr),
(CullFace::Back, StencilAction::Decr),
] {
pass_stats += frame_buffer.draw(
let draw_params = DrawParameters {
cull_face: Some(cull_face),
color_write: ColorMask::all(false),
depth_write: false,
stencil_test: Some(StencilFunc {
func: CompareFunc::Always,
..Default::default()
}),
stencil_op: StencilOp {
zfail: stencil_action,
..Default::default()
},
depth_test: Some(CompareFunc::Less),
blend: None,
scissor_box: None,
};
let properties =
PropertyGroup::from([property("worldViewProjection", &shape_wvp_matrix)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
pass_stats += self.volume_marker.run_pass(
&ImmutableString::new("Primary"),
frame_buffer,
bounding_shape,
viewport,
&self.flat_shader.program,
&DrawParameters {
cull_face: Some(cull_face),
color_write: ColorMask::all(false),
depth_write: false,
stencil_test: Some(StencilFunc {
func: CompareFunc::Always,
..Default::default()
}),
stencil_op: StencilOp {
zfail: stencil_action,
..Default::default()
},
depth_test: Some(CompareFunc::Less),
blend: None,
scissor_box: None,
},
&[ResourceBindGroup {
bindings: &[ResourceBinding::Buffer {
buffer: uniform_buffer.clone(),
binding: BufferLocation::Auto {
shader_location: self.flat_shader.uniform_buffer_binding,
},
data_usage: Default::default(),
}],
}],
ElementRange::Full,
&material,
uniform_buffer_cache,
Default::default(),
Some(&draw_params),
)?;
}

Expand All @@ -557,37 +555,19 @@ 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(StaticUniformBuffer::<256>::new().with(&frame_matrix))?;

visibility_cache.begin_query(server, camera_global_position, light.handle)?;
pass_stats += frame_buffer.draw(
let properties =
PropertyGroup::from([property("worldViewProjection", &frame_matrix)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
pass_stats += self.pixel_counter.run_pass(
&ImmutableString::new("Primary"),
frame_buffer,
&self.quad,
viewport,
&self.flat_shader.program,
&DrawParameters {
cull_face: None,
color_write: ColorMask::all(false),
depth_write: false,
stencil_test: Some(StencilFunc {
func: CompareFunc::NotEqual,
..Default::default()
}),
depth_test: None,
blend: None,
stencil_op: Default::default(),
scissor_box: None,
},
&[ResourceBindGroup {
bindings: &[ResourceBinding::Buffer {
buffer: uniform_buffer,
binding: BufferLocation::Auto {
shader_location: self.flat_shader.uniform_buffer_binding,
},
data_usage: Default::default(),
}],
}],
ElementRange::Full,
&material,
uniform_buffer_cache,
Default::default(),
None,
)?;
visibility_cache.end_query();
}
Expand Down
103 changes: 25 additions & 78 deletions fyrox-impl/src/renderer/light_volume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,9 @@ use crate::{
shader::{binding, property, PropertyGroup, RenderMaterial, RenderPassContainer},
uniform::UniformBufferCache,
},
flat_shader::FlatShader,
framework::{
buffer::BufferUsage,
error::FrameworkError,
framebuffer::{BufferLocation, GpuFrameBuffer, ResourceBindGroup, ResourceBinding},
geometry_buffer::GpuGeometryBuffer,
server::GraphicsServer,
uniform::StaticUniformBuffer,
ColorMask, CompareFunc, DrawParameters, ElementRange, GeometryBufferExt, StencilAction,
StencilFunc, StencilOp,
buffer::BufferUsage, error::FrameworkError, framebuffer::GpuFrameBuffer,
geometry_buffer::GpuGeometryBuffer, server::GraphicsServer, GeometryBufferExt,
},
gbuffer::GBuffer,
make_viewport_matrix, RenderPassStatistics,
Expand All @@ -50,9 +43,9 @@ use crate::{
pub struct LightVolumeRenderer {
spot_light_shader: RenderPassContainer,
point_light_shader: RenderPassContainer,
flat_shader: FlatShader,
cone: GpuGeometryBuffer,
sphere: GpuGeometryBuffer,
volume_marker: RenderPassContainer,
}

impl LightVolumeRenderer {
Expand All @@ -66,7 +59,6 @@ impl LightVolumeRenderer {
server,
include_str!("shaders/point_volumetric.shader"),
)?,
flat_shader: FlatShader::new(server)?,
cone: GpuGeometryBuffer::from_surface_data(
&SurfaceData::make_cone(
16,
Expand All @@ -82,6 +74,10 @@ impl LightVolumeRenderer {
BufferUsage::StaticDraw,
server,
)?,
volume_marker: RenderPassContainer::from_str(
server,
include_str!("shaders/volume_marker_vol.shader"),
)?,
})
}

Expand Down Expand Up @@ -121,7 +117,6 @@ impl LightVolumeRenderer {
// Draw cone into stencil buffer - it will mark pixels for further volumetric light
// calculations, it will significantly reduce amount of pixels for far lights thus
// significantly improve performance.

let k = (full_cone_angle * 0.5 + 1.0f32.to_radians()).tan() * distance;
let light_shape_matrix = Isometry3 {
rotation: graph.global_rotation(light.handle),
Expand All @@ -136,40 +131,17 @@ impl LightVolumeRenderer {
// Clear stencil only.
frame_buffer.clear(viewport, None, None, Some(0));

stats += frame_buffer.draw(
let properties = PropertyGroup::from([property("worldViewProjection", &mvp)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
stats += self.volume_marker.run_pass(
&ImmutableString::new("Primary"),
frame_buffer,
&self.cone,
viewport,
&self.flat_shader.program,
&DrawParameters {
cull_face: None,
color_write: ColorMask::all(false),
depth_write: false,
stencil_test: Some(StencilFunc {
func: CompareFunc::Equal,
ref_value: 0xFF,
mask: 0xFFFF_FFFF,
}),
depth_test: Some(CompareFunc::Less),
blend: None,
stencil_op: StencilOp {
fail: StencilAction::Replace,
zfail: StencilAction::Keep,
zpass: StencilAction::Replace,
write_mask: 0xFFFF_FFFF,
},
scissor_box: None,
},
&[ResourceBindGroup {
bindings: &[ResourceBinding::Buffer {
buffer: uniform_buffer_cache
.write(StaticUniformBuffer::<256>::new().with(&mvp))?,
binding: BufferLocation::Auto {
shader_location: self.flat_shader.uniform_buffer_binding,
},
data_usage: Default::default(),
}],
}],
ElementRange::Full,
&material,
uniform_buffer_cache,
Default::default(),
None,
)?;

// Finally draw fullscreen quad, GPU will calculate scattering only on pixels that were
Expand Down Expand Up @@ -214,42 +186,17 @@ impl LightVolumeRenderer {
* Matrix4::new_nonuniform_scaling(&Vector3::new(k, k, k));
let mvp = view_proj * light_shape_matrix;

let uniform_buffer =
uniform_buffer_cache.write(StaticUniformBuffer::<256>::new().with(&mvp))?;

stats += frame_buffer.draw(
let properties = PropertyGroup::from([property("worldViewProjection", &mvp)]);
let material = RenderMaterial::from([binding("properties", &properties)]);
stats += self.volume_marker.run_pass(
&ImmutableString::new("Primary"),
frame_buffer,
&self.sphere,
viewport,
&self.flat_shader.program,
&DrawParameters {
cull_face: None,
color_write: ColorMask::all(false),
depth_write: false,
stencil_test: Some(StencilFunc {
func: CompareFunc::Equal,
ref_value: 0xFF,
mask: 0xFFFF_FFFF,
}),
depth_test: Some(CompareFunc::Less),
blend: None,
stencil_op: StencilOp {
fail: StencilAction::Replace,
zfail: StencilAction::Keep,
zpass: StencilAction::Replace,
write_mask: 0xFFFF_FFFF,
},
scissor_box: None,
},
&[ResourceBindGroup {
bindings: &[ResourceBinding::Buffer {
buffer: uniform_buffer,
binding: BufferLocation::Auto {
shader_location: self.flat_shader.uniform_buffer_binding,
},
data_usage: Default::default(),
}],
}],
ElementRange::Full,
&material,
uniform_buffer_cache,
Default::default(),
None,
)?;

// Finally draw fullscreen quad, GPU will calculate scattering only on pixels that were
Expand Down
Loading

0 comments on commit f408734

Please sign in to comment.