1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use rinecs::{EntitiesThreadLocal, ResourcesThreadLocal, SystemThreadLocal, Read, system_thread_local};
use super::{
resources,
geometry::ShadowGeometry,
ShadowMaterialCache, ProgramCache, material::ShadowMaterialOffsets,
};
use rin_gl as gl;
use super::geometry::{AllShadowsCommandBuffer, AllShadowsCommandBufferData};
use super::shadow::{DepthRenderFn, BasicRenderer};
#[cfg(not(any(feature = "webgl", feature = "gles")))]
use super::shadow::{MultiDrawIndirectRenderer, BaseInstanceRenderer};
use super::renderer::RendererType;
use super::DeferredScene;
use std::marker::PhantomData;
struct DepthPrepass<F>{
render_fn: PhantomData<F>,
}
#[system_thread_local(name = "depth prepass")]
#[after("super::geometry::upload_all_shadows_command_buffer")]
#[after("super::geometry::all_shadows_geometry_sort")]
#[needs(
"resources::AllShadowsSortedGeometry",
"resources::AllModelMatricesBuffer",
"resources::CameraUBO",
"ShadowGeometry",
"super::geometry::VertexBuffer",
"super::geometry::IndicesBuffer",
)]
#[needs(
"AllShadowsCommandBuffer",
"AllShadowsCommandBufferData"
)]
#[updates("resources::DepthPrepass")]
#[gpu_stats]
impl<F: DepthRenderFn> SystemThreadLocal for DepthPrepass<F> {
fn run(&mut self, entities: EntitiesThreadLocal, resources: ResourcesThreadLocal){
let glin = resources.get::<gl::Renderer<'static>>().unwrap();
let camera_ubo = resources.get::<resources::CameraUBO>().unwrap();
let gl = glin.with_properties(&[
gl::Property::DepthTest(true),
gl::Property::DepthMask(true),
gl::Property::ColorMask([false, false, false, false]),
gl::Property::CullFace(Some(gl::BACK)),
#[cfg(not(any(feature = "webgl", feature = "gles")))]
gl::Property::DepthClamp(camera_ubo.clamp_depth)
]);
let gl = if camera_ubo.reversed_z{
gl.with_properties(&[gl::Property::DepthFunc(gl::GREATER)])
}else{
gl.with_properties(&[gl::Property::DepthFunc(gl::LESS)])
};
#[cfg(not(any(feature = "webgl", feature = "gles")))]
let gl = if camera_ubo.zero_to_one{
gl.with_properties(&[gl::Property::ClipControl(gl::LOWER_LEFT, gl::ZERO_TO_ONE)])
}else{
gl
};
let all_geometry_sorted = resources.get::<resources::AllShadowsSortedGeometry>().unwrap();
let render_buffer = resources.get::<resources::ScreenRenderBuffer>().unwrap();
let shadow_material_cache = resources.get::<ShadowMaterialCache>().unwrap();
let program_cache = resources.get::<ProgramCache>().unwrap();
let program = super::get_depth_only_shader(&gl);
let gl = gl.context().with_fbo(render_buffer.depth_prepass().unwrap());
let gl = gl.with(&[super::UBOBindingPoints::Camera.to_buffer_binding(&camera_ubo.ubo)]);
program.set_uniform(&super::UBOBindingPoints::Camera.to_uniform_block_binding())
.unwrap();
gl.clear_depth(1.);
F::render_all(
&entities,
&resources,
gl,
&all_geometry_sorted,
program,
&shadow_material_cache,
&program_cache,
);
}
}
pub fn create_depth_prepass(scene: &mut DeferredScene, renderer_ty: RendererType){
match renderer_ty {
#[cfg(not(any(feature = "webgl", feature = "gles")))]
RendererType::MultiDrawIndirect
=> scene.add_system_thread_local(DepthPrepass::<MultiDrawIndirectRenderer>{
render_fn: PhantomData,
}),
#[cfg(not(any(feature = "webgl", feature = "gles")))]
RendererType::BaseInstance
=> scene.add_system_thread_local(DepthPrepass::<BaseInstanceRenderer>{
render_fn: PhantomData,
}),
RendererType::Basic
=> scene.add_system_thread_local(DepthPrepass::<BasicRenderer>{
render_fn: PhantomData,
}),
};
}