1 | /**************************************************************************/ |
2 | /* ss_effects.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef SS_EFFECTS_RD_H |
32 | #define SS_EFFECTS_RD_H |
33 | |
34 | #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" |
35 | #include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl.gen.h" |
36 | #include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl.gen.h" |
37 | #include "servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl.gen.h" |
38 | #include "servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl.gen.h" |
39 | #include "servers/rendering/renderer_rd/shaders/effects/ssao.glsl.gen.h" |
40 | #include "servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl.gen.h" |
41 | #include "servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl.gen.h" |
42 | #include "servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl.gen.h" |
43 | #include "servers/rendering/renderer_rd/shaders/effects/ssil.glsl.gen.h" |
44 | #include "servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl.gen.h" |
45 | #include "servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl.gen.h" |
46 | #include "servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl.gen.h" |
47 | #include "servers/rendering/renderer_rd/shaders/effects/subsurface_scattering.glsl.gen.h" |
48 | #include "servers/rendering/renderer_scene_render.h" |
49 | #include "servers/rendering_server.h" |
50 | |
51 | #define RB_SCOPE_SSDS SNAME("rb_ssds") |
52 | #define RB_SCOPE_SSIL SNAME("rb_ssil") |
53 | #define RB_SCOPE_SSAO SNAME("rb_ssao") |
54 | #define RB_SCOPE_SSR SNAME("rb_ssr") |
55 | |
56 | #define RB_LINEAR_DEPTH SNAME("linear_depth") |
57 | #define RB_FINAL SNAME("final") |
58 | #define RB_LAST_FRAME SNAME("last_frame") |
59 | #define RB_DEINTERLEAVED SNAME("deinterleaved") |
60 | #define RB_DEINTERLEAVED_PONG SNAME("deinterleaved_pong") |
61 | #define RB_EDGES SNAME("edges") |
62 | #define RB_IMPORTANCE_MAP SNAME("importance_map") |
63 | #define RB_IMPORTANCE_PONG SNAME("importance_pong") |
64 | |
65 | #define RB_DEPTH_SCALED SNAME("depth_scaled") |
66 | #define RB_NORMAL_SCALED SNAME("normal_scaled") |
67 | #define RB_BLUR_RADIUS SNAME("blur_radius") |
68 | #define RB_INTERMEDIATE SNAME("intermediate") |
69 | #define RB_OUTPUT SNAME("output") |
70 | |
71 | class RenderSceneBuffersRD; |
72 | |
73 | namespace RendererRD { |
74 | |
75 | class SSEffects { |
76 | private: |
77 | static SSEffects *singleton; |
78 | |
79 | public: |
80 | static SSEffects *get_singleton() { return singleton; } |
81 | |
82 | SSEffects(); |
83 | ~SSEffects(); |
84 | |
85 | /* SS Downsampler */ |
86 | |
87 | void downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_view, const Projection &p_projection); |
88 | |
89 | /* SSIL */ |
90 | void ssil_set_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to); |
91 | |
92 | struct SSILRenderBuffers { |
93 | bool half_size = false; |
94 | int buffer_width; |
95 | int buffer_height; |
96 | int half_buffer_width; |
97 | int half_buffer_height; |
98 | }; |
99 | |
100 | struct SSILSettings { |
101 | float radius = 1.0; |
102 | float intensity = 2.0; |
103 | float sharpness = 0.98; |
104 | float normal_rejection = 1.0; |
105 | |
106 | Size2i full_screen_size; |
107 | }; |
108 | |
109 | void ssil_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings); |
110 | void screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings); |
111 | |
112 | /* SSAO */ |
113 | void ssao_set_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to); |
114 | |
115 | struct SSAORenderBuffers { |
116 | bool half_size = false; |
117 | int buffer_width; |
118 | int buffer_height; |
119 | int half_buffer_width; |
120 | int half_buffer_height; |
121 | }; |
122 | |
123 | struct SSAOSettings { |
124 | float radius = 1.0; |
125 | float intensity = 2.0; |
126 | float power = 1.5; |
127 | float detail = 0.5; |
128 | float horizon = 0.06; |
129 | float sharpness = 0.98; |
130 | |
131 | Size2i full_screen_size; |
132 | }; |
133 | |
134 | void ssao_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings); |
135 | void generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings); |
136 | |
137 | /* Screen Space Reflection */ |
138 | void ssr_set_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality); |
139 | |
140 | struct SSRRenderBuffers { |
141 | Size2i size; |
142 | RenderingServer::EnvironmentSSRRoughnessQuality roughness_quality = RenderingServer::ENV_SSR_ROUGHNESS_QUALITY_DISABLED; |
143 | }; |
144 | |
145 | void ssr_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format); |
146 | void screen_space_reflection(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const Projection *p_projections, const Vector3 *p_eye_offsets); |
147 | |
148 | /* subsurface scattering */ |
149 | void sss_set_quality(RS::SubSurfaceScatteringQuality p_quality); |
150 | RS::SubSurfaceScatteringQuality sss_get_quality() const; |
151 | void sss_set_scale(float p_scale, float p_depth_scale); |
152 | |
153 | void sub_surface_scattering(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_diffuse, RID p_depth, const Projection &p_camera, const Size2i &p_screen_size); |
154 | |
155 | private: |
156 | /* Settings */ |
157 | |
158 | RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM; |
159 | bool ssao_half_size = false; |
160 | float ssao_adaptive_target = 0.5; |
161 | int ssao_blur_passes = 2; |
162 | float ssao_fadeout_from = 50.0; |
163 | float ssao_fadeout_to = 300.0; |
164 | |
165 | RS::EnvironmentSSILQuality ssil_quality = RS::ENV_SSIL_QUALITY_MEDIUM; |
166 | bool ssil_half_size = false; |
167 | float ssil_adaptive_target = 0.5; |
168 | int ssil_blur_passes = 4; |
169 | float ssil_fadeout_from = 50.0; |
170 | float ssil_fadeout_to = 300.0; |
171 | |
172 | RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; |
173 | |
174 | RS::SubSurfaceScatteringQuality sss_quality = RS::SUB_SURFACE_SCATTERING_QUALITY_MEDIUM; |
175 | float sss_scale = 0.05; |
176 | float sss_depth_scale = 0.01; |
177 | |
178 | /* SS Downsampler */ |
179 | |
180 | struct SSEffectsDownsamplePushConstant { |
181 | float pixel_size[2]; |
182 | float z_far; |
183 | float z_near; |
184 | uint32_t orthogonal; |
185 | float radius_sq; |
186 | uint32_t pad[2]; |
187 | }; |
188 | |
189 | enum SSEffectsMode { |
190 | SS_EFFECTS_DOWNSAMPLE, |
191 | SS_EFFECTS_DOWNSAMPLE_HALF_RES, |
192 | SS_EFFECTS_DOWNSAMPLE_MIPMAP, |
193 | SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES, |
194 | SS_EFFECTS_DOWNSAMPLE_HALF, |
195 | SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF, |
196 | SS_EFFECTS_DOWNSAMPLE_FULL_MIPS, |
197 | SS_EFFECTS_MAX |
198 | }; |
199 | |
200 | struct SSEffectsGatherConstants { |
201 | float rotation_matrices[80]; //5 vec4s * 4 |
202 | }; |
203 | |
204 | struct SSEffectsShader { |
205 | SSEffectsDownsamplePushConstant downsample_push_constant; |
206 | SsEffectsDownsampleShaderRD downsample_shader; |
207 | RID downsample_shader_version; |
208 | bool used_half_size_last_frame = false; |
209 | bool used_mips_last_frame = false; |
210 | bool used_full_mips_last_frame = false; |
211 | |
212 | RID gather_constants_buffer; |
213 | |
214 | RID mirror_sampler; |
215 | |
216 | RID pipelines[SS_EFFECTS_MAX]; |
217 | } ss_effects; |
218 | |
219 | /* SSIL */ |
220 | |
221 | enum SSILMode { |
222 | SSIL_GATHER, |
223 | SSIL_GATHER_BASE, |
224 | SSIL_GATHER_ADAPTIVE, |
225 | SSIL_GENERATE_IMPORTANCE_MAP, |
226 | SSIL_PROCESS_IMPORTANCE_MAPA, |
227 | SSIL_PROCESS_IMPORTANCE_MAPB, |
228 | SSIL_BLUR_PASS, |
229 | SSIL_BLUR_PASS_SMART, |
230 | SSIL_BLUR_PASS_WIDE, |
231 | SSIL_INTERLEAVE, |
232 | SSIL_INTERLEAVE_SMART, |
233 | SSIL_INTERLEAVE_HALF, |
234 | SSIL_MAX |
235 | }; |
236 | |
237 | struct SSILGatherPushConstant { |
238 | int32_t screen_size[2]; |
239 | int pass; |
240 | int quality; |
241 | |
242 | float half_screen_pixel_size[2]; |
243 | float half_screen_pixel_size_x025[2]; |
244 | |
245 | float NDC_to_view_mul[2]; |
246 | float NDC_to_view_add[2]; |
247 | |
248 | float pad2[2]; |
249 | float z_near; |
250 | float z_far; |
251 | |
252 | float radius; |
253 | float intensity; |
254 | int size_multiplier; |
255 | int pad; |
256 | |
257 | float fade_out_mul; |
258 | float fade_out_add; |
259 | float normal_rejection_amount; |
260 | float inv_radius_near_limit; |
261 | |
262 | uint32_t is_orthogonal; |
263 | float neg_inv_radius; |
264 | float load_counter_avg_div; |
265 | float adaptive_sample_limit; |
266 | |
267 | int32_t pass_coord_offset[2]; |
268 | float pass_uv_offset[2]; |
269 | }; |
270 | |
271 | struct SSILImportanceMapPushConstant { |
272 | float half_screen_pixel_size[2]; |
273 | float intensity; |
274 | float pad; |
275 | }; |
276 | |
277 | struct SSILBlurPushConstant { |
278 | float edge_sharpness; |
279 | float pad; |
280 | float half_screen_pixel_size[2]; |
281 | }; |
282 | |
283 | struct SSILInterleavePushConstant { |
284 | float inv_sharpness; |
285 | uint32_t size_modifier; |
286 | float pixel_size[2]; |
287 | }; |
288 | |
289 | struct SSILProjectionUniforms { |
290 | float inv_last_frame_projection_matrix[16]; |
291 | }; |
292 | |
293 | struct SSIL { |
294 | SSILGatherPushConstant gather_push_constant; |
295 | SsilShaderRD gather_shader; |
296 | RID gather_shader_version; |
297 | RID projection_uniform_buffer; |
298 | |
299 | SSILImportanceMapPushConstant importance_map_push_constant; |
300 | SsilImportanceMapShaderRD importance_map_shader; |
301 | RID importance_map_shader_version; |
302 | RID importance_map_load_counter; |
303 | RID counter_uniform_set; |
304 | |
305 | SSILBlurPushConstant blur_push_constant; |
306 | SsilBlurShaderRD blur_shader; |
307 | RID blur_shader_version; |
308 | |
309 | SSILInterleavePushConstant interleave_push_constant; |
310 | SsilInterleaveShaderRD interleave_shader; |
311 | RID interleave_shader_version; |
312 | |
313 | RID pipelines[SSIL_MAX]; |
314 | } ssil; |
315 | |
316 | void gather_ssil(RD::ComputeListID p_compute_list, const RID *p_ssil_slices, const RID *p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set); |
317 | |
318 | /* SSAO */ |
319 | |
320 | enum SSAOMode { |
321 | SSAO_GATHER, |
322 | SSAO_GATHER_BASE, |
323 | SSAO_GATHER_ADAPTIVE, |
324 | SSAO_GENERATE_IMPORTANCE_MAP, |
325 | SSAO_PROCESS_IMPORTANCE_MAPA, |
326 | SSAO_PROCESS_IMPORTANCE_MAPB, |
327 | SSAO_BLUR_PASS, |
328 | SSAO_BLUR_PASS_SMART, |
329 | SSAO_BLUR_PASS_WIDE, |
330 | SSAO_INTERLEAVE, |
331 | SSAO_INTERLEAVE_SMART, |
332 | SSAO_INTERLEAVE_HALF, |
333 | SSAO_MAX |
334 | }; |
335 | |
336 | struct SSAOGatherPushConstant { |
337 | int32_t screen_size[2]; |
338 | int pass; |
339 | int quality; |
340 | |
341 | float half_screen_pixel_size[2]; |
342 | int size_multiplier; |
343 | float detail_intensity; |
344 | |
345 | float NDC_to_view_mul[2]; |
346 | float NDC_to_view_add[2]; |
347 | |
348 | float pad[2]; |
349 | float half_screen_pixel_size_x025[2]; |
350 | |
351 | float radius; |
352 | float intensity; |
353 | float shadow_power; |
354 | float shadow_clamp; |
355 | |
356 | float fade_out_mul; |
357 | float fade_out_add; |
358 | float horizon_angle_threshold; |
359 | float inv_radius_near_limit; |
360 | |
361 | uint32_t is_orthogonal; |
362 | float neg_inv_radius; |
363 | float load_counter_avg_div; |
364 | float adaptive_sample_limit; |
365 | |
366 | int32_t pass_coord_offset[2]; |
367 | float pass_uv_offset[2]; |
368 | }; |
369 | |
370 | struct SSAOImportanceMapPushConstant { |
371 | float half_screen_pixel_size[2]; |
372 | float intensity; |
373 | float power; |
374 | }; |
375 | |
376 | struct SSAOBlurPushConstant { |
377 | float edge_sharpness; |
378 | float pad; |
379 | float half_screen_pixel_size[2]; |
380 | }; |
381 | |
382 | struct SSAOInterleavePushConstant { |
383 | float inv_sharpness; |
384 | uint32_t size_modifier; |
385 | float pixel_size[2]; |
386 | }; |
387 | |
388 | struct SSAO { |
389 | SSAOGatherPushConstant gather_push_constant; |
390 | SsaoShaderRD gather_shader; |
391 | RID gather_shader_version; |
392 | |
393 | SSAOImportanceMapPushConstant importance_map_push_constant; |
394 | SsaoImportanceMapShaderRD importance_map_shader; |
395 | RID importance_map_shader_version; |
396 | RID importance_map_load_counter; |
397 | RID counter_uniform_set; |
398 | |
399 | SSAOBlurPushConstant blur_push_constant; |
400 | SsaoBlurShaderRD blur_shader; |
401 | RID blur_shader_version; |
402 | |
403 | SSAOInterleavePushConstant interleave_push_constant; |
404 | SsaoInterleaveShaderRD interleave_shader; |
405 | RID interleave_shader_version; |
406 | |
407 | RID pipelines[SSAO_MAX]; |
408 | } ssao; |
409 | |
410 | void gather_ssao(RD::ComputeListID p_compute_list, const RID *p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set); |
411 | |
412 | /* Screen Space Reflection */ |
413 | |
414 | enum SSRShaderSpecializations { |
415 | SSR_MULTIVIEW = 1 << 0, |
416 | SSR_VARIATIONS = 2, |
417 | }; |
418 | |
419 | struct ScreenSpaceReflectionSceneData { |
420 | float projection[2][16]; |
421 | float inv_projection[2][16]; |
422 | float eye_offset[2][4]; |
423 | }; |
424 | |
425 | // SSR Scale |
426 | |
427 | struct ScreenSpaceReflectionScalePushConstant { |
428 | int32_t screen_size[2]; |
429 | float camera_z_near; |
430 | float camera_z_far; |
431 | |
432 | uint32_t orthogonal; |
433 | uint32_t filter; |
434 | uint32_t view_index; |
435 | uint32_t pad1; |
436 | }; |
437 | |
438 | struct ScreenSpaceReflectionScale { |
439 | ScreenSpaceReflectionScaleShaderRD shader; |
440 | RID shader_version; |
441 | RID pipelines[SSR_VARIATIONS]; |
442 | } ssr_scale; |
443 | |
444 | // SSR main |
445 | |
446 | enum ScreenSpaceReflectionMode { |
447 | SCREEN_SPACE_REFLECTION_NORMAL, |
448 | SCREEN_SPACE_REFLECTION_ROUGH, |
449 | SCREEN_SPACE_REFLECTION_MAX, |
450 | }; |
451 | |
452 | struct ScreenSpaceReflectionPushConstant { |
453 | float proj_info[4]; // 16 - 16 |
454 | |
455 | int32_t screen_size[2]; // 8 - 24 |
456 | float camera_z_near; // 4 - 28 |
457 | float camera_z_far; // 4 - 32 |
458 | |
459 | int32_t num_steps; // 4 - 36 |
460 | float depth_tolerance; // 4 - 40 |
461 | float distance_fade; // 4 - 44 |
462 | float curve_fade_in; // 4 - 48 |
463 | |
464 | uint32_t orthogonal; // 4 - 52 |
465 | float filter_mipmap_levels; // 4 - 56 |
466 | uint32_t use_half_res; // 4 - 60 |
467 | uint32_t view_index; // 4 - 64 |
468 | |
469 | // float projection[16]; // this is in our ScreenSpaceReflectionSceneData now |
470 | }; |
471 | |
472 | struct ScreenSpaceReflection { |
473 | ScreenSpaceReflectionShaderRD shader; |
474 | RID shader_version; |
475 | RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_MAX]; |
476 | |
477 | RID ubo; |
478 | } ssr; |
479 | |
480 | // SSR Filter |
481 | |
482 | struct ScreenSpaceReflectionFilterPushConstant { |
483 | float proj_info[4]; // 16 - 16 |
484 | |
485 | uint32_t orthogonal; // 4 - 20 |
486 | float edge_tolerance; // 4 - 24 |
487 | int32_t increment; // 4 - 28 |
488 | uint32_t view_index; // 4 - 32 |
489 | |
490 | int32_t screen_size[2]; // 8 - 40 |
491 | uint32_t vertical; // 4 - 44 |
492 | uint32_t steps; // 4 - 48 |
493 | }; |
494 | |
495 | enum SSRReflectionMode { |
496 | SCREEN_SPACE_REFLECTION_FILTER_HORIZONTAL, |
497 | SCREEN_SPACE_REFLECTION_FILTER_VERTICAL, |
498 | SCREEN_SPACE_REFLECTION_FILTER_MAX, |
499 | }; |
500 | |
501 | struct ScreenSpaceReflectionFilter { |
502 | ScreenSpaceReflectionFilterShaderRD shader; |
503 | RID shader_version; |
504 | RID pipelines[SSR_VARIATIONS][SCREEN_SPACE_REFLECTION_FILTER_MAX]; |
505 | } ssr_filter; |
506 | |
507 | /* Subsurface scattering */ |
508 | |
509 | struct SubSurfaceScatteringPushConstant { |
510 | int32_t screen_size[2]; |
511 | float camera_z_far; |
512 | float camera_z_near; |
513 | |
514 | uint32_t vertical; |
515 | uint32_t orthogonal; |
516 | float unit_size; |
517 | float scale; |
518 | |
519 | float depth_scale; |
520 | uint32_t pad[3]; |
521 | }; |
522 | |
523 | struct SubSurfaceScattering { |
524 | SubSurfaceScatteringPushConstant push_constant; |
525 | SubsurfaceScatteringShaderRD shader; |
526 | RID shader_version; |
527 | RID pipelines[3]; //3 quality levels |
528 | } sss; |
529 | }; |
530 | |
531 | } // namespace RendererRD |
532 | |
533 | #endif // SS_EFFECTS_RD_H |
534 | |