Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/modules/lightmapper_rd/lightmapper_rd.h
10277 views
1
/**************************************************************************/
2
/* lightmapper_rd.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
#pragma once
32
33
#include "core/templates/local_vector.h"
34
#include "scene/3d/lightmapper.h"
35
#include "scene/resources/mesh.h"
36
#include "servers/rendering/rendering_device.h"
37
38
class RDShaderFile;
39
class LightmapperRD : public Lightmapper {
40
GDCLASS(LightmapperRD, Lightmapper)
41
42
struct BakeParameters {
43
float world_size[3] = {};
44
float bias = 0.0;
45
46
float to_cell_offset[3] = {};
47
int32_t grid_size = 0;
48
49
float to_cell_size[3] = {};
50
uint32_t light_count = 0;
51
52
float env_transform[12] = {};
53
54
int32_t atlas_size[2] = {};
55
float exposure_normalization = 0.0f;
56
uint32_t bounces = 0;
57
58
float bounce_indirect_energy = 0.0f;
59
uint32_t shadowmask_light_idx = 0;
60
uint32_t transparency_rays = 0;
61
float supersampling_factor = 0.0f;
62
};
63
64
struct MeshInstance {
65
MeshData data;
66
int slice = 0;
67
Vector2i offset;
68
};
69
70
struct Light {
71
float position[3] = {};
72
uint32_t type = LIGHT_TYPE_DIRECTIONAL;
73
float direction[3] = {};
74
float energy = 0.0;
75
float color[3] = {};
76
float size = 0.0;
77
float range = 0.0;
78
float attenuation = 0.0;
79
float cos_spot_angle = 0.0;
80
float inv_spot_attenuation = 0.0;
81
float indirect_energy = 0.0;
82
float shadow_blur = 0.0;
83
uint32_t static_bake = 0;
84
uint32_t pad = 0;
85
86
bool operator<(const Light &p_light) const {
87
return type < p_light.type;
88
}
89
};
90
91
struct LightMetadata {
92
String name;
93
uint32_t type = LIGHT_TYPE_DIRECTIONAL;
94
95
bool operator<(const LightMetadata &p_light) const {
96
return type < p_light.type;
97
}
98
};
99
100
struct Vertex {
101
float position[3] = {};
102
float normal_z = 0.0;
103
float uv[2] = {};
104
float normal_xy[2] = {};
105
106
bool operator==(const Vertex &p_vtx) const {
107
return (position[0] == p_vtx.position[0]) &&
108
(position[1] == p_vtx.position[1]) &&
109
(position[2] == p_vtx.position[2]) &&
110
(uv[0] == p_vtx.uv[0]) &&
111
(uv[1] == p_vtx.uv[1]) &&
112
(normal_xy[0] == p_vtx.normal_xy[0]) &&
113
(normal_xy[1] == p_vtx.normal_xy[1]) &&
114
(normal_z == p_vtx.normal_z);
115
}
116
};
117
118
struct Edge {
119
Vector3 a;
120
Vector3 b;
121
Vector3 na;
122
Vector3 nb;
123
bool operator==(const Edge &p_seam) const {
124
return a == p_seam.a && b == p_seam.b && na == p_seam.na && nb == p_seam.nb;
125
}
126
Edge() {
127
}
128
129
Edge(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_na, const Vector3 &p_nb) {
130
a = p_a;
131
b = p_b;
132
na = p_na;
133
nb = p_nb;
134
}
135
};
136
137
struct Probe {
138
float position[4] = {};
139
};
140
141
Vector<Probe> probe_positions;
142
143
struct EdgeHash {
144
_FORCE_INLINE_ static uint32_t hash(const Edge &p_edge) {
145
uint32_t h = hash_murmur3_one_float(p_edge.a.x);
146
h = hash_murmur3_one_float(p_edge.a.y, h);
147
h = hash_murmur3_one_float(p_edge.a.z, h);
148
h = hash_murmur3_one_float(p_edge.b.x, h);
149
h = hash_murmur3_one_float(p_edge.b.y, h);
150
h = hash_murmur3_one_float(p_edge.b.z, h);
151
return h;
152
}
153
};
154
struct EdgeUV2 {
155
Vector2 a;
156
Vector2 b;
157
Vector2i indices;
158
bool operator==(const EdgeUV2 &p_uv2) const {
159
return a == p_uv2.a && b == p_uv2.b;
160
}
161
bool seam_found = false;
162
EdgeUV2(Vector2 p_a, Vector2 p_b, Vector2i p_indices) {
163
a = p_a;
164
b = p_b;
165
indices = p_indices;
166
}
167
EdgeUV2() {}
168
};
169
170
struct Seam {
171
Vector2i a;
172
Vector2i b;
173
uint32_t slice;
174
bool operator<(const Seam &p_seam) const {
175
return slice < p_seam.slice;
176
}
177
};
178
179
struct VertexHash {
180
_FORCE_INLINE_ static uint32_t hash(const Vertex &p_vtx) {
181
uint32_t h = hash_murmur3_one_float(p_vtx.position[0]);
182
h = hash_murmur3_one_float(p_vtx.position[1], h);
183
h = hash_murmur3_one_float(p_vtx.position[2], h);
184
h = hash_murmur3_one_float(p_vtx.uv[0], h);
185
h = hash_murmur3_one_float(p_vtx.uv[1], h);
186
h = hash_murmur3_one_float(p_vtx.normal_xy[0], h);
187
h = hash_murmur3_one_float(p_vtx.normal_xy[1], h);
188
h = hash_murmur3_one_float(p_vtx.normal_z, h);
189
return hash_fmix32(h);
190
}
191
};
192
193
struct Triangle {
194
uint32_t indices[3] = {};
195
uint32_t slice = 0;
196
float min_bounds[3] = {};
197
uint32_t cull_mode = 0;
198
float max_bounds[3] = {};
199
float pad1 = 0.0;
200
bool operator<(const Triangle &p_triangle) const {
201
return slice < p_triangle.slice;
202
}
203
};
204
205
struct ClusterAABB {
206
float min_bounds[3];
207
float pad0 = 0.0f;
208
float max_bounds[3];
209
float pad1 = 0.0f;
210
};
211
212
Vector<MeshInstance> mesh_instances;
213
214
Vector<Light> lights;
215
Vector<LightMetadata> light_metadata;
216
217
struct TriangleSort {
218
uint32_t cell_index = 0;
219
uint32_t triangle_index = 0;
220
AABB triangle_aabb;
221
222
bool operator<(const TriangleSort &p_triangle_sort) const {
223
return cell_index < p_triangle_sort.cell_index; //sorting by triangle index in this case makes no sense
224
}
225
};
226
227
template <int T>
228
struct TriangleSortAxis {
229
bool operator()(const TriangleSort &p_a, const TriangleSort &p_b) const {
230
return p_a.triangle_aabb.get_center()[T] < p_b.triangle_aabb.get_center()[T];
231
}
232
};
233
234
void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[3], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size);
235
void _sort_triangle_clusters(uint32_t p_cluster_size, uint32_t p_cluster_index, uint32_t p_index_start, uint32_t p_count, LocalVector<TriangleSort> &p_triangle_sort, LocalVector<ClusterAABB> &p_cluster_aabb);
236
237
struct RasterPushConstant {
238
float atlas_size[2] = {};
239
float uv_offset[2] = {};
240
float to_cell_size[3] = {};
241
uint32_t base_triangle = 0;
242
float to_cell_offset[3] = {};
243
float bias = 0.0;
244
int32_t grid_size[3] = {};
245
uint32_t pad2 = 0;
246
};
247
248
struct RasterSeamsPushConstant {
249
uint32_t base_index = 0;
250
uint32_t slice = 0;
251
float uv_offset[2] = {};
252
uint32_t debug = 0;
253
float blend = 0.0;
254
uint32_t pad[2] = {};
255
};
256
257
struct PushConstant {
258
uint32_t atlas_slice = 0;
259
uint32_t ray_count = 0;
260
uint32_t ray_from = 0;
261
uint32_t ray_to = 0;
262
uint32_t region_ofs[2] = {};
263
uint32_t probe_count = 0;
264
uint32_t denoiser_range = 0;
265
};
266
267
Vector<Ref<Image>> lightmap_textures;
268
Vector<Ref<Image>> shadowmask_textures;
269
Vector<Color> probe_values;
270
271
struct DilateParams {
272
uint32_t radius;
273
uint32_t pad[3];
274
};
275
276
struct DenoiseParams {
277
float spatial_bandwidth;
278
float light_bandwidth;
279
float albedo_bandwidth;
280
float normal_bandwidth;
281
282
int half_search_window;
283
float filter_strength;
284
float pad[2];
285
};
286
287
BakeError _blit_meshes_into_atlas(int p_max_texture_size, int p_denoiser_range, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, float p_supersampling_factor, BakeStepFunc p_step_function, void *p_bake_userdata);
288
void _create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, uint32_t p_cluster_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &lights_buffer, RID &r_triangle_indices_buffer, RID &r_cluster_indices_buffer, RID &r_cluster_aabbs_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata);
289
void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform);
290
291
BakeError _dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
292
BakeError _denoise(RenderingDevice *p_rd, Ref<RDShaderFile> &p_compute_shader, const RID &p_compute_base_uniform_set, PushConstant &p_push_constant, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, RID p_unocclude_tex, float p_denoiser_strength, int p_denoiser_range, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, BakeStepFunc p_step_function, void *p_bake_userdata);
293
BakeError _pack_l1(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices);
294
295
Error _store_pfm(RenderingDevice *p_rd, RID p_atlas_tex, int p_index, const Size2i &p_atlas_size, const String &p_name, bool p_shadowmask);
296
Ref<Image> _read_pfm(const String &p_name, bool p_shadowmask);
297
BakeError _denoise_oidn(RenderingDevice *p_rd, RID p_source_light_tex, RID p_source_normal_tex, RID p_dest_light_tex, const Size2i &p_atlas_size, int p_atlas_slices, bool p_bake_sh, bool p_shadowmask, const String &p_exe);
298
299
public:
300
virtual void add_mesh(const MeshData &p_mesh) override;
301
virtual void add_directional_light(const String &p_name, bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_energy, float p_angular_distance, float p_shadow_blur) override;
302
virtual void add_omni_light(const String &p_name, bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) override;
303
virtual void add_spot_light(const String &p_name, bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) override;
304
virtual void add_probe(const Vector3 &p_position) override;
305
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, float p_denoiser_strength, int p_denoiser_range, int p_bounces, float p_bounce_indirect_energy, float p_bias, int p_max_texture_size, bool p_bake_sh, bool p_bake_shadowmask, bool p_texture_for_bounces, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr, float p_exposure_normalization = 1.0, float p_supersampling_factor = 1.0f) override;
306
307
int get_bake_texture_count() const override;
308
Ref<Image> get_bake_texture(int p_index) const override;
309
int get_shadowmask_texture_count() const override;
310
Ref<Image> get_shadowmask_texture(int p_index) const override;
311
int get_bake_mesh_count() const override;
312
Variant get_bake_mesh_userdata(int p_index) const override;
313
Rect2 get_bake_mesh_uv_scale(int p_index) const override;
314
int get_bake_mesh_texture_slice(int p_index) const override;
315
int get_bake_probe_count() const override;
316
Vector3 get_bake_probe_point(int p_probe) const override;
317
Vector<Color> get_bake_probe_sh(int p_probe) const override;
318
319
LightmapperRD();
320
};
321
322