Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/renderer_rd/effects/copy_effects.cpp
20911 views
1
/**************************************************************************/
2
/* copy_effects.cpp */
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
#include "copy_effects.h"
32
#include "core/config/project_settings.h"
33
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
34
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
35
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
36
#include "thirdparty/misc/cubemap_coeffs.h"
37
38
using namespace RendererRD;
39
40
CopyEffects *CopyEffects::singleton = nullptr;
41
42
CopyEffects *CopyEffects::get_singleton() {
43
return singleton;
44
}
45
46
CopyEffects::CopyEffects(BitField<RasterEffects> p_raster_effects) {
47
singleton = this;
48
raster_effects = p_raster_effects;
49
50
if (raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR)) {
51
// init blur shader (on compute use copy shader)
52
53
Vector<String> blur_modes;
54
blur_modes.push_back("\n#define MODE_MIPMAP\n"); // BLUR_MIPMAP
55
blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR
56
blur_modes.push_back("\n#define MODE_GLOW_GATHER\n"); // BLUR_MODE_GAUSSIAN_GLOW_GATHER
57
blur_modes.push_back("\n#define MODE_GLOW_DOWNSAMPLE\n"); // BLUR_MODE_GAUSSIAN_GLOW_DOWNSAMPLE
58
blur_modes.push_back("\n#define MODE_GLOW_UPSAMPLE\n"); // BLUR_MODE_GAUSSIAN_GLOW_UPSAMPLE
59
blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY
60
blur_modes.push_back("\n#define MODE_SET_COLOR\n"); // BLUR_MODE_SET_COLOR
61
62
blur_raster.shader.initialize(blur_modes);
63
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
64
blur_raster.shader_version = blur_raster.shader.version_create();
65
66
for (int i = 0; i < BLUR_MODE_MAX; i++) {
67
blur_raster.pipelines[i].setup(blur_raster.shader.version_get_shader(blur_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
68
}
69
70
RD::SamplerState sampler_state;
71
sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
72
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
73
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER;
74
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER;
75
sampler_state.border_color = RD::SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
76
77
blur_raster.glow_sampler = RD::get_singleton()->sampler_create(sampler_state);
78
79
} else {
80
// not used in clustered
81
for (int i = 0; i < BLUR_MODE_MAX; i++) {
82
blur_raster.pipelines[i].clear();
83
}
84
}
85
86
{
87
Vector<String> copy_modes;
88
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
89
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n");
90
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n");
91
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
92
copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
93
copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n");
94
copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");
95
copy_modes.push_back("\n#define MODE_SET_COLOR\n");
96
copy_modes.push_back("\n#define MODE_SET_COLOR\n#define DST_IMAGE_8BIT\n");
97
copy_modes.push_back("\n#define MODE_MIPMAP\n");
98
copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");
99
copy_modes.push_back("\n#define MODE_OCTMAP_TO_PANORAMA\n");
100
copy_modes.push_back("\n#define MODE_OCTMAP_ARRAY_TO_PANORAMA\n");
101
102
copy.shader.initialize(copy_modes);
103
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
104
105
copy.shader_version = copy.shader.version_create();
106
107
for (int i = 0; i < COPY_MODE_MAX; i++) {
108
if (copy.shader.is_variant_enabled(i)) {
109
copy.pipelines[i].create_compute_pipeline(copy.shader.version_get_shader(copy.shader_version, i));
110
}
111
}
112
}
113
114
{
115
Vector<String> copy_modes;
116
copy_modes.push_back("\n"); // COPY_TO_FB_COPY
117
copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); // COPY_TO_FB_COPY_PANORAMA_TO_DP
118
copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2
119
copy_modes.push_back("\n#define MODE_SET_COLOR\n"); // COPY_TO_FB_SET_COLOR
120
copy_modes.push_back("\n#define USE_MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW
121
copy_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH
122
123
copy_to_fb.shader.initialize(copy_modes);
124
125
if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) {
126
copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false);
127
copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false);
128
}
129
130
copy_to_fb.shader_version = copy_to_fb.shader.version_create();
131
132
//use additive
133
134
for (int i = 0; i < COPY_TO_FB_MAX; i++) {
135
if (copy_to_fb.shader.is_variant_enabled(i)) {
136
copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
137
} else {
138
copy_to_fb.pipelines[i].clear();
139
}
140
}
141
}
142
143
{
144
// Initialize copier
145
Vector<String> copy_modes;
146
copy_modes.push_back("\n");
147
148
cube_to_dp.shader.initialize(copy_modes);
149
150
cube_to_dp.shader_version = cube_to_dp.shader.version_create();
151
RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
152
RD::PipelineDepthStencilState dss;
153
dss.enable_depth_test = true;
154
dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
155
dss.enable_depth_write = true;
156
cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
157
}
158
159
{
160
// Initialize cubemap to octmap copier.
161
cube_to_octmap.shader.initialize({ "" });
162
cube_to_octmap.shader_version = cube_to_octmap.shader.version_create();
163
RID shader = cube_to_octmap.shader.version_get_shader(cube_to_octmap.shader_version, 0);
164
cube_to_octmap.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled());
165
}
166
167
{
168
// Initialize octmap downsampler.
169
170
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
171
octmap_downsampler.raster_shader.initialize({ "" });
172
octmap_downsampler.shader_version = octmap_downsampler.raster_shader.version_create();
173
octmap_downsampler.raster_pipeline.setup(octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
174
} else {
175
Vector<String> downsampler_modes;
176
for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {
177
String mode;
178
if (i & DOWNSAMPLER_MODE_FLAG_RGB10_A2) {
179
mode += "\n#define OCTMAP_FORMAT rgb10_a2\n";
180
} else {
181
mode += "\n#define OCTMAP_FORMAT rgba16f\n";
182
}
183
downsampler_modes.push_back(mode);
184
}
185
186
octmap_downsampler.compute_shader.initialize(downsampler_modes);
187
octmap_downsampler.shader_version = octmap_downsampler.compute_shader.version_create();
188
for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {
189
octmap_downsampler.compute_pipelines[i].create_compute_pipeline(octmap_downsampler.compute_shader.version_get_shader(octmap_downsampler.shader_version, i));
190
}
191
}
192
}
193
194
{
195
// Initialize cubemap filter
196
filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality");
197
198
if (filter.use_high_quality) {
199
filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs));
200
RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]);
201
} else {
202
filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs));
203
RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]);
204
}
205
206
Vector<String> cubemap_filter_modes;
207
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
208
for (int i = 0; i < FILTER_MODE_RASTER_MAX; i++) {
209
String mode;
210
if (i & FILTER_MODE_FLAG_HIGH_QUALITY) {
211
mode += "\n#define USE_HIGH_QUALITY\n";
212
} else {
213
mode += "\n#define USE_LOW_QUALITY\n";
214
}
215
cubemap_filter_modes.push_back(mode);
216
}
217
218
filter.raster_shader.initialize(cubemap_filter_modes);
219
filter.shader_version = filter.raster_shader.version_create();
220
221
for (int i = 0; i < FILTER_MODE_RASTER_MAX; i++) {
222
filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
223
}
224
225
Vector<RD::Uniform> uniforms;
226
{
227
RD::Uniform u;
228
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
229
u.binding = 0;
230
u.append_id(filter.coefficient_buffer);
231
uniforms.push_back(u);
232
}
233
filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
234
} else {
235
for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {
236
String mode;
237
if (i & FILTER_MODE_FLAG_HIGH_QUALITY) {
238
mode += "\n#define USE_HIGH_QUALITY\n";
239
} else {
240
mode += "\n#define USE_LOW_QUALITY\n";
241
}
242
if (i & FILTER_MODE_FLAG_ARRAY) {
243
mode += "\n#define USE_TEXTURE_ARRAY\n";
244
}
245
if (i & FILTER_MODE_FLAG_RGB10_A2) {
246
mode += "\n#define OCTMAP_FORMAT rgb10_a2\n";
247
} else {
248
mode += "\n#define OCTMAP_FORMAT rgba16f\n";
249
}
250
cubemap_filter_modes.push_back(mode);
251
}
252
253
filter.compute_shader.initialize(cubemap_filter_modes);
254
filter.shader_version = filter.compute_shader.version_create();
255
256
for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {
257
filter.compute_pipelines[i].create_compute_pipeline(filter.compute_shader.version_get_shader(filter.shader_version, i));
258
}
259
260
Vector<RD::Uniform> uniforms;
261
{
262
RD::Uniform u;
263
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
264
u.binding = 0;
265
u.append_id(filter.coefficient_buffer);
266
uniforms.push_back(u);
267
}
268
filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
269
}
270
}
271
272
{
273
// Initialize roughness
274
Vector<String> cubemap_roughness_modes;
275
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
276
cubemap_roughness_modes.push_back("");
277
278
roughness.raster_shader.initialize(cubemap_roughness_modes);
279
280
roughness.shader_version = roughness.raster_shader.version_create();
281
282
roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
283
284
} else {
285
cubemap_roughness_modes.push_back("\n#define OCTMAP_FORMAT rgba16f\n");
286
cubemap_roughness_modes.push_back("\n#define OCTMAP_FORMAT rgb10_a2\n");
287
288
roughness.compute_shader.initialize(cubemap_roughness_modes);
289
290
roughness.shader_version = roughness.compute_shader.version_create();
291
292
for (int i = 0; i < ROUGHNESS_MODE_MAX; i++) {
293
roughness.compute_pipelines[i].create_compute_pipeline(roughness.compute_shader.version_get_shader(roughness.shader_version, i));
294
}
295
}
296
}
297
298
{
299
Vector<String> specular_modes;
300
specular_modes.push_back("\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD
301
specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR
302
specular_modes.push_back("\n"); // SPECULAR_MERGE_ADDITIVE_ADD
303
specular_modes.push_back("\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR
304
305
specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD_MULTIVIEW
306
specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR_MULTIVIEW
307
specular_modes.push_back("\n#define USE_MULTIVIEW\n"); // SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW
308
specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW
309
310
specular_merge.shader.initialize(specular_modes);
311
312
if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) {
313
specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADD_MULTIVIEW, false);
314
specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_SSR_MULTIVIEW, false);
315
specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW, false);
316
specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW, false);
317
}
318
319
specular_merge.shader_version = specular_merge.shader.version_create();
320
321
//use additive
322
323
RD::PipelineColorBlendState::Attachment ba;
324
ba.enable_blend = true;
325
ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE;
326
ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
327
ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
328
ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
329
ba.color_blend_op = RD::BLEND_OP_ADD;
330
ba.alpha_blend_op = RD::BLEND_OP_ADD;
331
332
RD::PipelineColorBlendState blend_additive;
333
blend_additive.attachments.push_back(ba);
334
335
for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {
336
if (specular_merge.shader.is_variant_enabled(i)) {
337
RD::PipelineColorBlendState blend_state;
338
if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR || i == SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW || i == SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW) {
339
blend_state = blend_additive;
340
} else {
341
blend_state = RD::PipelineColorBlendState::create_disabled();
342
}
343
specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
344
}
345
}
346
}
347
}
348
349
CopyEffects::~CopyEffects() {
350
for (int i = 0; i < COPY_MODE_MAX; i++) {
351
copy.pipelines[i].free();
352
}
353
354
if (raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR)) {
355
blur_raster.shader.version_free(blur_raster.shader_version);
356
RD::get_singleton()->free_rid(blur_raster.glow_sampler);
357
}
358
359
if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {
360
octmap_downsampler.raster_shader.version_free(octmap_downsampler.shader_version);
361
filter.raster_shader.version_free(filter.shader_version);
362
roughness.raster_shader.version_free(roughness.shader_version);
363
} else {
364
// PipelineDeferredRD always needs to be freed before its corresponding shader since the pipeline may not have finished compiling before the shader is freed. This
365
// ensures that we wait on the pipeline compilation before we free it.
366
for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {
367
octmap_downsampler.compute_pipelines[i].free();
368
}
369
octmap_downsampler.compute_shader.version_free(octmap_downsampler.shader_version);
370
371
for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {
372
filter.compute_pipelines[i].free();
373
}
374
filter.compute_shader.version_free(filter.shader_version);
375
376
for (int i = 0; i < ROUGHNESS_MODE_MAX; i++) {
377
roughness.compute_pipelines[i].free();
378
}
379
roughness.compute_shader.version_free(roughness.shader_version);
380
}
381
382
copy.shader.version_free(copy.shader_version);
383
specular_merge.shader.version_free(specular_merge.shader_version);
384
385
RD::get_singleton()->free_rid(filter.coefficient_buffer);
386
387
if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
388
RD::get_singleton()->free_rid(filter.image_uniform_set);
389
}
390
391
if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) {
392
RD::get_singleton()->free_rid(filter.uniform_set);
393
}
394
395
copy_to_fb.shader.version_free(copy_to_fb.shader_version);
396
cube_to_dp.shader.version_free(cube_to_dp.shader_version);
397
cube_to_octmap.shader.version_free(cube_to_octmap.shader_version);
398
399
singleton = nullptr;
400
}
401
402
void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one, bool p_sanitize_inf_nan) {
403
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
404
ERR_FAIL_NULL(uniform_set_cache);
405
MaterialStorage *material_storage = MaterialStorage::get_singleton();
406
ERR_FAIL_NULL(material_storage);
407
408
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
409
if (p_flip_y) {
410
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
411
}
412
413
if (p_force_luminance) {
414
copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE;
415
}
416
417
if (p_all_source) {
418
copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE;
419
}
420
421
if (p_alpha_to_one) {
422
copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE;
423
}
424
425
if (p_sanitize_inf_nan) {
426
copy.push_constant.flags |= COPY_FLAG_SANITIZE_INF_NAN;
427
}
428
429
copy.push_constant.section[0] = p_rect.position.x;
430
copy.push_constant.section[1] = p_rect.position.y;
431
copy.push_constant.section[2] = p_rect.size.width;
432
copy.push_constant.section[3] = p_rect.size.height;
433
copy.push_constant.target[0] = p_rect.position.x;
434
copy.push_constant.target[1] = p_rect.position.y;
435
436
// setup our uniforms
437
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
438
439
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
440
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);
441
442
CopyMode mode = p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY;
443
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
444
ERR_FAIL_COND(shader.is_null());
445
446
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
447
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
448
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
449
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);
450
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
451
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
452
RD::get_singleton()->compute_list_end();
453
}
454
455
void CopyEffects::copy_octmap_to_panorama(RID p_source_octmap, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array, const Size2 &p_source_octmap_border_size) {
456
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
457
ERR_FAIL_NULL(uniform_set_cache);
458
MaterialStorage *material_storage = MaterialStorage::get_singleton();
459
ERR_FAIL_NULL(material_storage);
460
461
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
462
463
copy.push_constant.section[0] = 0;
464
copy.push_constant.section[1] = 0;
465
copy.push_constant.section[2] = p_panorama_size.width;
466
copy.push_constant.section[3] = p_panorama_size.height;
467
copy.push_constant.target[0] = 0;
468
copy.push_constant.target[1] = 0;
469
copy.push_constant.camera_z_far = p_lod;
470
copy.push_constant.octmap_border_size[0] = p_source_octmap_border_size.x;
471
copy.push_constant.octmap_border_size[1] = p_source_octmap_border_size.y;
472
473
// TODO, if this is needed at the copy stage, then we need to pass in the multiplier.
474
copy.push_constant.luminance_multiplier = raster_effects.has_flag(RASTER_EFFECT_COPY) ? 2.0 : 1.0;
475
476
// setup our uniforms
477
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
478
479
RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));
480
RD::Uniform u_dest_panorama(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_panorama);
481
482
CopyMode mode = p_is_array ? COPY_MODE_OCTMAP_ARRAY_TO_PANORAMA : COPY_MODE_OCTMAP_TO_PANORAMA;
483
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
484
ERR_FAIL_COND(shader.is_null());
485
486
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
487
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
488
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);
489
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_panorama), 3);
490
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
491
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1);
492
RD::get_singleton()->compute_list_end();
493
}
494
495
void CopyEffects::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
496
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
497
ERR_FAIL_NULL(uniform_set_cache);
498
MaterialStorage *material_storage = MaterialStorage::get_singleton();
499
ERR_FAIL_NULL(material_storage);
500
501
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
502
if (p_flip_y) {
503
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
504
}
505
506
copy.push_constant.section[0] = 0;
507
copy.push_constant.section[1] = 0;
508
copy.push_constant.section[2] = p_rect.size.width;
509
copy.push_constant.section[3] = p_rect.size.height;
510
copy.push_constant.target[0] = p_rect.position.x;
511
copy.push_constant.target[1] = p_rect.position.y;
512
513
// setup our uniforms
514
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
515
516
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
517
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);
518
519
CopyMode mode = COPY_MODE_SIMPLY_COPY_DEPTH;
520
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
521
ERR_FAIL_COND(shader.is_null());
522
523
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
524
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
525
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
526
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);
527
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
528
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
529
RD::get_singleton()->compute_list_end();
530
}
531
532
void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
533
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
534
ERR_FAIL_NULL(uniform_set_cache);
535
MaterialStorage *material_storage = MaterialStorage::get_singleton();
536
ERR_FAIL_NULL(material_storage);
537
538
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
539
if (p_flip_y) {
540
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
541
}
542
543
copy.push_constant.section[0] = 0;
544
copy.push_constant.section[1] = 0;
545
copy.push_constant.section[2] = p_rect.size.width;
546
copy.push_constant.section[3] = p_rect.size.height;
547
copy.push_constant.target[0] = p_rect.position.x;
548
copy.push_constant.target[1] = p_rect.position.y;
549
copy.push_constant.camera_z_far = p_z_far;
550
copy.push_constant.camera_z_near = p_z_near;
551
552
// setup our uniforms
553
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
554
555
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
556
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);
557
558
CopyMode mode = COPY_MODE_LINEARIZE_DEPTH;
559
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
560
ERR_FAIL_COND(shader.is_null());
561
562
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
563
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
564
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
565
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);
566
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
567
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);
568
RD::get_singleton()->compute_list_end();
569
}
570
571
void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) {
572
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
573
ERR_FAIL_NULL(uniform_set_cache);
574
MaterialStorage *material_storage = MaterialStorage::get_singleton();
575
ERR_FAIL_NULL(material_storage);
576
577
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
578
579
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION;
580
copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;
581
copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;
582
copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;
583
copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;
584
585
if (p_flip_y) {
586
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
587
}
588
589
copy_to_fb.push_constant.luminance_multiplier = 1.0;
590
591
// setup our uniforms
592
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
593
594
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
595
596
CopyToFBMode mode = p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY;
597
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
598
ERR_FAIL_COND(shader.is_null());
599
600
RD::DrawListID draw_list = p_draw_list;
601
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
602
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
603
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
604
RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
605
RD::get_singleton()->draw_list_draw(draw_list, true);
606
}
607
608
void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal, const Rect2 &p_src_rect, float p_linear_luminance_multiplier) {
609
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
610
ERR_FAIL_NULL(uniform_set_cache);
611
MaterialStorage *material_storage = MaterialStorage::get_singleton();
612
ERR_FAIL_NULL(material_storage);
613
614
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
615
copy_to_fb.push_constant.luminance_multiplier = 1.0;
616
617
if (p_flip_y) {
618
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;
619
}
620
if (p_force_luminance) {
621
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE;
622
}
623
if (p_alpha_to_zero) {
624
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO;
625
}
626
if (p_srgb) {
627
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB;
628
}
629
if (p_alpha_to_one) {
630
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE;
631
}
632
if (p_linear) {
633
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;
634
copy_to_fb.push_constant.luminance_multiplier = p_linear_luminance_multiplier;
635
}
636
637
if (p_normal) {
638
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_NORMAL;
639
}
640
641
if (p_src_rect != Rect2()) {
642
copy_to_fb.push_constant.section[0] = p_src_rect.position.x;
643
copy_to_fb.push_constant.section[1] = p_src_rect.position.y;
644
copy_to_fb.push_constant.section[2] = p_src_rect.size.x;
645
copy_to_fb.push_constant.section[3] = p_src_rect.size.y;
646
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SRC_SECTION;
647
}
648
649
// setup our uniforms
650
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
651
652
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
653
654
CopyToFBMode mode;
655
if (p_multiview) {
656
mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW;
657
} else {
658
mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY;
659
}
660
661
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
662
ERR_FAIL_COND(shader.is_null());
663
664
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_rect);
665
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
666
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
667
if (p_secondary.is_valid()) {
668
// TODO may need to do this differently when reading from depth buffer for multiview
669
RD::Uniform u_secondary(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_secondary }));
670
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_secondary), 1);
671
}
672
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
673
RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
674
RD::get_singleton()->draw_list_draw(draw_list, true);
675
RD::get_singleton()->draw_list_end();
676
}
677
678
void CopyEffects::copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear, float p_linear_luminance_multiplier) {
679
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
680
ERR_FAIL_NULL(uniform_set_cache);
681
MaterialStorage *material_storage = MaterialStorage::get_singleton();
682
ERR_FAIL_NULL(material_storage);
683
684
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
685
copy_to_fb.push_constant.luminance_multiplier = 1.0;
686
687
if (p_linear) {
688
copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;
689
copy_to_fb.push_constant.luminance_multiplier = p_linear_luminance_multiplier;
690
}
691
692
// setup our uniforms
693
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
694
695
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
696
697
// Multiview not supported here!
698
CopyToFBMode mode = COPY_TO_FB_COPY;
699
700
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
701
ERR_FAIL_COND(shader.is_null());
702
703
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_fb_format));
704
RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
705
RD::get_singleton()->draw_list_bind_index_array(p_draw_list, material_storage->get_quad_index_array());
706
RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
707
RD::get_singleton()->draw_list_draw(p_draw_list, true);
708
}
709
710
void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) {
711
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of the copy.");
712
713
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
714
ERR_FAIL_NULL(uniform_set_cache);
715
MaterialStorage *material_storage = MaterialStorage::get_singleton();
716
ERR_FAIL_NULL(material_storage);
717
718
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
719
720
// setup our uniforms
721
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
722
723
RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_texture }));
724
725
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, BLUR_MODE_COPY);
726
ERR_FAIL_COND(shader.is_null());
727
728
// Just copy it back (we use our blur raster shader here)..
729
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
730
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
731
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);
732
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
733
734
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
735
RD::get_singleton()->draw_list_end();
736
}
737
738
void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst) {
739
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the compute version of the gaussian blur.");
740
741
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
742
ERR_FAIL_NULL(uniform_set_cache);
743
MaterialStorage *material_storage = MaterialStorage::get_singleton();
744
ERR_FAIL_NULL(material_storage);
745
746
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
747
748
copy.push_constant.section[0] = p_region.position.x;
749
copy.push_constant.section[1] = p_region.position.y;
750
copy.push_constant.target[0] = p_region.position.x;
751
copy.push_constant.target[1] = p_region.position.y;
752
copy.push_constant.section[2] = p_size.width;
753
copy.push_constant.section[3] = p_size.height;
754
755
// setup our uniforms
756
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
757
758
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
759
RD::Uniform u_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_texture);
760
761
CopyMode mode = p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY;
762
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
763
ERR_FAIL_COND(shader.is_null());
764
765
RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
766
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
767
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
768
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_texture), 3);
769
770
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
771
772
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
773
774
RD::get_singleton()->compute_list_end();
775
}
776
777
void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size) {
778
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian blur.");
779
780
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
781
ERR_FAIL_NULL(uniform_set_cache);
782
MaterialStorage *material_storage = MaterialStorage::get_singleton();
783
ERR_FAIL_NULL(material_storage);
784
785
RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
786
787
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
788
789
BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_BLUR;
790
791
blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_size.x);
792
blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_size.y);
793
794
// setup our uniforms
795
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
796
797
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
798
799
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);
800
ERR_FAIL_COND(shader.is_null());
801
802
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
803
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
804
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
805
806
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
807
808
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
809
RD::get_singleton()->draw_list_end();
810
}
811
812
void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {
813
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the compute version of the gaussian glow.");
814
815
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
816
ERR_FAIL_NULL(uniform_set_cache);
817
MaterialStorage *material_storage = MaterialStorage::get_singleton();
818
ERR_FAIL_NULL(material_storage);
819
820
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
821
822
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
823
uint32_t base_flags = 0;
824
825
copy.push_constant.section[2] = p_size.x;
826
copy.push_constant.section[3] = p_size.y;
827
828
copy.push_constant.glow_strength = p_strength;
829
copy.push_constant.glow_bloom = p_bloom;
830
copy.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold;
831
copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
832
copy.push_constant.glow_exposure = p_exposure;
833
copy.push_constant.glow_white = 0; //actually unused
834
copy.push_constant.glow_luminance_cap = p_luminance_cap;
835
836
copy.push_constant.glow_auto_exposure_scale = p_auto_exposure_scale; //unused also
837
838
// setup our uniforms
839
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
840
841
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
842
RD::Uniform u_back_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_back_texture);
843
844
RID shader = copy.shader.version_get_shader(copy.shader_version, copy_mode);
845
ERR_FAIL_COND(shader.is_null());
846
847
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
848
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode].get_rid());
849
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
850
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_back_texture), 3);
851
if (p_auto_exposure.is_valid() && p_first_pass) {
852
RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_auto_exposure }));
853
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1);
854
}
855
856
copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);
857
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
858
859
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);
860
RD::get_singleton()->compute_list_end();
861
}
862
863
void CopyEffects::gaussian_glow_downsample_raster(RID p_source_rd_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale) {
864
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian glow.");
865
866
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
867
ERR_FAIL_NULL(uniform_set_cache);
868
MaterialStorage *material_storage = MaterialStorage::get_singleton();
869
ERR_FAIL_NULL(material_storage);
870
871
RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
872
873
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
874
875
BlurRasterMode blur_mode = p_first_pass ? BLUR_MODE_GAUSSIAN_GLOW_GATHER : BLUR_MODE_GAUSSIAN_GLOW_DOWNSAMPLE;
876
877
blur_raster.push_constant.source_pixel_size[0] = 1.0 / float(p_size.x);
878
blur_raster.push_constant.source_pixel_size[1] = 1.0 / float(p_size.y);
879
880
blur_raster.push_constant.glow_strength = p_strength;
881
blur_raster.push_constant.glow_bloom = p_bloom;
882
blur_raster.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold;
883
blur_raster.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
884
blur_raster.push_constant.glow_exposure = p_exposure;
885
blur_raster.push_constant.glow_white = 0; //actually unused
886
blur_raster.push_constant.glow_luminance_cap = p_luminance_cap;
887
888
blur_raster.push_constant.luminance_multiplier = p_luminance_multiplier;
889
890
// setup our uniforms
891
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ blur_raster.glow_sampler, p_source_rd_texture }));
892
893
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);
894
ERR_FAIL_COND(shader.is_null());
895
896
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
897
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
898
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
899
900
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
901
902
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
903
RD::get_singleton()->draw_list_end();
904
}
905
906
void CopyEffects::gaussian_glow_upsample_raster(RID p_source_rd_texture, RID p_dest_texture, RID p_blend_texture, float p_luminance_multiplier, const Size2i &p_source_size, const Size2i &p_dest_size, float p_level, float p_base_strength, bool p_use_debanding) {
907
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian glow.");
908
909
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
910
ERR_FAIL_NULL(uniform_set_cache);
911
MaterialStorage *material_storage = MaterialStorage::get_singleton();
912
ERR_FAIL_NULL(material_storage);
913
914
RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
915
916
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
917
918
BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_GLOW_UPSAMPLE;
919
920
blur_raster.push_constant.source_pixel_size[0] = 1.0 / float(p_source_size.x);
921
blur_raster.push_constant.source_pixel_size[1] = 1.0 / float(p_source_size.y);
922
blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_dest_size.x);
923
blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_dest_size.y);
924
blur_raster.push_constant.luminance_multiplier = p_luminance_multiplier;
925
blur_raster.push_constant.level = p_level * 0.5;
926
blur_raster.push_constant.glow_strength = p_base_strength;
927
928
uint32_t spec_constant = p_use_debanding ? 1 : 0;
929
spec_constant |= p_level > 0.01 ? 2 : 0;
930
931
// setup our uniforms
932
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
933
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
934
RD::Uniform u_blend_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_blend_texture }));
935
936
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);
937
ERR_FAIL_COND(shader.is_null());
938
939
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
940
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer), false, 0, spec_constant));
941
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
942
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_blend_rd_texture), 1);
943
944
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
945
946
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
947
RD::get_singleton()->draw_list_end();
948
}
949
950
void CopyEffects::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
951
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the compute version of the make_mipmap shader.");
952
953
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
954
ERR_FAIL_NULL(uniform_set_cache);
955
MaterialStorage *material_storage = MaterialStorage::get_singleton();
956
ERR_FAIL_NULL(material_storage);
957
958
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
959
960
copy.push_constant.section[0] = 0;
961
copy.push_constant.section[1] = 0;
962
copy.push_constant.section[2] = p_size.width;
963
copy.push_constant.section[3] = p_size.height;
964
965
// setup our uniforms
966
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
967
968
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
969
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);
970
971
CopyMode mode = COPY_MODE_MIPMAP;
972
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
973
ERR_FAIL_COND(shader.is_null());
974
975
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
976
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
977
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
978
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);
979
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
980
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);
981
RD::get_singleton()->compute_list_end();
982
}
983
984
void CopyEffects::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
985
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of mipmap.");
986
987
RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
988
989
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
990
ERR_FAIL_NULL(uniform_set_cache);
991
MaterialStorage *material_storage = MaterialStorage::get_singleton();
992
ERR_FAIL_NULL(material_storage);
993
994
memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));
995
996
BlurRasterMode mode = BLUR_MIPMAP;
997
998
blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_size.x);
999
blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_size.y);
1000
1001
// setup our uniforms
1002
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1003
1004
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
1005
1006
RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, mode);
1007
ERR_FAIL_COND(shader.is_null());
1008
1009
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);
1010
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
1011
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
1012
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));
1013
1014
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
1015
RD::get_singleton()->draw_list_end();
1016
}
1017
1018
void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) {
1019
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the compute version of the set_color shader.");
1020
1021
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1022
ERR_FAIL_NULL(uniform_set_cache);
1023
1024
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
1025
1026
copy.push_constant.section[0] = 0;
1027
copy.push_constant.section[1] = 0;
1028
copy.push_constant.section[2] = p_region.size.width;
1029
copy.push_constant.section[3] = p_region.size.height;
1030
copy.push_constant.target[0] = p_region.position.x;
1031
copy.push_constant.target[1] = p_region.position.y;
1032
copy.push_constant.set_color[0] = p_color.r;
1033
copy.push_constant.set_color[1] = p_color.g;
1034
copy.push_constant.set_color[2] = p_color.b;
1035
copy.push_constant.set_color[3] = p_color.a;
1036
1037
// setup our uniforms
1038
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);
1039
1040
CopyMode mode = p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR;
1041
RID shader = copy.shader.version_get_shader(copy.shader_version, mode);
1042
ERR_FAIL_COND(shader.is_null());
1043
1044
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
1045
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());
1046
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);
1047
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
1048
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
1049
RD::get_singleton()->compute_list_end();
1050
}
1051
1052
void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region) {
1053
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of the set_color shader.");
1054
1055
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1056
ERR_FAIL_NULL(uniform_set_cache);
1057
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1058
ERR_FAIL_NULL(material_storage);
1059
1060
memset(&copy_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));
1061
1062
copy_to_fb.push_constant.set_color[0] = p_color.r;
1063
copy_to_fb.push_constant.set_color[1] = p_color.g;
1064
copy_to_fb.push_constant.set_color[2] = p_color.b;
1065
copy_to_fb.push_constant.set_color[3] = p_color.a;
1066
1067
RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);
1068
1069
CopyToFBMode mode = COPY_TO_FB_SET_COLOR;
1070
1071
RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);
1072
ERR_FAIL_COND(shader.is_null());
1073
1074
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_region);
1075
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));
1076
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
1077
RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
1078
RD::get_singleton()->draw_list_draw(draw_list, true);
1079
RD::get_singleton()->draw_list_end();
1080
}
1081
1082
void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) {
1083
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1084
ERR_FAIL_NULL(uniform_set_cache);
1085
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1086
ERR_FAIL_NULL(material_storage);
1087
1088
Rect2i screen_rect;
1089
float atlas_width = p_dst_size.width / p_rect.size.width;
1090
float atlas_height = p_dst_size.height / p_rect.size.height;
1091
screen_rect.position.x = (int32_t)(Math::round(p_rect.position.x * atlas_width));
1092
screen_rect.position.y = (int32_t)(Math::round(p_rect.position.y * atlas_height));
1093
screen_rect.size.width = (int32_t)(Math::round(p_dst_size.width));
1094
screen_rect.size.height = (int32_t)(Math::round(p_dst_size.height));
1095
1096
CopyToDPPushConstant push_constant;
1097
push_constant.z_far = p_z_far;
1098
push_constant.z_near = p_z_near;
1099
push_constant.texel_size[0] = 1.0f / p_dst_size.width;
1100
push_constant.texel_size[1] = 1.0f / p_dst_size.height;
1101
push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign
1102
1103
// setup our uniforms
1104
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1105
1106
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
1107
1108
RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
1109
ERR_FAIL_COND(shader.is_null());
1110
1111
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, screen_rect);
1112
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
1113
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
1114
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
1115
1116
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
1117
RD::get_singleton()->draw_list_draw(draw_list, true);
1118
RD::get_singleton()->draw_list_end();
1119
}
1120
1121
void CopyEffects::copy_cubemap_to_octmap(RID p_source_rd_texture, RID p_dst_framebuffer, float p_border_size) {
1122
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1123
ERR_FAIL_NULL(uniform_set_cache);
1124
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1125
ERR_FAIL_NULL(material_storage);
1126
RID shader = cube_to_octmap.shader.version_get_shader(cube_to_octmap.shader_version, 0);
1127
ERR_FAIL_COND(shader.is_null());
1128
1129
cube_to_octmap.push_constant.border_size = 1.0f - p_border_size * 2.0f;
1130
1131
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1132
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
1133
1134
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer);
1135
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_octmap.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
1136
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
1137
RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
1138
RD::get_singleton()->draw_list_set_push_constant(draw_list, &cube_to_octmap.push_constant, sizeof(CopyToOctmapPushConstant));
1139
RD::get_singleton()->draw_list_draw(draw_list, true);
1140
RD::get_singleton()->draw_list_end();
1141
}
1142
1143
void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, float p_border_size) {
1144
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap downsample.");
1145
1146
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1147
ERR_FAIL_NULL(uniform_set_cache);
1148
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1149
ERR_FAIL_NULL(material_storage);
1150
1151
octmap_downsampler.push_constant.size = p_size.x;
1152
octmap_downsampler.push_constant.border_size = 1.0f - p_border_size * 2.0f;
1153
1154
// setup our uniforms
1155
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1156
1157
RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));
1158
RD::Uniform u_dest_octmap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_octmap }));
1159
1160
int mode = 0;
1161
1162
RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_octmap);
1163
switch (texture_format.format) {
1164
case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {
1165
mode |= DOWNSAMPLER_MODE_FLAG_RGB10_A2;
1166
} break;
1167
case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {
1168
// Absence of the flag indicates RGBA16F.
1169
} break;
1170
default: {
1171
ERR_FAIL_MSG("Unrecognized octmap format.");
1172
}
1173
}
1174
1175
RID shader = octmap_downsampler.compute_shader.version_get_shader(octmap_downsampler.shader_version, mode);
1176
ERR_FAIL_COND(shader.is_null());
1177
1178
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
1179
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, octmap_downsampler.compute_pipelines[mode].get_rid());
1180
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);
1181
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_octmap), 1);
1182
1183
int x_groups = Math::division_round_up(p_size.x, 8);
1184
int y_groups = Math::division_round_up(p_size.y, 8);
1185
1186
RD::get_singleton()->compute_list_set_push_constant(compute_list, &octmap_downsampler.push_constant, sizeof(OctmapDownsamplerPushConstant));
1187
1188
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
1189
1190
RD::get_singleton()->compute_list_end();
1191
}
1192
1193
void CopyEffects::octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, float p_border_size) {
1194
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap downsample.");
1195
1196
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1197
ERR_FAIL_NULL(uniform_set_cache);
1198
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1199
ERR_FAIL_NULL(material_storage);
1200
1201
octmap_downsampler.push_constant.size = p_size.x;
1202
octmap_downsampler.push_constant.border_size = 1.0f - p_border_size * 2.0f;
1203
1204
// setup our uniforms
1205
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1206
1207
RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));
1208
1209
RID shader = octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0);
1210
ERR_FAIL_COND(shader.is_null());
1211
1212
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);
1213
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, octmap_downsampler.raster_pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
1214
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0);
1215
1216
RD::get_singleton()->draw_list_set_push_constant(draw_list, &octmap_downsampler.push_constant, sizeof(OctmapDownsamplerPushConstant));
1217
1218
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
1219
RD::get_singleton()->draw_list_end();
1220
}
1221
1222
static constexpr int _compute_dispatch_size(bool p_use_array) {
1223
constexpr int SIZE = 320;
1224
constexpr int GROUP = 64;
1225
constexpr int LEVELS = 6; // One less than Sky::REAL_TIME_ROUGHNESS_LAYERS.
1226
int size = 0;
1227
if (p_use_array) {
1228
size = SIZE * SIZE * LEVELS;
1229
} else {
1230
int dim = SIZE;
1231
for (int i = 0; i < LEVELS && dim >= 2; i++) {
1232
size += dim * dim;
1233
dim >>= 1;
1234
}
1235
}
1236
1237
return (size + GROUP - 1) / GROUP;
1238
}
1239
1240
void CopyEffects::octmap_filter(RID p_source_octmap, const Vector<RID> &p_dest_octmap, bool p_use_array, float p_border_size) {
1241
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap filter.");
1242
ERR_FAIL_COND(p_dest_octmap.is_empty());
1243
1244
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1245
ERR_FAIL_NULL(uniform_set_cache);
1246
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1247
ERR_FAIL_NULL(material_storage);
1248
1249
OctmapFilterPushConstant push_constant;
1250
push_constant.border_size[0] = p_border_size;
1251
push_constant.border_size[1] = 1.0f - p_border_size * 2.0f;
1252
1253
Vector<RD::Uniform> uniforms;
1254
for (int i = 0; i < p_dest_octmap.size(); i++) {
1255
RD::Uniform u;
1256
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
1257
u.binding = i;
1258
u.append_id(p_dest_octmap[i]);
1259
uniforms.push_back(u);
1260
}
1261
if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
1262
RD::get_singleton()->free_rid(filter.image_uniform_set);
1263
}
1264
filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2);
1265
1266
// setup our uniforms
1267
RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1268
1269
RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_octmap }));
1270
1271
int mode = 0;
1272
if (p_use_array) {
1273
mode |= FILTER_MODE_FLAG_ARRAY;
1274
}
1275
if (filter.use_high_quality) {
1276
mode |= FILTER_MODE_FLAG_HIGH_QUALITY;
1277
}
1278
1279
RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_octmap[0]);
1280
switch (texture_format.format) {
1281
case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {
1282
mode |= FILTER_MODE_FLAG_RGB10_A2;
1283
} break;
1284
case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {
1285
// Absence of the flag indicates RGBA16F.
1286
} break;
1287
default: {
1288
ERR_FAIL_MSG("Unrecognized octmap format.");
1289
}
1290
}
1291
1292
RID shader = filter.compute_shader.version_get_shader(filter.shader_version, mode);
1293
ERR_FAIL_COND(shader.is_null());
1294
1295
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
1296
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[mode].get_rid());
1297
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);
1298
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1);
1299
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2);
1300
1301
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(OctmapFilterPushConstant));
1302
1303
RD::get_singleton()->compute_list_dispatch(compute_list, _compute_dispatch_size(p_use_array), 1, 1);
1304
1305
RD::get_singleton()->compute_list_end();
1306
}
1307
1308
void CopyEffects::octmap_filter_raster(RID p_source_octmap, RID p_dest_framebuffer, uint32_t p_mip_level, float p_border_size) {
1309
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap filter.");
1310
1311
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1312
ERR_FAIL_NULL(uniform_set_cache);
1313
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1314
ERR_FAIL_NULL(material_storage);
1315
1316
OctmapFilterRasterPushConstant push_constant;
1317
push_constant.border_size[0] = p_border_size;
1318
push_constant.border_size[1] = 1.0f - p_border_size * 2.0f;
1319
push_constant.mip_level = p_mip_level;
1320
1321
// setup our uniforms
1322
RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1323
1324
RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_octmap }));
1325
1326
int mode = 0;
1327
if (filter.use_high_quality) {
1328
mode |= FILTER_MODE_FLAG_HIGH_QUALITY;
1329
}
1330
1331
RID shader = filter.raster_shader.version_get_shader(filter.shader_version, mode);
1332
ERR_FAIL_COND(shader.is_null());
1333
1334
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);
1335
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
1336
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);
1337
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1);
1338
1339
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(OctmapFilterRasterPushConstant));
1340
1341
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
1342
RD::get_singleton()->draw_list_end();
1343
}
1344
1345
void CopyEffects::octmap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size) {
1346
ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap roughness.");
1347
1348
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1349
ERR_FAIL_NULL(uniform_set_cache);
1350
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1351
ERR_FAIL_NULL(material_storage);
1352
1353
memset(&roughness.push_constant, 0, sizeof(OctmapRoughnessPushConstant));
1354
1355
// Remap to perceptual-roughness^2 to create more detail in lower mips and match the mapping of octmap_filter.
1356
roughness.push_constant.roughness = p_roughness * p_roughness;
1357
roughness.push_constant.sample_count = MIN(p_sample_count, 64u);
1358
roughness.push_constant.source_size = p_source_size;
1359
roughness.push_constant.dest_size = p_dest_size;
1360
roughness.push_constant.use_direct_write = p_roughness == 0.0;
1361
roughness.push_constant.border_size[0] = p_border_size;
1362
roughness.push_constant.border_size[1] = 1.0f - p_border_size * 2.0;
1363
1364
// setup our uniforms
1365
RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1366
1367
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_rd_texture }));
1368
RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_texture }));
1369
1370
OctmapRoughnessMode mode;
1371
RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_texture);
1372
switch (texture_format.format) {
1373
case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {
1374
mode = ROUGHNESS_MODE_RGB10_A2;
1375
} break;
1376
case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {
1377
mode = ROUGHNESS_MODE_RGBA16F;
1378
} break;
1379
default: {
1380
ERR_FAIL_MSG("Unrecognized octmap format.");
1381
}
1382
}
1383
1384
RID shader = roughness.compute_shader.version_get_shader(roughness.shader_version, mode);
1385
ERR_FAIL_COND(shader.is_null());
1386
1387
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
1388
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipelines[mode].get_rid());
1389
1390
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
1391
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_texture), 1);
1392
1393
RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(OctmapRoughnessPushConstant));
1394
1395
int x_groups = (p_dest_size + 7) / 8;
1396
int y_groups = x_groups;
1397
1398
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
1399
1400
RD::get_singleton()->compute_list_end();
1401
}
1402
1403
void CopyEffects::octmap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size) {
1404
ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap roughness.");
1405
1406
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1407
ERR_FAIL_NULL(uniform_set_cache);
1408
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1409
ERR_FAIL_NULL(material_storage);
1410
1411
memset(&roughness.push_constant, 0, sizeof(OctmapRoughnessPushConstant));
1412
1413
roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
1414
roughness.push_constant.sample_count = MAX(uint32_t(float(p_sample_count * 4u) * roughness.push_constant.roughness), 4u);
1415
roughness.push_constant.source_size = p_source_size;
1416
roughness.push_constant.dest_size = p_dest_size;
1417
roughness.push_constant.use_direct_write = p_roughness == 0.0;
1418
roughness.push_constant.border_size[0] = p_border_size;
1419
roughness.push_constant.border_size[1] = 1.0f - p_border_size * 2.0;
1420
1421
// Setup our uniforms.
1422
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1423
1424
RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));
1425
1426
RID shader = roughness.raster_shader.version_get_shader(roughness.shader_version, 0);
1427
ERR_FAIL_COND(shader.is_null());
1428
1429
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);
1430
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.raster_pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
1431
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
1432
1433
RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(OctmapRoughnessPushConstant));
1434
1435
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
1436
RD::get_singleton()->draw_list_end();
1437
}
1438
1439
void CopyEffects::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count) {
1440
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
1441
ERR_FAIL_NULL(uniform_set_cache);
1442
MaterialStorage *material_storage = MaterialStorage::get_singleton();
1443
ERR_FAIL_NULL(material_storage);
1444
1445
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1446
1447
RD::get_singleton()->draw_command_begin_label("Merge Specular");
1448
1449
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
1450
1451
int mode;
1452
if (p_reflection.is_valid()) {
1453
if (p_base.is_valid()) {
1454
mode = SPECULAR_MERGE_SSR;
1455
} else {
1456
mode = SPECULAR_MERGE_ADDITIVE_SSR;
1457
}
1458
} else {
1459
if (p_base.is_valid()) {
1460
mode = SPECULAR_MERGE_ADD;
1461
} else {
1462
mode = SPECULAR_MERGE_ADDITIVE_ADD;
1463
}
1464
}
1465
1466
if (p_view_count > 1) {
1467
mode += SPECULAR_MERGE_ADD_MULTIVIEW;
1468
}
1469
1470
RID shader = specular_merge.shader.version_get_shader(specular_merge.shader_version, mode);
1471
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
1472
1473
if (p_base.is_valid()) {
1474
RD::Uniform u_base(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_base }));
1475
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_base), 2);
1476
}
1477
1478
RD::Uniform u_specular(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_specular }));
1479
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_specular), 0);
1480
1481
if (p_reflection.is_valid()) {
1482
RD::Uniform u_reflection(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_reflection }));
1483
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_reflection), 1);
1484
}
1485
1486
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
1487
RD::get_singleton()->draw_list_end();
1488
1489
RD::get_singleton()->draw_command_end_label();
1490
}
1491
1492