Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/renderer_rd/environment/sky.h
10279 views
1
/**************************************************************************/
2
/* sky.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/rid_owner.h"
34
#include "servers/rendering/renderer_compositor.h"
35
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
36
#include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h"
37
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
38
#include "servers/rendering/renderer_rd/storage_rd/render_data_rd.h"
39
#include "servers/rendering/renderer_scene_render.h"
40
#include "servers/rendering/rendering_device.h"
41
#include "servers/rendering/shader_compiler.h"
42
43
// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
44
class RendererSceneRenderRD;
45
class RenderSceneBuffersRD;
46
47
namespace RendererRD {
48
49
class SkyRD {
50
public:
51
enum SkySet {
52
SKY_SET_UNIFORMS,
53
SKY_SET_MATERIAL,
54
SKY_SET_TEXTURES,
55
SKY_SET_FOG,
56
};
57
58
const int SAMPLERS_BINDING_FIRST_INDEX = 4;
59
60
// Skys need less info from Directional Lights than the normal shaders
61
struct SkyDirectionalLightData {
62
float direction[3];
63
float energy;
64
float color[3];
65
float size;
66
uint32_t enabled;
67
uint32_t pad[3];
68
};
69
70
private:
71
RD::DataFormat texture_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
72
73
enum SkyTextureSetVersion {
74
SKY_TEXTURE_SET_BACKGROUND,
75
SKY_TEXTURE_SET_HALF_RES,
76
SKY_TEXTURE_SET_QUARTER_RES,
77
SKY_TEXTURE_SET_CUBEMAP,
78
SKY_TEXTURE_SET_CUBEMAP_HALF_RES,
79
SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES,
80
SKY_TEXTURE_SET_MAX
81
};
82
83
enum SkyVersion {
84
SKY_VERSION_BACKGROUND,
85
SKY_VERSION_HALF_RES,
86
SKY_VERSION_QUARTER_RES,
87
SKY_VERSION_CUBEMAP,
88
SKY_VERSION_CUBEMAP_HALF_RES,
89
SKY_VERSION_CUBEMAP_QUARTER_RES,
90
91
SKY_VERSION_BACKGROUND_MULTIVIEW,
92
SKY_VERSION_HALF_RES_MULTIVIEW,
93
SKY_VERSION_QUARTER_RES_MULTIVIEW,
94
95
SKY_VERSION_MAX
96
};
97
98
struct SkyPushConstant {
99
float orientation[12]; // 48 - 48
100
float projection[4]; // 16 - 64
101
float position[3]; // 12 - 76
102
float time; // 4 - 80
103
float pad[2]; // 8 - 88
104
float luminance_multiplier; // 4 - 92
105
float brightness_multiplier; // 4 - 96
106
// 128 is the max size of a push constant. We can replace "pad" but we can't add any more.
107
};
108
109
struct SkyShaderData : public RendererRD::MaterialStorage::ShaderData {
110
bool valid = false;
111
RID version;
112
113
PipelineCacheRD pipelines[SKY_VERSION_MAX];
114
Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
115
116
Vector<uint32_t> ubo_offsets;
117
uint32_t ubo_size = 0;
118
119
String code;
120
121
bool uses_time = false;
122
bool uses_position = false;
123
bool uses_half_res = false;
124
bool uses_quarter_res = false;
125
bool uses_light = false;
126
127
virtual void set_code(const String &p_Code);
128
virtual bool is_animated() const;
129
virtual bool casts_shadows() const;
130
virtual RS::ShaderNativeSourceCode get_native_source_code() const;
131
virtual Pair<ShaderRD *, RID> get_native_shader_and_version() const;
132
133
SkyShaderData() {}
134
virtual ~SkyShaderData();
135
};
136
137
void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier, float p_brightness_modifier);
138
139
public:
140
struct SkySceneState {
141
struct UBO {
142
float combined_reprojection[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 128
143
float view_inv_projections[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 256
144
float view_eye_offsets[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 288
145
146
uint32_t volumetric_fog_enabled; // 4 - 292
147
float volumetric_fog_inv_length; // 4 - 296
148
float volumetric_fog_detail_spread; // 4 - 300
149
float volumetric_fog_sky_affect; // 4 - 304
150
151
uint32_t fog_enabled; // 4 - 308
152
float fog_sky_affect; // 4 - 312
153
float fog_density; // 4 - 316
154
float fog_sun_scatter; // 4 - 320
155
156
float fog_light_color[3]; // 12 - 332
157
float fog_aerial_perspective; // 4 - 336
158
159
float z_far; // 4 - 340
160
uint32_t directional_light_count; // 4 - 344
161
uint32_t pad1; // 4 - 348
162
uint32_t pad2; // 4 - 352
163
};
164
165
UBO ubo;
166
167
uint32_t view_count = 1;
168
Transform3D cam_transform;
169
Projection cam_projection;
170
171
SkyDirectionalLightData *directional_lights = nullptr;
172
SkyDirectionalLightData *last_frame_directional_lights = nullptr;
173
uint32_t max_directional_lights;
174
uint32_t last_frame_directional_light_count;
175
RID directional_light_buffer;
176
RID uniform_set;
177
RID uniform_buffer;
178
RID fog_uniform_set;
179
RID default_fog_uniform_set;
180
181
RID fog_shader;
182
RID fog_material;
183
RID fog_only_texture_uniform_set;
184
} sky_scene_state;
185
186
struct ReflectionData {
187
struct Layer {
188
struct Mipmap {
189
RID framebuffers[6];
190
RID views[6];
191
Size2i size;
192
};
193
Vector<Mipmap> mipmaps; //per-face view
194
Vector<RID> views; // per-cubemap view
195
};
196
197
struct DownsampleLayer {
198
struct Mipmap {
199
RID view;
200
Size2i size;
201
202
// for mobile only
203
RID views[6];
204
RID framebuffers[6];
205
};
206
Vector<Mipmap> mipmaps;
207
};
208
209
RID radiance_base_cubemap; //cubemap for first layer, first cubemap
210
RID downsampled_radiance_cubemap;
211
DownsampleLayer downsampled_layer;
212
RID coefficient_buffer;
213
214
bool dirty = true;
215
216
Vector<Layer> layers;
217
218
void clear_reflection_data();
219
void update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format);
220
void create_reflection_fast_filter(bool p_use_arrays);
221
void create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
222
void update_reflection_mipmaps(int p_start, int p_end);
223
};
224
225
/* Sky shader */
226
227
struct SkyShader {
228
SkyShaderRD shader;
229
ShaderCompiler compiler;
230
231
RID default_shader;
232
RID default_material;
233
RID default_shader_rd;
234
} sky_shader;
235
236
struct SkyMaterialData : public RendererRD::MaterialStorage::MaterialData {
237
SkyShaderData *shader_data = nullptr;
238
RID uniform_set;
239
bool uniform_set_updated;
240
241
virtual void set_render_priority(int p_priority) {}
242
virtual void set_next_pass(RID p_pass) {}
243
virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
244
virtual ~SkyMaterialData();
245
};
246
247
struct Sky {
248
RID radiance;
249
RID quarter_res_pass;
250
RID quarter_res_framebuffer;
251
Size2i screen_size;
252
253
RID uniform_set;
254
255
RID material;
256
RID uniform_buffer;
257
258
int radiance_size = 256;
259
260
RS::SkyMode mode = RS::SKY_MODE_AUTOMATIC;
261
262
ReflectionData reflection;
263
bool dirty = false;
264
int processing_layer = 0;
265
Sky *dirty_list = nullptr;
266
float baked_exposure = 1.0;
267
268
//State to track when radiance cubemap needs updating
269
SkyMaterialData *prev_material = nullptr;
270
Vector3 prev_position;
271
float prev_time;
272
273
void free();
274
275
RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers);
276
bool set_radiance_size(int p_radiance_size);
277
bool set_mode(RS::SkyMode p_mode);
278
bool set_material(RID p_material);
279
Ref<Image> bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size);
280
};
281
282
uint32_t sky_ggx_samples_quality;
283
bool sky_use_cubemap_array;
284
#if defined(MACOS_ENABLED) && defined(__x86_64__)
285
void check_cubemap_array();
286
#endif
287
Sky *dirty_sky_list = nullptr;
288
mutable RID_Owner<Sky, true> sky_owner;
289
int roughness_layers;
290
291
RendererRD::MaterialStorage::ShaderData *_create_sky_shader_func();
292
static RendererRD::MaterialStorage::ShaderData *_create_sky_shader_funcs();
293
294
RendererRD::MaterialStorage::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);
295
static RendererRD::MaterialStorage::MaterialData *_create_sky_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader);
296
297
SkyRD();
298
void init();
299
void set_texture_format(RD::DataFormat p_texture_format);
300
~SkyRD();
301
302
void setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size);
303
void update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0);
304
void update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0);
305
void draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0, float p_brightness_multiplier = 1.0);
306
307
void invalidate_sky(Sky *p_sky);
308
void update_dirty_skys();
309
310
RID sky_get_material(RID p_sky) const;
311
RID sky_get_radiance_texture_rd(RID p_sky) const;
312
float sky_get_baked_exposure(RID p_sky) const;
313
314
RID allocate_sky_rid();
315
void initialize_sky_rid(RID p_rid);
316
Sky *get_sky(RID p_sky) const;
317
void free_sky(RID p_sky);
318
void sky_set_radiance_size(RID p_sky, int p_radiance_size);
319
void sky_set_mode(RID p_sky, RS::SkyMode p_mode);
320
void sky_set_material(RID p_sky, RID p_material);
321
Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);
322
};
323
324
} // namespace RendererRD
325
326