Path: blob/master/servers/rendering/renderer_rd/environment/sky.h
10279 views
/**************************************************************************/1/* sky.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/templates/rid_owner.h"33#include "servers/rendering/renderer_compositor.h"34#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"35#include "servers/rendering/renderer_rd/shaders/environment/sky.glsl.gen.h"36#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"37#include "servers/rendering/renderer_rd/storage_rd/render_data_rd.h"38#include "servers/rendering/renderer_scene_render.h"39#include "servers/rendering/rendering_device.h"40#include "servers/rendering/shader_compiler.h"4142// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound43class RendererSceneRenderRD;44class RenderSceneBuffersRD;4546namespace RendererRD {4748class SkyRD {49public:50enum SkySet {51SKY_SET_UNIFORMS,52SKY_SET_MATERIAL,53SKY_SET_TEXTURES,54SKY_SET_FOG,55};5657const int SAMPLERS_BINDING_FIRST_INDEX = 4;5859// Skys need less info from Directional Lights than the normal shaders60struct SkyDirectionalLightData {61float direction[3];62float energy;63float color[3];64float size;65uint32_t enabled;66uint32_t pad[3];67};6869private:70RD::DataFormat texture_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;7172enum SkyTextureSetVersion {73SKY_TEXTURE_SET_BACKGROUND,74SKY_TEXTURE_SET_HALF_RES,75SKY_TEXTURE_SET_QUARTER_RES,76SKY_TEXTURE_SET_CUBEMAP,77SKY_TEXTURE_SET_CUBEMAP_HALF_RES,78SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES,79SKY_TEXTURE_SET_MAX80};8182enum SkyVersion {83SKY_VERSION_BACKGROUND,84SKY_VERSION_HALF_RES,85SKY_VERSION_QUARTER_RES,86SKY_VERSION_CUBEMAP,87SKY_VERSION_CUBEMAP_HALF_RES,88SKY_VERSION_CUBEMAP_QUARTER_RES,8990SKY_VERSION_BACKGROUND_MULTIVIEW,91SKY_VERSION_HALF_RES_MULTIVIEW,92SKY_VERSION_QUARTER_RES_MULTIVIEW,9394SKY_VERSION_MAX95};9697struct SkyPushConstant {98float orientation[12]; // 48 - 4899float projection[4]; // 16 - 64100float position[3]; // 12 - 76101float time; // 4 - 80102float pad[2]; // 8 - 88103float luminance_multiplier; // 4 - 92104float brightness_multiplier; // 4 - 96105// 128 is the max size of a push constant. We can replace "pad" but we can't add any more.106};107108struct SkyShaderData : public RendererRD::MaterialStorage::ShaderData {109bool valid = false;110RID version;111112PipelineCacheRD pipelines[SKY_VERSION_MAX];113Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;114115Vector<uint32_t> ubo_offsets;116uint32_t ubo_size = 0;117118String code;119120bool uses_time = false;121bool uses_position = false;122bool uses_half_res = false;123bool uses_quarter_res = false;124bool uses_light = false;125126virtual void set_code(const String &p_Code);127virtual bool is_animated() const;128virtual bool casts_shadows() const;129virtual RS::ShaderNativeSourceCode get_native_source_code() const;130virtual Pair<ShaderRD *, RID> get_native_shader_and_version() const;131132SkyShaderData() {}133virtual ~SkyShaderData();134};135136void _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);137138public:139struct SkySceneState {140struct UBO {141float combined_reprojection[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 128142float view_inv_projections[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 256143float view_eye_offsets[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 288144145uint32_t volumetric_fog_enabled; // 4 - 292146float volumetric_fog_inv_length; // 4 - 296147float volumetric_fog_detail_spread; // 4 - 300148float volumetric_fog_sky_affect; // 4 - 304149150uint32_t fog_enabled; // 4 - 308151float fog_sky_affect; // 4 - 312152float fog_density; // 4 - 316153float fog_sun_scatter; // 4 - 320154155float fog_light_color[3]; // 12 - 332156float fog_aerial_perspective; // 4 - 336157158float z_far; // 4 - 340159uint32_t directional_light_count; // 4 - 344160uint32_t pad1; // 4 - 348161uint32_t pad2; // 4 - 352162};163164UBO ubo;165166uint32_t view_count = 1;167Transform3D cam_transform;168Projection cam_projection;169170SkyDirectionalLightData *directional_lights = nullptr;171SkyDirectionalLightData *last_frame_directional_lights = nullptr;172uint32_t max_directional_lights;173uint32_t last_frame_directional_light_count;174RID directional_light_buffer;175RID uniform_set;176RID uniform_buffer;177RID fog_uniform_set;178RID default_fog_uniform_set;179180RID fog_shader;181RID fog_material;182RID fog_only_texture_uniform_set;183} sky_scene_state;184185struct ReflectionData {186struct Layer {187struct Mipmap {188RID framebuffers[6];189RID views[6];190Size2i size;191};192Vector<Mipmap> mipmaps; //per-face view193Vector<RID> views; // per-cubemap view194};195196struct DownsampleLayer {197struct Mipmap {198RID view;199Size2i size;200201// for mobile only202RID views[6];203RID framebuffers[6];204};205Vector<Mipmap> mipmaps;206};207208RID radiance_base_cubemap; //cubemap for first layer, first cubemap209RID downsampled_radiance_cubemap;210DownsampleLayer downsampled_layer;211RID coefficient_buffer;212213bool dirty = true;214215Vector<Layer> layers;216217void clear_reflection_data();218void 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);219void create_reflection_fast_filter(bool p_use_arrays);220void create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);221void update_reflection_mipmaps(int p_start, int p_end);222};223224/* Sky shader */225226struct SkyShader {227SkyShaderRD shader;228ShaderCompiler compiler;229230RID default_shader;231RID default_material;232RID default_shader_rd;233} sky_shader;234235struct SkyMaterialData : public RendererRD::MaterialStorage::MaterialData {236SkyShaderData *shader_data = nullptr;237RID uniform_set;238bool uniform_set_updated;239240virtual void set_render_priority(int p_priority) {}241virtual void set_next_pass(RID p_pass) {}242virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);243virtual ~SkyMaterialData();244};245246struct Sky {247RID radiance;248RID quarter_res_pass;249RID quarter_res_framebuffer;250Size2i screen_size;251252RID uniform_set;253254RID material;255RID uniform_buffer;256257int radiance_size = 256;258259RS::SkyMode mode = RS::SKY_MODE_AUTOMATIC;260261ReflectionData reflection;262bool dirty = false;263int processing_layer = 0;264Sky *dirty_list = nullptr;265float baked_exposure = 1.0;266267//State to track when radiance cubemap needs updating268SkyMaterialData *prev_material = nullptr;269Vector3 prev_position;270float prev_time;271272void free();273274RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers);275bool set_radiance_size(int p_radiance_size);276bool set_mode(RS::SkyMode p_mode);277bool set_material(RID p_material);278Ref<Image> bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size);279};280281uint32_t sky_ggx_samples_quality;282bool sky_use_cubemap_array;283#if defined(MACOS_ENABLED) && defined(__x86_64__)284void check_cubemap_array();285#endif286Sky *dirty_sky_list = nullptr;287mutable RID_Owner<Sky, true> sky_owner;288int roughness_layers;289290RendererRD::MaterialStorage::ShaderData *_create_sky_shader_func();291static RendererRD::MaterialStorage::ShaderData *_create_sky_shader_funcs();292293RendererRD::MaterialStorage::MaterialData *_create_sky_material_func(SkyShaderData *p_shader);294static RendererRD::MaterialStorage::MaterialData *_create_sky_material_funcs(RendererRD::MaterialStorage::ShaderData *p_shader);295296SkyRD();297void init();298void set_texture_format(RD::DataFormat p_texture_format);299~SkyRD();300301void setup_sky(const RenderDataRD *p_render_data, const Size2i p_screen_size);302void 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);303void 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);304void 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);305306void invalidate_sky(Sky *p_sky);307void update_dirty_skys();308309RID sky_get_material(RID p_sky) const;310RID sky_get_radiance_texture_rd(RID p_sky) const;311float sky_get_baked_exposure(RID p_sky) const;312313RID allocate_sky_rid();314void initialize_sky_rid(RID p_rid);315Sky *get_sky(RID p_sky) const;316void free_sky(RID p_sky);317void sky_set_radiance_size(RID p_sky, int p_radiance_size);318void sky_set_mode(RID p_sky, RS::SkyMode p_mode);319void sky_set_material(RID p_sky, RID p_material);320Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);321};322323} // namespace RendererRD324325326