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
71class RenderSceneBuffersRD;
72
73namespace RendererRD {
74
75class SSEffects {
76private:
77 static SSEffects *singleton;
78
79public:
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
155private:
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